intl/icu/source/io/ufile.c

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 ******************************************************************************
michael@0 3 *
michael@0 4 * Copyright (C) 1998-2013, International Business Machines
michael@0 5 * Corporation and others. All Rights Reserved.
michael@0 6 *
michael@0 7 ******************************************************************************
michael@0 8 *
michael@0 9 * File ufile.c
michael@0 10 *
michael@0 11 * Modification History:
michael@0 12 *
michael@0 13 * Date Name Description
michael@0 14 * 11/19/98 stephen Creation.
michael@0 15 * 03/12/99 stephen Modified for new C API.
michael@0 16 * 06/16/99 stephen Changed T_LocaleBundle to u_locbund
michael@0 17 * 07/19/99 stephen Fixed to use ucnv's default codepage.
michael@0 18 ******************************************************************************
michael@0 19 */
michael@0 20
michael@0 21 /*
michael@0 22 * fileno is not declared when building with GCC in strict mode.
michael@0 23 */
michael@0 24 #if defined(__GNUC__) && defined(__STRICT_ANSI__)
michael@0 25 #undef __STRICT_ANSI__
michael@0 26 #endif
michael@0 27
michael@0 28 #include "locmap.h"
michael@0 29 #include "unicode/ustdio.h"
michael@0 30 #include "ufile.h"
michael@0 31 #include "unicode/uloc.h"
michael@0 32 #include "unicode/ures.h"
michael@0 33 #include "unicode/ucnv.h"
michael@0 34 #include "cstring.h"
michael@0 35 #include "cmemory.h"
michael@0 36
michael@0 37 #if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno)
michael@0 38 /* Windows likes to rename Unix-like functions */
michael@0 39 #define fileno _fileno
michael@0 40 #endif
michael@0 41
michael@0 42 static UFILE*
michael@0 43 finit_owner(FILE *f,
michael@0 44 const char *locale,
michael@0 45 const char *codepage,
michael@0 46 UBool take
michael@0 47 )
michael@0 48 {
michael@0 49 UErrorCode status = U_ZERO_ERROR;
michael@0 50 UFILE *result;
michael@0 51 if(f == NULL) {
michael@0 52 return 0;
michael@0 53 }
michael@0 54 result = (UFILE*) uprv_malloc(sizeof(UFILE));
michael@0 55 if(result == NULL) {
michael@0 56 return 0;
michael@0 57 }
michael@0 58
michael@0 59 uprv_memset(result, 0, sizeof(UFILE));
michael@0 60 result->fFileno = fileno(f);
michael@0 61
michael@0 62 #if U_PLATFORM_USES_ONLY_WIN32_API
michael@0 63 if (0 <= result->fFileno && result->fFileno <= 2) {
michael@0 64 /* stdin, stdout and stderr need to be special cased for Windows 98 */
michael@0 65 #if _MSC_VER >= 1400
michael@0 66 result->fFile = &__iob_func()[_fileno(f)];
michael@0 67 #else
michael@0 68 result->fFile = &_iob[_fileno(f)];
michael@0 69 #endif
michael@0 70 }
michael@0 71 else
michael@0 72 #endif
michael@0 73 {
michael@0 74 result->fFile = f;
michael@0 75 }
michael@0 76
michael@0 77 result->str.fBuffer = result->fUCBuffer;
michael@0 78 result->str.fPos = result->fUCBuffer;
michael@0 79 result->str.fLimit = result->fUCBuffer;
michael@0 80
michael@0 81 #if !UCONFIG_NO_FORMATTING
michael@0 82 /* if locale is 0, use the default */
michael@0 83 if(u_locbund_init(&result->str.fBundle, locale) == 0) {
michael@0 84 /* DO NOT FCLOSE HERE! */
michael@0 85 uprv_free(result);
michael@0 86 return 0;
michael@0 87 }
michael@0 88 #endif
michael@0 89
michael@0 90 /* If the codepage is not "" use the ucnv_open default behavior */
michael@0 91 if(codepage == NULL || *codepage != '\0') {
michael@0 92 result->fConverter = ucnv_open(codepage, &status);
michael@0 93 }
michael@0 94 /* else result->fConverter is already memset'd to NULL. */
michael@0 95
michael@0 96 if(U_SUCCESS(status)) {
michael@0 97 result->fOwnFile = take;
michael@0 98 }
michael@0 99 else {
michael@0 100 #if !UCONFIG_NO_FORMATTING
michael@0 101 u_locbund_close(&result->str.fBundle);
michael@0 102 #endif
michael@0 103 /* DO NOT fclose here!!!!!! */
michael@0 104 uprv_free(result);
michael@0 105 result = NULL;
michael@0 106 }
michael@0 107
michael@0 108 return result;
michael@0 109 }
michael@0 110
michael@0 111 U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 112 u_finit(FILE *f,
michael@0 113 const char *locale,
michael@0 114 const char *codepage)
michael@0 115 {
michael@0 116 return finit_owner(f, locale, codepage, FALSE);
michael@0 117 }
michael@0 118
michael@0 119 U_CAPI UFILE* U_EXPORT2
michael@0 120 u_fadopt(FILE *f,
michael@0 121 const char *locale,
michael@0 122 const char *codepage)
michael@0 123 {
michael@0 124 return finit_owner(f, locale, codepage, TRUE);
michael@0 125 }
michael@0 126
michael@0 127 U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 128 u_fopen(const char *filename,
michael@0 129 const char *perm,
michael@0 130 const char *locale,
michael@0 131 const char *codepage)
michael@0 132 {
michael@0 133 UFILE *result;
michael@0 134 FILE *systemFile = fopen(filename, perm);
michael@0 135 if(systemFile == 0) {
michael@0 136 return 0;
michael@0 137 }
michael@0 138
michael@0 139 result = finit_owner(systemFile, locale, codepage, TRUE);
michael@0 140
michael@0 141 if (!result) {
michael@0 142 /* Something bad happened.
michael@0 143 Maybe the converter couldn't be opened. */
michael@0 144 fclose(systemFile);
michael@0 145 }
michael@0 146
michael@0 147 return result; /* not a file leak */
michael@0 148 }
michael@0 149
michael@0 150 U_CAPI UFILE* U_EXPORT2
michael@0 151 u_fstropen(UChar *stringBuf,
michael@0 152 int32_t capacity,
michael@0 153 const char *locale)
michael@0 154 {
michael@0 155 UFILE *result;
michael@0 156
michael@0 157 if (capacity < 0) {
michael@0 158 return NULL;
michael@0 159 }
michael@0 160
michael@0 161 result = (UFILE*) uprv_malloc(sizeof(UFILE));
michael@0 162 /* Null pointer test */
michael@0 163 if (result == NULL) {
michael@0 164 return NULL; /* Just get out. */
michael@0 165 }
michael@0 166 uprv_memset(result, 0, sizeof(UFILE));
michael@0 167 result->str.fBuffer = stringBuf;
michael@0 168 result->str.fPos = stringBuf;
michael@0 169 result->str.fLimit = stringBuf+capacity;
michael@0 170
michael@0 171 #if !UCONFIG_NO_FORMATTING
michael@0 172 /* if locale is 0, use the default */
michael@0 173 if(u_locbund_init(&result->str.fBundle, locale) == 0) {
michael@0 174 /* DO NOT FCLOSE HERE! */
michael@0 175 uprv_free(result);
michael@0 176 return 0;
michael@0 177 }
michael@0 178 #endif
michael@0 179
michael@0 180 return result;
michael@0 181 }
michael@0 182
michael@0 183 U_CAPI UBool U_EXPORT2
michael@0 184 u_feof(UFILE *f)
michael@0 185 {
michael@0 186 UBool endOfBuffer;
michael@0 187 if (f == NULL) {
michael@0 188 return TRUE;
michael@0 189 }
michael@0 190 endOfBuffer = (UBool)(f->str.fPos >= f->str.fLimit);
michael@0 191 if (f->fFile != NULL) {
michael@0 192 return endOfBuffer && feof(f->fFile);
michael@0 193 }
michael@0 194 return endOfBuffer;
michael@0 195 }
michael@0 196
michael@0 197 U_CAPI void U_EXPORT2
michael@0 198 u_fflush(UFILE *file)
michael@0 199 {
michael@0 200 ufile_flush_translit(file);
michael@0 201 ufile_flush_io(file);
michael@0 202 if (file->fFile) {
michael@0 203 fflush(file->fFile);
michael@0 204 }
michael@0 205 else if (file->str.fPos < file->str.fLimit) {
michael@0 206 *(file->str.fPos++) = 0;
michael@0 207 }
michael@0 208 /* TODO: flush input */
michael@0 209 }
michael@0 210
michael@0 211 U_CAPI void
michael@0 212 u_frewind(UFILE *file)
michael@0 213 {
michael@0 214 u_fflush(file);
michael@0 215 ucnv_reset(file->fConverter);
michael@0 216 if (file->fFile) {
michael@0 217 rewind(file->fFile);
michael@0 218 file->str.fLimit = file->fUCBuffer;
michael@0 219 file->str.fPos = file->fUCBuffer;
michael@0 220 }
michael@0 221 else {
michael@0 222 file->str.fPos = file->str.fBuffer;
michael@0 223 }
michael@0 224 }
michael@0 225
michael@0 226 U_CAPI void U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 227 u_fclose(UFILE *file)
michael@0 228 {
michael@0 229 if (file) {
michael@0 230 u_fflush(file);
michael@0 231 ufile_close_translit(file);
michael@0 232
michael@0 233 if(file->fOwnFile)
michael@0 234 fclose(file->fFile);
michael@0 235
michael@0 236 #if !UCONFIG_NO_FORMATTING
michael@0 237 u_locbund_close(&file->str.fBundle);
michael@0 238 #endif
michael@0 239
michael@0 240 ucnv_close(file->fConverter);
michael@0 241 uprv_free(file);
michael@0 242 }
michael@0 243 }
michael@0 244
michael@0 245 U_CAPI FILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 246 u_fgetfile( UFILE *f)
michael@0 247 {
michael@0 248 return f->fFile;
michael@0 249 }
michael@0 250
michael@0 251 #if !UCONFIG_NO_FORMATTING
michael@0 252
michael@0 253 U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 254 u_fgetlocale( UFILE *file)
michael@0 255 {
michael@0 256 return file->str.fBundle.fLocale;
michael@0 257 }
michael@0 258
michael@0 259 U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 260 u_fsetlocale(UFILE *file,
michael@0 261 const char *locale)
michael@0 262 {
michael@0 263 u_locbund_close(&file->str.fBundle);
michael@0 264
michael@0 265 return u_locbund_init(&file->str.fBundle, locale) == 0 ? -1 : 0;
michael@0 266 }
michael@0 267
michael@0 268 #endif
michael@0 269
michael@0 270 U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 271 u_fgetcodepage(UFILE *file)
michael@0 272 {
michael@0 273 UErrorCode status = U_ZERO_ERROR;
michael@0 274 const char *codepage = NULL;
michael@0 275
michael@0 276 if (file->fConverter) {
michael@0 277 codepage = ucnv_getName(file->fConverter, &status);
michael@0 278 if(U_FAILURE(status))
michael@0 279 return 0;
michael@0 280 }
michael@0 281 return codepage;
michael@0 282 }
michael@0 283
michael@0 284 U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 285 u_fsetcodepage( const char *codepage,
michael@0 286 UFILE *file)
michael@0 287 {
michael@0 288 UErrorCode status = U_ZERO_ERROR;
michael@0 289 int32_t retVal = -1;
michael@0 290
michael@0 291 /* We use the normal default codepage for this system, and not the one for the locale. */
michael@0 292 if ((file->str.fPos == file->str.fBuffer) && (file->str.fLimit == file->str.fBuffer)) {
michael@0 293 ucnv_close(file->fConverter);
michael@0 294 file->fConverter = ucnv_open(codepage, &status);
michael@0 295 if(U_SUCCESS(status)) {
michael@0 296 retVal = 0;
michael@0 297 }
michael@0 298 }
michael@0 299 return retVal;
michael@0 300 }
michael@0 301
michael@0 302
michael@0 303 U_CAPI UConverter * U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
michael@0 304 u_fgetConverter(UFILE *file)
michael@0 305 {
michael@0 306 return file->fConverter;
michael@0 307 }
michael@0 308 #if !UCONFIG_NO_FORMATTING
michael@0 309 U_CAPI const UNumberFormat* U_EXPORT2 u_fgetNumberFormat(UFILE *file)
michael@0 310 {
michael@0 311 return u_locbund_getNumberFormat(&file->str.fBundle, UNUM_DECIMAL);
michael@0 312 }
michael@0 313 #endif
michael@0 314

mercurial