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