00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "unicode/ustdio.h"
00021 #include "ufile.h"
00022 #include "ufmt_cmn.h"
00023 #include "unicode/ucnv.h"
00024 #include "unicode/ustring.h"
00025
00026 #include <string.h>
00027
00028 static const UChar DELIMITERS [] = { 0x000A, 0x0000 };
00029
00030 #define DELIM_CR 0x000D
00031 #define DELIM_LF 0x000A
00032
00033 #define IS_STRING_DELIMITER(s) (UBool)( (s) == DELIM_CR || \
00034 (s) == DELIM_LF )
00035
00036
00037
00038
00039 int32_t
00040 u_fputs(const UChar *s,
00041 UFILE *f)
00042 {
00043 int32_t count = u_file_write(s, u_strlen(s), f);
00044 count += u_file_write(DELIMITERS, u_strlen(DELIMITERS), f);
00045 return count;
00046 }
00047
00048 int32_t
00049 u_fputc(UChar uc,
00050 UFILE *f)
00051 {
00052 return u_file_write(&uc, 1, f) == 1 ? uc : EOF;
00053 }
00054
00055 int32_t
00056 u_file_write( const UChar *chars,
00057 int32_t count,
00058 UFILE *f)
00059 {
00060
00061 UErrorCode status = U_ZERO_ERROR;
00062 const UChar *mySource = chars;
00063 const UChar *sourceAlias = chars;
00064 const UChar *mySourceEnd = chars + count;
00065 char *myTarget = f->fCharBuffer;
00066 int32_t bufferSize = UFILE_CHARBUFFER_SIZE;
00067 int32_t written = 0;
00068
00069
00070 do {
00071 status = U_ZERO_ERROR;
00072 sourceAlias = mySource;
00073 if(f->fConverter != NULL) {
00074 ucnv_fromUnicode(f->fConverter,
00075 &myTarget,
00076 f->fCharBuffer + bufferSize,
00077 &mySource,
00078 mySourceEnd,
00079 NULL,
00080 TRUE,
00081 &status);
00082 } else {
00083 u_UCharsToChars(mySource, myTarget, count);
00084 myTarget += count;
00085 }
00086
00087
00088 fwrite(f->fCharBuffer,
00089 sizeof(char),
00090 myTarget - f->fCharBuffer,
00091 f->fFile);
00092
00093 written += (myTarget - f->fCharBuffer);
00094 myTarget = f->fCharBuffer;
00095 }
00096 while(status == U_BUFFER_OVERFLOW_ERROR);
00097
00098
00099 return written;
00100 }
00101
00102
00103 void
00104 ufile_fill_uchar_buffer(UFILE *f)
00105 {
00106 UErrorCode status;
00107 const char *mySource;
00108 const char *mySourceEnd;
00109 UChar *myTarget;
00110 int32_t bufferSize;
00111 int32_t maxCPBytes;
00112 int32_t bytesRead;
00113 int32_t availLength;
00114 int32_t dataSize;
00115
00116
00117
00118 dataSize = f->fUCLimit - f->fUCPos;
00119 if(dataSize != 0) {
00120 memmove(f->fUCBuffer,
00121 f->fUCPos,
00122 dataSize * sizeof(UChar));
00123 }
00124
00125
00126
00127 availLength = UFILE_UCHARBUFFER_SIZE - dataSize;
00128
00129
00130
00131 maxCPBytes = availLength / (f->fConverter!=NULL?(2*ucnv_getMinCharSize(f->fConverter)):1);
00132
00133
00134 bytesRead = fread(f->fCharBuffer,
00135 sizeof(char),
00136 ufmt_min(maxCPBytes, UFILE_CHARBUFFER_SIZE),
00137 f->fFile);
00138
00139
00140 status = U_ZERO_ERROR;
00141 mySource = f->fCharBuffer;
00142 mySourceEnd = f->fCharBuffer + bytesRead;
00143 myTarget = f->fUCBuffer + dataSize;
00144 bufferSize = UFILE_UCHARBUFFER_SIZE;
00145
00146 if(f->fConverter != NULL) {
00147
00148 ucnv_toUnicode(f->fConverter,
00149 &myTarget,
00150 f->fUCBuffer + bufferSize,
00151 &mySource,
00152 mySourceEnd,
00153 NULL,
00154 (UBool)(feof(f->fFile) != 0),
00155 &status);
00156
00157 } else {
00158 u_charsToUChars(mySource, myTarget, bytesRead);
00159 myTarget += bytesRead;
00160 }
00161
00162
00163 f->fUCPos = f->fUCBuffer;
00164 f->fUCLimit = myTarget;
00165 }
00166
00167 UChar*
00168 u_fgets(UFILE *f,
00169 int32_t n,
00170 UChar *s)
00171 {
00172 int32_t dataSize;
00173 int32_t read;
00174 int32_t count;
00175 UChar *alias;
00176
00177
00178
00179 ufile_fill_uchar_buffer(f);
00180
00181
00182 --n;
00183
00184
00185 dataSize = f->fUCLimit - f->fUCPos;
00186
00187
00188 if(dataSize > n) {
00189
00190
00191 alias = f->fUCPos;
00192 count = 0;
00193 while( ! IS_STRING_DELIMITER(*alias) && count < n) {
00194 ++count;
00195 alias++;
00196 }
00197
00198
00199 memcpy(s, f->fUCPos, count * sizeof(UChar));
00200
00201
00202 s[count] = 0x0000;
00203
00204
00205 f->fUCPos += count;
00206
00207
00208 ufile_fill_uchar_buffer(f);
00209
00210
00211 while(IS_STRING_DELIMITER(*(f->fUCPos)) && f->fUCPos < f->fUCLimit)
00212 (f->fUCPos)++;
00213
00214
00215 return s;
00216 }
00217
00218
00219 read = 0;
00220 do {
00221
00222
00223 dataSize = f->fUCLimit - f->fUCPos;
00224
00225
00226 alias = f->fUCPos;
00227 count = 0;
00228 while( ! IS_STRING_DELIMITER(*alias) && alias < f->fUCLimit && count < n) {
00229 ++count;
00230 alias++;
00231 }
00232
00233
00234 memcpy(s + read, f->fUCPos, count * sizeof(UChar));
00235
00236
00237 read += count;
00238
00239
00240 f->fUCPos += count;
00241
00242
00243 if(alias < f->fUCLimit) {
00244
00245
00246 ufile_fill_uchar_buffer(f);
00247
00248
00249 while(IS_STRING_DELIMITER(*(f->fUCPos)) && f->fUCPos < f->fUCLimit)
00250 (f->fUCPos)++;
00251
00252
00253 break;
00254 }
00255
00256
00257 ufile_fill_uchar_buffer(f);
00258
00259 } while(dataSize != 0 && read < n);
00260
00261
00262 if(read == 0)
00263 return 0;
00264
00265
00266 s[read] = 0x0000;
00267 return s;
00268 }
00269
00270 UChar
00271 u_fgetc(UFILE *f)
00272 {
00273
00274 if(f->fUCPos < f->fUCLimit)
00275 return *(f->fUCPos)++;
00276
00277 else {
00278 ufile_fill_uchar_buffer(f);
00279 if(f->fUCPos < f->fUCLimit)
00280 return *(f->fUCPos)++;
00281 else
00282 return 0xFFFF;
00283 }
00284 }
00285
00286
00287 static UChar _charAt(int32_t offset, void *context) {
00288 return ((UFILE*) context)->fUCPos[offset];
00289 }
00290
00291
00292 UChar32
00293 u_fgetcx(UFILE *f) {
00294 int32_t length;
00295 int32_t offset;
00296 UChar32 c32;
00297 UChar c16;
00298
00299
00300 if (f->fUCPos >= f->fUCLimit) {
00301 ufile_fill_uchar_buffer(f);
00302 }
00303
00304
00305 if (f->fUCPos < f->fUCLimit) {
00306 c16 = *(f->fUCPos)++;
00307 } else {
00308 c16 = U_EOF;
00309 }
00310
00311
00312 if (c16 != 0x005C ) {
00313 return c16;
00314 }
00315
00316
00317 length = f->fUCLimit - f->fUCPos;
00318
00319
00320
00321 if (length < 10) {
00322
00323 ufile_fill_uchar_buffer(f);
00324 length = f->fUCLimit - f->fUCPos;
00325 }
00326
00327
00328 offset = 0;
00329 c32 = u_unescapeAt(_charAt, &offset, length, (void*)f);
00330
00331
00332 f->fUCPos += offset;
00333
00334 return c32;
00335 }
00336
00337 UChar
00338 u_fungetc(UChar c,
00339 UFILE *f)
00340 {
00341
00342 if(f->fUCPos == f->fUCBuffer)
00343 return 0xFFFF;
00344
00345 else {
00346 *--(f->fUCPos) = c;
00347 return c;
00348 }
00349 }
00350
00351 int32_t
00352 u_file_read( UChar *chars,
00353 int32_t count,
00354 UFILE *f)
00355 {
00356 int32_t dataSize;
00357 int32_t read;
00358
00359
00360 ufile_fill_uchar_buffer(f);
00361
00362
00363 dataSize = f->fUCLimit - f->fUCPos;
00364
00365
00366 if(dataSize > count) {
00367 memcpy(chars, f->fUCPos, count * sizeof(UChar));
00368
00369
00370 f->fUCPos += count;
00371
00372
00373 return count;
00374 }
00375
00376
00377 read = 0;
00378 do {
00379
00380
00381 dataSize = f->fUCLimit - f->fUCPos;
00382
00383
00384 memcpy(chars + read, f->fUCPos, dataSize * sizeof(UChar));
00385
00386
00387 read += dataSize;
00388
00389
00390 f->fUCPos += dataSize;
00391
00392
00393 ufile_fill_uchar_buffer(f);
00394
00395 } while(dataSize != 0 && read < count);
00396
00397 return read;
00398 }