blob: e80629980446fd9c23b0fb6e688d04de118b6231 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <log4cxx/helpers/transcoder.h>
#include "../insertwide.h"
#include "../logunit.h"
using namespace log4cxx;
using namespace log4cxx::helpers;
LOGUNIT_CLASS(TranscoderTestCase)
{
LOGUNIT_TEST_SUITE(TranscoderTestCase);
LOGUNIT_TEST(decode1);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(decode2);
#endif
LOGUNIT_TEST(decode3);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(decode4);
#endif
LOGUNIT_TEST(decode7);
LOGUNIT_TEST(decode8);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(encode1);
#endif
LOGUNIT_TEST(encode2);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(encode3);
LOGUNIT_TEST(encode3_1);
#endif
LOGUNIT_TEST(encode4);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(encode5);
#endif
LOGUNIT_TEST(encode6);
LOGUNIT_TEST(testDecodeUTF8_1);
LOGUNIT_TEST(testDecodeUTF8_2);
LOGUNIT_TEST(testDecodeUTF8_3);
LOGUNIT_TEST(testDecodeUTF8_4);
#if LOG4CXX_UNICHAR_API
LOGUNIT_TEST(udecode2);
LOGUNIT_TEST(udecode4);
LOGUNIT_TEST(uencode1);
LOGUNIT_TEST(uencode3);
LOGUNIT_TEST(uencode5);
#endif
#if LOG4CXX_LOGCHAR_IS_UTF8
LOGUNIT_TEST(encodeCharsetName1);
LOGUNIT_TEST(encodeCharsetName2);
LOGUNIT_TEST(encodeCharsetName3);
#endif
LOGUNIT_TEST_SUITE_END();
public:
void decode1()
{
const char* greeting = "Hello, World";
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(greeting, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
}
#if LOG4CXX_WCHAR_T_API
void decode2()
{
const wchar_t* greeting = L"Hello, World";
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(greeting, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
}
#endif
void decode3()
{
const char* nothing = "";
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(nothing, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
}
#if LOG4CXX_WCHAR_T_API
void decode4()
{
const wchar_t* nothing = L"";
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(nothing, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
}
#endif
enum { BUFSIZE = 255 };
void decode7()
{
//
// normal characters striding over a buffer boundary
//
std::string longMsg(BUFSIZE - 2, 'A');
longMsg.append("Hello");
LogString decoded;
Transcoder::decode(longMsg, decoded);
LOGUNIT_ASSERT_EQUAL((size_t) BUFSIZE + 3, decoded.length());
LOGUNIT_ASSERT_EQUAL(LogString(BUFSIZE - 2, LOG4CXX_STR('A')),
decoded.substr(0, BUFSIZE - 2));
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("Hello"),
decoded.substr(BUFSIZE - 2 ));
}
void decode8()
{
std::string msg("Hello, World.");
LogString actual;
Transcoder::decode(msg, actual);
LogString expected(LOG4CXX_STR("Hello, World."));
LOGUNIT_ASSERT_EQUAL(expected, actual);
}
#if LOG4CXX_WCHAR_T_API
void encode1()
{
const LogString greeting(LOG4CXX_STR("Hello, World"));
std::wstring encoded;
Transcoder::encode(greeting, encoded);
LOGUNIT_ASSERT_EQUAL((std::wstring) L"Hello, World", encoded);
}
#endif
void encode2()
{
const LogString greeting(LOG4CXX_STR("Hello, World"));
std::string encoded;
Transcoder::encode(greeting, encoded);
LOGUNIT_ASSERT_EQUAL((std::string) "Hello, World", encoded);
}
#if LOG4CXX_WCHAR_T_API
void encode3()
{
LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
greeting.append(LOG4CXX_STR("Hello"));
std::wstring encoded;
Transcoder::encode(greeting, encoded);
std::wstring manyAs(BUFSIZE - 3, L'A');
LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
LOGUNIT_ASSERT_EQUAL(std::wstring(L"Hello"), encoded.substr(BUFSIZE - 3));
}
void encode3_1()
{
// Test invalid multibyte string
LogString greeting;
greeting.push_back( 0xff );
std::wstring encoded;
Transcoder::encode(greeting, encoded);
std::wstring expected;
expected.push_back( log4cxx::helpers::Transcoder::LOSSCHAR );
LOGUNIT_ASSERT_EQUAL(encoded, expected );
}
#endif
void encode4()
{
LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
greeting.append(LOG4CXX_STR("Hello"));
std::string encoded;
Transcoder::encode(greeting, encoded);
std::string manyAs(BUFSIZE - 3, 'A');
LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
LOGUNIT_ASSERT_EQUAL(std::string("Hello"), encoded.substr(BUFSIZE - 3));
}
#if LOG4CXX_WCHAR_T_API
void encode5()
{
// arbitrary, hopefully meaningless, characters from
// Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
const wchar_t greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
//
// decode to LogString (UTF-16 or UTF-8)
//
LogString decoded;
Transcoder::decode(greeting, decoded);
//
// decode to wstring
//
std::wstring encoded;
Transcoder::encode(decoded, encoded);
//
// should be lossless
//
LOGUNIT_ASSERT_EQUAL((std::wstring) greeting, encoded);
}
#endif
void encode6()
{
#if LOG4CXX_LOGCHAR_IS_WCHAR || LOG4CXX_LOGCHAR_IS_UNICHAR
// arbitrary, hopefully meaningless, characters from
// Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
const logchar greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
#endif
#if LOG4CXX_LOGCHAR_IS_UTF8
const char greeting[] = { 'A',
(char) 0xD8, (char) 0x85,
(char) 0xD4, (char) 0xB0,
(char) 0xE0, (char) 0xCC, (char) 0x84,
(char) 0xE8, (char) 0x87, (char) 0x83,
(char) 0xD0, (char) 0x80,
0
};
#endif
//
// decode to LogString (UTF-16 or UTF-8)
//
LogString decoded;
Transcoder::decode(greeting, decoded);
//
// decode to wstring
//
std::string encoded;
//
// likely 'A\u0605\u0530\u0984\u40E3\u0400'
//
Transcoder::encode(decoded, encoded);
}
void testDecodeUTF8_1()
{
std::string src("a");
LogString out;
Transcoder::decodeUTF8(src, out);
LOGUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("a")), out);
}
void testDecodeUTF8_2()
{
std::string src(1, 0x80);
LogString out;
Transcoder::decodeUTF8(src, out);
LOGUNIT_ASSERT_EQUAL(LogString(1, Transcoder::LOSSCHAR), out);
}
void testDecodeUTF8_3()
{
std::string src("\xC2");
LogString out;
Transcoder::decodeUTF8(src, out);
LOGUNIT_ASSERT_EQUAL(LogString(1, Transcoder::LOSSCHAR), out);
}
void testDecodeUTF8_4()
{
std::string src("\xC2\xA9");
LogString out;
Transcoder::decodeUTF8(src, out);
LogString::const_iterator iter = out.begin();
unsigned int sv = Transcoder::decode(out, iter);
LOGUNIT_ASSERT_EQUAL((unsigned int) 0xA9, sv);
LOGUNIT_ASSERT_EQUAL(true, iter == out.end());
}
#if LOG4CXX_UNICHAR_API
void udecode2()
{
const UniChar greeting[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(greeting, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\nHello, World"), decoded);
}
void udecode4()
{
const UniChar nothing[] = { 0 };
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(nothing, decoded);
LOGUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo\n"), decoded);
}
void uencode1()
{
const LogString greeting(LOG4CXX_STR("Hello, World"));
std::basic_string<UniChar> encoded;
Transcoder::encode(greeting, encoded);
const UniChar expected[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', 0 };
LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(expected), encoded);
}
void uencode3()
{
LogString greeting(BUFSIZE - 3, LOG4CXX_STR('A'));
greeting.append(LOG4CXX_STR("Hello"));
std::basic_string<UniChar> encoded;
Transcoder::encode(greeting, encoded);
std::basic_string<UniChar> manyAs(BUFSIZE - 3, 'A');
LOGUNIT_ASSERT_EQUAL(manyAs, encoded.substr(0, BUFSIZE - 3));
const UniChar hello[] = { 'H', 'e', 'l', 'l', 'o', 0 };
LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(hello), encoded.substr(BUFSIZE - 3));
}
void uencode5()
{
// arbitrary, hopefully meaningless, characters from
// Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
const UniChar greeting[] = { L'A', 0x0605, 0x0530, 0x984, 0x40E3, 0x400, 0 };
//
// decode to LogString (UTF-16 or UTF-8)
//
LogString decoded;
Transcoder::decode(greeting, decoded);
//
// decode to basic_string<UniChar>
//
std::basic_string<UniChar> encoded;
Transcoder::encode(decoded, encoded);
//
// should be lossless
//
LOGUNIT_ASSERT_EQUAL(std::basic_string<UniChar>(greeting), encoded);
}
#endif
#if LOG4CXX_LOGCHAR_IS_UTF8
void encodeCharsetName1()
{
const logchar utf8[] = { 0x75, 0x74, 0x66, 0x2D, 0x38, 0x00 };
std::string encoded(Transcoder::encodeCharsetName(LogString(utf8)));
LOGUNIT_ASSERT_EQUAL(std::string("utf-8"), encoded);
}
void encodeCharsetName2()
{
logchar lascii[0x60];
char ascii[0x60];
for (int i = 0; i < 0x5F; i++)
{
lascii[i] = i + 0x20;
ascii[i] = i + 0x20;
}
lascii[0x5F] = 0;
ascii[0x5F] = 0;
std::string encoded(Transcoder::encodeCharsetName(LogString(ascii)));
LOGUNIT_ASSERT_EQUAL(std::string(" !\"#$%&'()*+,-./"), encoded.substr(0, 0x10));
if (0x40 == 'A')
{
LOGUNIT_ASSERT_EQUAL(std::string(ascii), encoded);
}
}
void encodeCharsetName3()
{
logchar unsupported[] = { 0x1F, 0x7F, static_cast<logchar>(0x80), static_cast<logchar>(0x81), 0x00 };
std::string encoded(Transcoder::encodeCharsetName(LogString(unsupported)));
LOGUNIT_ASSERT_EQUAL(std::string("????"), encoded);
}
#endif
};
LOGUNIT_TEST_SUITE_REGISTRATION(TranscoderTestCase);