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
|
U_IO_API STD_ISTREAM & U_EXPORT2
|
||||||
operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
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 */
|
/* ipfx should eat whitespace when ios::skipws is set */
|
||||||
UChar uBuffer[16];
|
UChar uBuffer[16];
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
@ -78,7 +83,6 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
|||||||
UConverter *converter;
|
UConverter *converter;
|
||||||
UErrorCode errorCode = U_ZERO_ERROR;
|
UErrorCode errorCode = U_ZERO_ERROR;
|
||||||
|
|
||||||
str.truncate(0);
|
|
||||||
// use the default converter to convert chunks of text
|
// use the default converter to convert chunks of text
|
||||||
converter = u_getDefaultConverter(&errorCode);
|
converter = u_getDefaultConverter(&errorCode);
|
||||||
if(U_SUCCESS(errorCode)) {
|
if(U_SUCCESS(errorCode)) {
|
||||||
@ -104,6 +108,11 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
|||||||
us = uBuffer;
|
us = uBuffer;
|
||||||
s = &ch;
|
s = &ch;
|
||||||
errorCode = U_ZERO_ERROR;
|
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);
|
ucnv_toUnicode(converter, &us, uLimit, &s, sLimit, 0, !continueReading, &errorCode);
|
||||||
if(U_FAILURE(errorCode)) {
|
if(U_FAILURE(errorCode)) {
|
||||||
/* Something really bad happened */
|
/* Something really bad happened */
|
||||||
@ -128,8 +137,17 @@ operator>>(STD_ISTREAM& stream, UnicodeString& str)
|
|||||||
/* else skip intialWhitespace */
|
/* else skip intialWhitespace */
|
||||||
}
|
}
|
||||||
else {
|
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);
|
str.append(ch32);
|
||||||
initialWhitespace = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
@ -170,6 +170,7 @@ void
|
|||||||
testString(
|
testString(
|
||||||
UnicodeString& str,
|
UnicodeString& str,
|
||||||
const char* testString,
|
const char* testString,
|
||||||
|
const char* expectedString,
|
||||||
int32_t expectedStatus)
|
int32_t expectedStatus)
|
||||||
{
|
{
|
||||||
#ifdef USE_SSTREAM
|
#ifdef USE_SSTREAM
|
||||||
@ -192,6 +193,9 @@ testString(
|
|||||||
printBits(sstrm);
|
printBits(sstrm);
|
||||||
log_err("Expected status %d, Got %d. See verbose output for details\n", getBitStatus(sstrm), expectedStatus);
|
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)
|
static void U_CALLCONV TestStreamEOF(void)
|
||||||
@ -226,12 +230,13 @@ static void U_CALLCONV TestStreamEOF(void)
|
|||||||
log_verbose("Testing operator >> for UnicodeString...\n");
|
log_verbose("Testing operator >> for UnicodeString...\n");
|
||||||
|
|
||||||
UnicodeString UStr;
|
UnicodeString UStr;
|
||||||
testString(UStr, "", IOSTREAM_EOF|IOSTREAM_FAIL);
|
testString(UStr, "", "", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||||
testString(UStr, "foo", IOSTREAM_EOF);
|
testString(UStr, "foo", "foo", IOSTREAM_EOF);
|
||||||
testString(UStr, " ", IOSTREAM_EOF|IOSTREAM_FAIL);
|
UStr = "unchanged";
|
||||||
testString(UStr, " bar", IOSTREAM_EOF);
|
testString(UStr, " ", "unchanged", IOSTREAM_EOF|IOSTREAM_FAIL);
|
||||||
testString(UStr, "bar ", IOSTREAM_GOOD);
|
testString(UStr, " bar", "bar", IOSTREAM_EOF);
|
||||||
testString(UStr, " bar ", IOSTREAM_GOOD);
|
testString(UStr, "bar ", "bar", IOSTREAM_GOOD);
|
||||||
|
testString(UStr, " bar ", "bar", IOSTREAM_GOOD);
|
||||||
}
|
}
|
||||||
U_CDECL_END
|
U_CDECL_END
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user