2 **********************************************************************
3 * Copyright (C) 2002-2010, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 * file name: iotest.cpp
8 * tab size: 8 (not used)
11 * created on: 2002feb21
12 * created by: George Rhoten
16 #include "unicode/ustream.h"
18 #include "unicode/ucnv.h"
19 #include "unicode/ustring.h"
23 #if U_IOSTREAM_SOURCE >= 199711
24 #if defined(__GNUC__) && __GNUC__ >= 4
28 // <strstream> is deprecated on some platforms, and the compiler complains very loudly if you use it.
34 #elif U_IOSTREAM_SOURCE >= 198506
35 #define USE_OLD_IOSTREAM 1
36 #include <strstream.h>
44 const UChar NEW_LINE
[] = {0x0d,0x0a,0};
45 const char C_NEW_LINE
[] = {0x0d,0x0a,0};
46 #define UTF8_NEW_LINE "\x0d\x0a"
48 const UChar NEW_LINE
[] = {0x0a,0};
49 const char C_NEW_LINE
[] = {'\n',0};
50 #define UTF8_NEW_LINE "\x0a"
56 static void U_CALLCONV
TestStream(void)
58 #if U_IOSTREAM_SOURCE >= 198506
59 const UChar thisMu
[] = { 0x74, 0x48, 0x69, 0x73, 0x3BC, 0};
60 const UChar mu
[] = { 0x6D, 0x75, 0};
61 UnicodeString str1
= UNICODE_STRING_SIMPLE("str1");
62 UnicodeString str2
= UNICODE_STRING_SIMPLE(" <<");
63 UnicodeString str3
= UNICODE_STRING_SIMPLE("2");
64 UnicodeString str4
= UNICODE_STRING_SIMPLE(" UTF-8 ");
65 UnicodeString inStr
= UNICODE_STRING_SIMPLE(" UTF-8 ");
67 char defConvName
[UCNV_MAX_CONVERTER_NAME_LENGTH
*2];
69 UErrorCode status
= U_ZERO_ERROR
;
71 static const char testStr
[] = "\x42\x65\x67\x69\x6E\x6E\x69\x6E\x67\x20\x6F\x66\x20\x74\x65\x73\x74\x20\x73\x74\x72\x31\x20\x20\x20\x3C\x3C\x32\x31\x20" UTF8_NEW_LINE
"\x20\x55\x54\x46\x2D\x38\x20\xCE\xBC\xF0\x90\x80\x81\xF0\x90\x80\x82";
73 str4
.append((UChar32
)0x03BC); /* mu */
74 str4
.append((UChar32
)0x10001);
75 str4
.append((UChar32
)0x10002);
77 /* release the default converter and use utf-8 for a bit */
78 defConv
= u_getDefaultConverter(&status
);
79 if (U_FAILURE(status
)) {
80 log_err("Can't get default converter\n");
84 strncpy(defConvName
, ucnv_getDefaultName(), sizeof(defConvName
)/sizeof(defConvName
[0]));
85 ucnv_setDefaultName("UTF-8");
87 static const char * const TESTSTRING
= "\x20\x74\x48\x69\x73\xCE\xBC\xE2\x80\x82\x20\x6D\x75\x20\x77\x6F\x72\x6C\x64";
89 ostringstream outTestStream
;
90 istringstream
inTestStream(TESTSTRING
);
92 char testStreamBuf
[512];
93 ostrstream
outTestStream(testStreamBuf
, sizeof(testStreamBuf
));
94 istrstream
inTestStream(TESTSTRING
, 0);
96 /* initialize testStreamBuf */
97 memset(testStreamBuf
, '*', sizeof(testStreamBuf
));
98 testStreamBuf
[sizeof(testStreamBuf
)-1] = 0;
101 outTestStream
<< "\x42\x65\x67\x69\x6E\x6E\x69\x6E\x67\x20\x6F\x66\x20\x74\x65\x73\x74\x20";
102 outTestStream
<< str1
<< "\x20\x20" << str2
<< str3
<< "\x31\x20" << UTF8_NEW_LINE
<< str4
<< ends
;
104 string tempStr
= outTestStream
.str();
105 const char *testStreamBuf
= tempStr
.c_str();
107 if (strcmp(testStreamBuf
, testStr
) != 0) {
108 log_err("Got: \"%s\", Expected: \"%s\"\n", testStreamBuf
, testStr
);
111 inTestStream
>> inStr
>> inStr2
;
112 if (inStr
.compare(thisMu
) != 0) {
113 u_austrncpy(inStrC
, inStr
.getBuffer(), inStr
.length());
114 inStrC
[inStr
.length()] = 0;
115 log_err("Got: \"%s\", Expected: \"tHis\\u03BC\"\n", inStrC
);
117 if (inStr2
.compare(mu
) != 0) {
118 u_austrncpy(inStrC
, inStr
.getBuffer(), inStr
.length());
119 inStrC
[inStr
.length()] = 0;
120 log_err("Got: \"%s\", Expected: \"mu\"\n", inStrC
);
123 /* return the default converter to the original state. */
124 ucnv_setDefaultName(defConvName
);
125 defConv
= u_getDefaultConverter(&status
);
126 if (U_FAILURE(status
)) {
127 log_err("Can't get default converter");
131 /* Test formatting when using '<<' and UnicodeString */
133 ostringstream outFormatStream
;
135 char testFormatStreamBuf
[512];
136 memset(testFormatStreamBuf
, 0, sizeof(testFormatStreamBuf
));
137 ostrstream
outFormatStream(testFormatStreamBuf
, sizeof(testFormatStreamBuf
));
139 UnicodeString
ustr("string");
141 outFormatStream
<< "1234567890" << setw(10) << left
<< ustr
<< " " << "0123456789";
144 tempStr
= outFormatStream
.str();
145 const char *testFormatStreamBuf
= tempStr
.c_str();
147 const char *format_test_expected
= "1234567890string 0123456789";
148 if (strcmp(format_test_expected
, testFormatStreamBuf
) != 0) {
149 log_err("UnicodeString format test using << operator Got: '%s' Expected: '%s'\n", testFormatStreamBuf
, format_test_expected
);
152 /* Test large buffer (size > 200) when using '<<' and UnicodeString */
154 ostringstream outLargeStream
;
156 char testLargeStreamBuf
[512];
157 memset(testLargeStreamBuf
, 0, sizeof(testLargeStreamBuf
));
158 ostrstream
outLargeStream(testLargeStreamBuf
, sizeof(testLargeStreamBuf
));
160 UChar large_array
[200];
161 int32_t large_array_length
= sizeof(large_array
)/sizeof(UChar
);
162 for (int32_t i
= 0; i
< large_array_length
; i
++) {
163 large_array
[i
] = 0x41;
165 UnicodeString
large_array_unistr(large_array
, large_array_length
);
167 outLargeStream
<< large_array_unistr
;
170 string tmpString
= outLargeStream
.str();
171 const char *testLargeStreamBuf
= tmpString
.c_str();
173 char expectedLargeStreamBuf
[300];
174 int32_t expectedBufLength
= sizeof(expectedLargeStreamBuf
);
176 ucnv_fromUChars(defConv
, expectedLargeStreamBuf
, expectedBufLength
, large_array
, large_array_length
, &status
);
177 if (U_SUCCESS(status
)) {
178 if (strcmp(testLargeStreamBuf
, expectedLargeStreamBuf
) != 0) {
179 log_err("Large UnicodeString operator << output incorrect.\n");
182 log_err("Error converting string for large stream buffer testing.\n");
186 log_info("U_IOSTREAM_SOURCE is disabled\n");
190 #define IOSTREAM_GOOD_SHIFT 3
191 #define IOSTREAM_GOOD (1<<IOSTREAM_GOOD_SHIFT)
192 #define IOSTREAM_BAD_SHIFT 2
193 #define IOSTREAM_BAD (1<<IOSTREAM_BAD_SHIFT)
194 #define IOSTREAM_EOF_SHIFT 1
195 #define IOSTREAM_EOF (1<<IOSTREAM_EOF_SHIFT)
196 #define IOSTREAM_FAIL_SHIFT 0
197 #define IOSTREAM_FAIL (1<<IOSTREAM_FAIL_SHIFT)
199 static int32_t getBitStatus(const iostream
& stream
) {
200 return (stream
.good()<<IOSTREAM_GOOD_SHIFT
)
201 | (stream
.bad()<<IOSTREAM_BAD_SHIFT
)
202 | (stream
.eof()<<IOSTREAM_EOF_SHIFT
)
203 | (stream
.fail()<<IOSTREAM_FAIL_SHIFT
);
207 printBits(const iostream
& stream
)
209 int32_t status
= getBitStatus(stream
);
210 log_verbose("status 0x%02X (", status
);
211 if (status
& IOSTREAM_GOOD
) {
214 if (status
& IOSTREAM_BAD
) {
217 if (status
& IOSTREAM_EOF
) {
220 if (status
& IOSTREAM_FAIL
) {
229 const char* testString
,
230 const UChar
* expectedString
,
231 int32_t expectedStatus
)
241 /*log_verbose("iostream before operator::>>() call \"%s\" ", testString);
246 log_verbose("iostream after operator::>>() call \"%s\" ", testString
);
249 if (getBitStatus(sstrm
) != expectedStatus
) {
251 #ifdef USE_OLD_IOSTREAM
252 log_info("Warning. Expected status %d, Got %d. This maybe caused by the fact that the non-standardized iostream is being used.\n", expectedStatus
, getBitStatus(sstrm
));
253 log_info("See verbose output for details.\n");
255 log_err("Expected status %d, Got %d. See verbose output for details\n", expectedStatus
, getBitStatus(sstrm
));
258 if (str
!= UnicodeString(expectedString
)) {
259 log_err("Did not get expected results from \"%s\", expected \"%s\"\n", testString
, expectedString
);
264 static void U_CALLCONV
TestStreamEOF(void)
267 fstream
fs(STANDARD_TEST_FILE
, fstream::in
| fstream::out
| fstream::trunc
);
274 #ifdef USE_OLD_IOSTREAM
275 log_info("Old non-standardized iostream being used. This may result in inconsistent state flag settings. (e.g. failbit may not be set properly)\n");
276 log_info("In such a case, warnings will be issued instead of errors.\n");
284 log_err("Reading of file did not return expected status result\n");
286 if (dest
!= "EXAMPLE") {
287 log_err("Reading of file did not return expected string\n");
291 log_err("Reading of string did not return expected status result\n");
293 if (dest
!= "EXAMPLE") {
294 log_err("Reading of string did not return expected string\n");
298 log_verbose("Testing operator >> for UnicodeString...\n");
300 /* The test cases needs to be converted to the default codepage. However, the stream operator needs char* so U_STRING_* is called. */
301 U_STRING_DECL(testCase1
, "", 0);
302 U_STRING_INIT(testCase1
, "", 0);
303 U_STRING_DECL(testCase2
, "foo", 3);
304 U_STRING_INIT(testCase2
, "foo", 3);
305 U_STRING_DECL(testCase3
, " ", 3);
306 U_STRING_INIT(testCase3
, " ", 3);
307 U_STRING_DECL(testCase4
, " bar", 6);
308 U_STRING_INIT(testCase4
, " bar", 6);
309 U_STRING_DECL(testCase5
, "bar ", 6);
310 U_STRING_INIT(testCase5
, "bar ", 6);
311 U_STRING_DECL(testCase6
, " bar ", 9);
312 U_STRING_INIT(testCase6
, " bar ", 9);
315 U_STRING_DECL(expectedResultA
, "", 0);
316 U_STRING_INIT(expectedResultA
, "", 0);
317 U_STRING_DECL(expectedResultB
, "foo", 3);
318 U_STRING_INIT(expectedResultB
, "foo", 3);
319 U_STRING_DECL(expectedResultC
, "unchanged", 9);
320 U_STRING_INIT(expectedResultC
, "unchanged", 9);
321 U_STRING_DECL(expectedResultD
, "bar", 3);
322 U_STRING_INIT(expectedResultD
, "bar", 3);
326 UnicodeString expectedResults
;
328 testString(UStr
, u_austrcpy(testcase
, testCase1
), expectedResultA
, IOSTREAM_EOF
|IOSTREAM_FAIL
);
329 testString(UStr
, u_austrcpy(testcase
, testCase2
), expectedResultB
, IOSTREAM_EOF
);
330 UStr
= UnicodeString(expectedResultC
);
331 testString(UStr
, u_austrcpy(testcase
, testCase3
), expectedResultC
, IOSTREAM_EOF
|IOSTREAM_FAIL
);
332 testString(UStr
, u_austrcpy(testcase
, testCase4
), expectedResultD
, IOSTREAM_EOF
);
333 testString(UStr
, u_austrcpy(testcase
, testCase5
), expectedResultD
, IOSTREAM_GOOD
);
334 testString(UStr
, u_austrcpy(testcase
, testCase6
), expectedResultD
, IOSTREAM_GOOD
);
338 U_CFUNC
void addStreamTests(TestNode
** root
) {
339 addTest(root
, &TestStream
, "stream/TestStream");
340 addTest(root
, &TestStreamEOF
, "stream/TestStreamEOF");