]>
git.saurik.com Git - apple/icu.git/blob - icuSources/io/ustream.cpp
2 **********************************************************************
3 * Copyright (C) 2001-2011, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 * FILE NAME : ustream.cpp
8 * Modification History:
10 * Date Name Description
11 * 06/25/2001 grhoten Move iostream from unistr.h to here
12 ******************************************************************************
15 #include "unicode/utypes.h"
16 #include "unicode/uobject.h"
17 #include "unicode/ustream.h"
18 #include "unicode/ucnv.h"
19 #include "unicode/uchar.h"
20 #include "unicode/utf16.h"
27 #if U_IOSTREAM_SOURCE >= 199711
29 #define STD_NAMESPACE std::
31 #define STD_OSTREAM STD_NAMESPACE ostream
32 #define STD_ISTREAM STD_NAMESPACE istream
36 U_IO_API STD_OSTREAM
& U_EXPORT2
37 operator<<(STD_OSTREAM
& stream
, const UnicodeString
& str
)
39 if(str
.length() > 0) {
41 UConverter
*converter
;
42 UErrorCode errorCode
= U_ZERO_ERROR
;
44 // use the default converter to convert chunks of text
45 converter
= u_getDefaultConverter(&errorCode
);
46 if(U_SUCCESS(errorCode
)) {
47 const UChar
*us
= str
.getBuffer();
48 const UChar
*uLimit
= us
+ str
.length();
49 char *s
, *sLimit
= buffer
+ (sizeof(buffer
) - 1);
51 errorCode
= U_ZERO_ERROR
;
53 ucnv_fromUnicode(converter
, &s
, sLimit
, &us
, uLimit
, 0, FALSE
, &errorCode
);
60 } while(errorCode
== U_BUFFER_OVERFLOW_ERROR
);
61 u_releaseDefaultConverter(converter
);
69 U_IO_API STD_ISTREAM
& U_EXPORT2
70 operator>>(STD_ISTREAM
& stream
, UnicodeString
& str
)
72 // This is like ICU status checking.
77 /* ipfx should eat whitespace when ios::skipws is set */
81 UConverter
*converter
;
82 UErrorCode errorCode
= U_ZERO_ERROR
;
84 // use the default converter to convert chunks of text
85 converter
= u_getDefaultConverter(&errorCode
);
86 if(U_SUCCESS(errorCode
)) {
88 const UChar
*uLimit
= uBuffer
+ sizeof(uBuffer
)/sizeof(*uBuffer
);
89 const char *s
, *sLimit
;
92 UBool initialWhitespace
= TRUE
;
93 UBool continueReading
= TRUE
;
95 /* We need to consume one byte at a time to see what is considered whitespace. */
96 while (continueReading
) {
99 // The EOF is only set after the get() of an unavailable byte.
100 if (!initialWhitespace
) {
101 stream
.clear(stream
.eofbit
);
103 continueReading
= FALSE
;
105 sLimit
= &ch
+ (int)continueReading
;
108 errorCode
= U_ZERO_ERROR
;
110 Since we aren't guaranteed to see the state before this call,
111 this code won't work on stateful encodings like ISO-2022 or an EBCDIC stateful encoding.
112 We flush on the last byte to ensure that we output truncated multibyte characters.
114 ucnv_toUnicode(converter
, &us
, uLimit
, &s
, sLimit
, 0, !continueReading
, &errorCode
);
115 if(U_FAILURE(errorCode
)) {
116 /* Something really bad happened. setstate() isn't always an available API */
117 stream
.clear(stream
.failbit
);
120 /* Was the character consumed? */
122 /* Reminder: ibm-1390 & JISX0213 can output 2 Unicode code points */
123 int32_t uBuffSize
= us
-uBuffer
;
124 int32_t uBuffIdx
= 0;
125 while (uBuffIdx
< uBuffSize
) {
126 U16_NEXT(uBuffer
, uBuffIdx
, uBuffSize
, ch32
);
127 if (u_isWhitespace(ch32
)) {
128 if (!initialWhitespace
) {
131 stream
.putback(buffer
[--idx
]);
135 /* else skip intialWhitespace */
138 if (initialWhitespace
) {
140 When initialWhitespace is TRUE, we haven't appended any
141 character yet. This is where we truncate the string,
142 to avoid modifying the string before we know if we can
143 actually read from the stream.
146 initialWhitespace
= FALSE
;
158 u_releaseDefaultConverter(converter
);