1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2001-2010, International Business Machines 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************** 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* FILE NAME : ustream.cpp 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History: 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Date Name Description 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 06/25/2001 grhoten Move iostream from unistr.h to here 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uobject.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustream.h" 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnv.h" 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uchar.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_cnv.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h> 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// console IO 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if U_IOSTREAM_SOURCE >= 198506 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if U_IOSTREAM_SOURCE >= 199711 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STD_NAMESPACE std:: 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STD_NAMESPACE 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STD_OSTREAM STD_NAMESPACE ostream 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STD_ISTREAM STD_NAMESPACE istream 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_IO_API STD_OSTREAM & U_EXPORT2 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)operator<<(STD_OSTREAM& stream, const UnicodeString& str) 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(str.length() > 0) { 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[200]; 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *converter; 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode = U_ZERO_ERROR; 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use the default converter to convert chunks of text 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) converter = u_getDefaultConverter(&errorCode); 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *us = str.getBuffer(); 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *uLimit = us + str.length(); 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *s, *sLimit = buffer + (sizeof(buffer) - 1); 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode = U_ZERO_ERROR; 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s = buffer; 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_fromUnicode(converter, &s, sLimit, &us, uLimit, 0, FALSE, &errorCode); 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *s = 0; 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // write this chunk 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s > buffer) { 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stream << buffer; 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while(errorCode == U_BUFFER_OVERFLOW_ERROR); 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_releaseDefaultConverter(converter); 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* stream.flush();*/ 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return stream; 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_IO_API STD_ISTREAM & U_EXPORT2 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)operator>>(STD_ISTREAM& stream, UnicodeString& str) 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This is like ICU status checking. 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (stream.fail()) { 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return stream; 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* ipfx should eat whitespace when ios::skipws is set */ 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar uBuffer[16]; 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char buffer[16]; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t idx = 0; 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter *converter; 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode errorCode = U_ZERO_ERROR; 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use the default converter to convert chunks of text 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) converter = u_getDefaultConverter(&errorCode); 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(errorCode)) { 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *us = uBuffer; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *uLimit = uBuffer + sizeof(uBuffer)/sizeof(*uBuffer); 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *s, *sLimit; 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char ch; 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar ch32; 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool initialWhitespace = TRUE; 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool continueReading = TRUE; 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* We need to consume one byte at a time to see what is considered whitespace. */ 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (continueReading) { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ch = stream.get(); 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (stream.eof()) { 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The EOF is only set after the get() of an unavailable byte. 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!initialWhitespace) { 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stream.clear(stream.eofbit); 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continueReading = FALSE; 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sLimit = &ch + (int)continueReading; 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) us = uBuffer; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s = &ch; 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) errorCode = U_ZERO_ERROR; 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Since we aren't guaranteed to see the state before this call, 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) this code won't work on stateful encodings like ISO-2022 or an EBCDIC stateful encoding. 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) We flush on the last byte to ensure that we output truncated multibyte characters. 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_toUnicode(converter, &us, uLimit, &s, sLimit, 0, !continueReading, &errorCode); 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(errorCode)) { 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Something really bad happened. setstate() isn't always an available API */ 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stream.clear(stream.failbit); 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto STOP_READING; 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Was the character consumed? */ 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (us != uBuffer) { 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Reminder: ibm-1390 & JISX0213 can output 2 Unicode code points */ 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t uBuffSize = us-uBuffer; 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t uBuffIdx = 0; 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (uBuffIdx < uBuffSize) { 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U16_NEXT(uBuffer, uBuffIdx, uBuffSize, ch32); 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (u_isWhitespace(ch32)) { 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!initialWhitespace) { 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer[idx++] = ch; 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (idx > 0) { 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) stream.putback(buffer[--idx]); 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto STOP_READING; 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* else skip intialWhitespace */ 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (initialWhitespace) { 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) When initialWhitespace is TRUE, we haven't appended any 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) character yet. This is where we truncate the string, 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) to avoid modifying the string before we know if we can 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) actually read from the stream. 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) str.truncate(0); 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initialWhitespace = FALSE; 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) str.append(ch32); 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) idx = 0; 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer[idx++] = ch; 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)STOP_READING: 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_releaseDefaultConverter(converter); 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* stream.flush();*/ 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return stream; 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 173