X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..4388f060552cc537e71e957d32f35e9d75a61233:/icuSources/io/ustdio.c diff --git a/icuSources/io/ustdio.c b/icuSources/io/ustdio.c index 8ffd9050..df4c4f1c 100644 --- a/icuSources/io/ustdio.c +++ b/icuSources/io/ustdio.c @@ -1,21 +1,21 @@ /* -****************************************************************************** -* -* Copyright (C) 1998-2004, International Business Machines -* Corporation and others. All Rights Reserved. -* -****************************************************************************** -* -* File ustdio.c -* -* Modification History: -* -* Date Name Description -* 11/18/98 stephen Creation. -* 03/12/99 stephen Modified for new C API. -* 07/19/99 stephen Fixed read() and gets() -****************************************************************************** -*/ + ****************************************************************************** + * + * Copyright (C) 1998-2011, International Business Machines + * Corporation and others. All Rights Reserved. + * + ****************************************************************************** + * + * File ustdio.c + * + * Modification History: + * + * Date Name Description + * 11/18/98 stephen Creation. + * 03/12/99 stephen Modified for new C API. + * 07/19/99 stephen Fixed read() and gets() + ****************************************************************************** + */ #include "unicode/ustdio.h" #include "unicode/putil.h" @@ -36,11 +36,8 @@ #define DELIM_LS 0x2028 #define DELIM_PS 0x2029 -/* Leave this copyright notice here! */ -static const char copyright[] = U_COPYRIGHT_STRING; - /* TODO: is this correct for all codepages? Should we just use \n and let the converter handle it? */ -#ifdef WIN32 +#if U_PLATFORM_USES_ONLY_WIN32_API static const UChar DELIMITERS [] = { DELIM_CR, DELIM_LF, 0x0000 }; static const uint32_t DELIMITERS_LEN = 2; /* TODO: Default newline writing should be detected based upon the converter being used. */ @@ -166,6 +163,10 @@ static const UChar * u_file_translit(UFILE *f, const UChar *src, int32_t *count, { f->fTranslit->buffer = (UChar*)uprv_realloc(f->fTranslit->buffer, newlen * sizeof(UChar)); } + /* Check for malloc/realloc failure. */ + if (f->fTranslit->buffer == NULL) { + return NULL; + } f->fTranslit->capacity = newlen; } @@ -233,7 +234,18 @@ ufile_flush_translit(UFILE *f) return; #endif - u_file_write_flush(NULL, 0, f, TRUE); + u_file_write_flush(NULL, 0, f, FALSE, TRUE); +} + + +void +ufile_flush_io(UFILE *f) +{ + if((!f) || (!f->fFile)) { + return; /* skip if no file */ + } + + u_file_write_flush(NULL, 0, f, TRUE, FALSE); } @@ -283,58 +295,59 @@ u_fputc(UChar32 uc, U16_APPEND(buf, idx, sizeof(buf)/sizeof(*buf), uc, isError); if (isError) { - return EOF; + return U_EOF; } - return u_file_write(buf, idx, f) == idx ? uc : EOF; + return u_file_write(buf, idx, f) == idx ? uc : U_EOF; } -U_CAPI int32_t U_EXPORT2 -u_file_write_flush( const UChar *chars, - int32_t count, - UFILE *f, - UBool flush) +U_CFUNC int32_t U_EXPORT2 +u_file_write_flush(const UChar *chars, + int32_t count, + UFILE *f, + UBool flushIO, + UBool flushTranslit) { /* Set up conversion parameters */ UErrorCode status = U_ZERO_ERROR; const UChar *mySource = chars; - const UChar *sourceAlias = chars; + const UChar *mySourceBegin; const UChar *mySourceEnd; char charBuffer[UFILE_CHARBUFFER_SIZE]; char *myTarget = charBuffer; int32_t written = 0; int32_t numConverted = 0; - if (!f->fFile) { - int32_t charsLeft = f->str.fLimit - f->str.fPos; - if (flush && charsLeft > count) { - count++; - } - written = ufmt_min(count, charsLeft); - u_strncpy(f->str.fPos, chars, written); - f->str.fPos += written; - return written; - } - if (count < 0) { count = u_strlen(chars); } - mySourceEnd = chars + count; #if !UCONFIG_NO_TRANSLITERATION if((f->fTranslit) && (f->fTranslit->translit)) { /* Do the transliteration */ - mySource = u_file_translit(f, chars, &count, flush); - sourceAlias = mySource; - mySourceEnd = mySource + count; + mySource = u_file_translit(f, chars, &count, flushTranslit); } #endif + /* Write to a string. */ + if (!f->fFile) { + int32_t charsLeft = (int32_t)(f->str.fLimit - f->str.fPos); + if (flushIO && charsLeft > count) { + count++; + } + written = ufmt_min(count, charsLeft); + u_strncpy(f->str.fPos, mySource, written); + f->str.fPos += written; + return written; + } + + mySourceEnd = mySource + count; + /* Perform the conversion in a loop */ do { + mySourceBegin = mySource; /* beginning location for this loop */ status = U_ZERO_ERROR; - sourceAlias = mySource; if(f->fConverter != NULL) { /* We have a valid converter */ ucnv_fromUnicode(f->fConverter, &myTarget, @@ -342,11 +355,17 @@ u_file_write_flush( const UChar *chars, &mySource, mySourceEnd, NULL, - flush, + flushIO, &status); } else { /*weiv: do the invariant conversion */ - u_UCharsToChars(mySource, myTarget, count); - myTarget += count; + int32_t convertChars = (int32_t) (mySourceEnd - mySource); + if (convertChars > UFILE_CHARBUFFER_SIZE) { + convertChars = UFILE_CHARBUFFER_SIZE; + status = U_BUFFER_OVERFLOW_ERROR; + } + u_UCharsToChars(mySource, myTarget, convertChars); + mySource += convertChars; + myTarget += convertChars; } numConverted = (int32_t)(myTarget - charBuffer); @@ -357,7 +376,7 @@ u_file_write_flush( const UChar *chars, numConverted, f->fFile); - written += numConverted; + written += (int32_t) (mySource - mySourceBegin); } myTarget = charBuffer; } @@ -372,7 +391,7 @@ u_file_write( const UChar *chars, int32_t count, UFILE *f) { - return u_file_write_flush(chars,count,f,FALSE); + return u_file_write_flush(chars,count,f,FALSE,FALSE); } @@ -406,7 +425,7 @@ ufile_fill_uchar_buffer(UFILE *f) /* shift the buffer if it isn't empty */ if(dataSize != 0) { - uprv_memmove(f->fUCBuffer, str->fPos, dataSize * sizeof(UChar)); + uprv_memmove(f->fUCBuffer, str->fPos, dataSize * sizeof(UChar)); /* not accessing beyond memory */ } @@ -421,7 +440,7 @@ ufile_fill_uchar_buffer(UFILE *f) if (f->fFileno == 0) { /* Special case. Read from stdin one line at a time. */ char *retStr = fgets(charBuffer, ufmt_min(maxCPBytes, UFILE_CHARBUFFER_SIZE), f->fFile); - bytesRead = (retStr ? uprv_strlen(charBuffer) : 0); + bytesRead = (int32_t)(retStr ? uprv_strlen(charBuffer) : 0); } else { /* A normal file */ @@ -501,11 +520,11 @@ u_fgets(UChar *s, alias = str->fPos; /* Find how much to copy */ - if (dataSize < n) { + if (dataSize < (n - count)) { limit = str->fLimit; } else { - limit = alias + n; + limit = alias + (n - count); } if (!currDelim) { @@ -519,6 +538,12 @@ u_fgets(UChar *s, if (CAN_HAVE_COMBINED_STRING_DELIMITER(*alias)) { currDelim = *alias; } + else { + currDelim = 1; /* This isn't a newline, but it's used to say + that we should break later. We've checked all + possible newline combinations even across buffer + boundaries. */ + } count++; *(sItr++) = *(alias++); } @@ -567,7 +592,7 @@ ufile_getch(UFILE *f, UChar *ch) *ch = *(f->str.fPos)++; isValidChar = TRUE; } - else if (f) { + else { /* otherwise, fill the buffer and return the next character */ if(f->str.fPos >= f->str.fLimit) { ufile_fill_uchar_buffer(f);