ICU-5830 Better iostream error handling
X-SVN-Rev: 22629
This commit is contained in:
parent
f7286f7ed6
commit
4976895e3b
@ -71,6 +71,11 @@ operator<<(STD_OSTREAM& stream, const UnicodeString& str)
|
||||
U_IO_API STD_ISTREAM & U_EXPORT2
|
||||
operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
||||
{
|
||||
// This is like ICU status checking.
|
||||
if (stream.fail()) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
/* ipfx should eat whitespace when ios::skipws is set */
|
||||
UChar uBuffer[16];
|
||||
char buffer[16];
|
||||
@ -78,7 +83,6 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
||||
UConverter *converter;
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
|
||||
str.truncate(0);
|
||||
// use the default converter to convert chunks of text
|
||||
converter = u_getDefaultConverter(&errorCode);
|
||||
if(U_SUCCESS(errorCode)) {
|
||||
@ -104,6 +108,11 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
||||
us = uBuffer;
|
||||
s = &ch;
|
||||
errorCode = U_ZERO_ERROR;
|
||||
/*
|
||||
Since we aren't guaranteed to see the state before this call,
|
||||
this code won't work on stateful encodings like ISO-2022 or an EBCDIC stateful encoding.
|
||||
We flush on the last byte to ensure that we output truncated multibyte characters.
|
||||
*/
|
||||
ucnv_toUnicode(converter, &us, uLimit, &s, sLimit, 0, !continueReading, &errorCode);
|
||||
if(U_FAILURE(errorCode)) {
|
||||
/* Something really bad happened */
|
||||
@ -128,8 +137,17 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
||||
/* else skip intialWhitespace */
|
||||
}
|
||||
else {
|
||||
if (initialWhitespace) {
|
||||
/*
|
||||
When initialWhitespace is TRUE, we haven't appended any
|
||||
character yet. This is where we truncate the string,
|
||||
to avoid modifying the string before we know if we can
|
||||
actually read from the stream.
|
||||
*/
|
||||
str.truncate(0);
|
||||
initialWhitespace = FALSE;
|
||||
}
|
||||
str.append(ch32);
|
||||
initialWhitespace = FALSE;
|
||||
}
|
||||
}
|
||||
idx = 0;
|
||||
|
@ -170,6 +170,7 @@ void
|
||||
testString(
|
||||
UnicodeString& str,
|
||||
const char* testString,
|
||||
const char* expectedString,
|
||||
int32_t expectedStatus)
|
||||
{
|
||||
#ifdef USE_SSTREAM
|
||||
@ -192,6 +193,9 @@ testString(
|
||||
printBits(sstrm);
|
||||
log_err("Expected status %d, Got %d. See verbose output for details\n", getBitStatus(sstrm), expectedStatus);
|
||||
}
|
||||
if (str != UnicodeString(expectedString)) {
|
||||
log_err("Did not get expected results from \"%s\", expected \"%s\"\n", testString, expectedString);
|
||||
}
|
||||
}
|
||||
|
||||
static void U_CALLCONV TestStreamEOF(void)
|
||||
@ -226,12 +230,13 @@ static void U_CALLCONV TestStreamEOF(void)
|
||||
log_verbose("Testing operator >> for UnicodeString...\n");
|
||||
|
||||
UnicodeString UStr;
|
||||
testString(UStr, "", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||
testString(UStr, "foo", IOSTREAM_EOF);
|
||||
testString(UStr, " ", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||
testString(UStr, " bar", IOSTREAM_EOF);
|
||||
testString(UStr, "bar ", IOSTREAM_GOOD);
|
||||
testString(UStr, " bar ", IOSTREAM_GOOD);
|
||||
testString(UStr, "", "", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||
testString(UStr, "foo", "foo", IOSTREAM_EOF);
|
||||
UStr = "unchanged";
|
||||
testString(UStr, " ", "unchanged", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||
testString(UStr, " bar", "bar", IOSTREAM_EOF);
|
||||
testString(UStr, "bar ", "bar", IOSTREAM_GOOD);
|
||||
testString(UStr, " bar ", "bar", IOSTREAM_GOOD);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user