/*
-******************************************************************************
-*
-* Copyright (C) 1998-2006, 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"
#define DELIM_PS 0x2029
/* TODO: is this correct for all codepages? Should we just use \n and let the converter handle it? */
-#ifdef U_WINDOWS
+#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. */
{
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;
}
}
+void
+ufile_flush_io(UFILE *f)
+{
+ if((!f) || (!f->fFile)) {
+ return; /* skip if no file */
+ }
+
+ u_file_write_flush(NULL, 0, f, TRUE, FALSE);
+}
+
+
void
ufile_close_translit(UFILE *f)
{
}
-U_CAPI int32_t U_EXPORT2
+U_CFUNC int32_t U_EXPORT2
u_file_write_flush(const UChar *chars,
int32_t count,
UFILE *f,
/* Set up conversion parameters */
UErrorCode status = U_ZERO_ERROR;
const UChar *mySource = chars;
+ const UChar *mySourceBegin;
const UChar *mySourceEnd;
char charBuffer[UFILE_CHARBUFFER_SIZE];
char *myTarget = charBuffer;
/* Perform the conversion in a loop */
do {
+ mySourceBegin = mySource; /* beginning location for this loop */
status = U_ZERO_ERROR;
if(f->fConverter != NULL) { /* We have a valid converter */
ucnv_fromUnicode(f->fConverter,
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);
numConverted,
f->fFile);
- written += numConverted;
+ written += (int32_t) (mySource - mySourceBegin);
}
myTarget = charBuffer;
}
/* 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 */
}
*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);