1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/io/ufile.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,314 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* 1.7 +* Copyright (C) 1998-2013, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +****************************************************************************** 1.11 +* 1.12 +* File ufile.c 1.13 +* 1.14 +* Modification History: 1.15 +* 1.16 +* Date Name Description 1.17 +* 11/19/98 stephen Creation. 1.18 +* 03/12/99 stephen Modified for new C API. 1.19 +* 06/16/99 stephen Changed T_LocaleBundle to u_locbund 1.20 +* 07/19/99 stephen Fixed to use ucnv's default codepage. 1.21 +****************************************************************************** 1.22 +*/ 1.23 + 1.24 +/* 1.25 + * fileno is not declared when building with GCC in strict mode. 1.26 + */ 1.27 +#if defined(__GNUC__) && defined(__STRICT_ANSI__) 1.28 +#undef __STRICT_ANSI__ 1.29 +#endif 1.30 + 1.31 +#include "locmap.h" 1.32 +#include "unicode/ustdio.h" 1.33 +#include "ufile.h" 1.34 +#include "unicode/uloc.h" 1.35 +#include "unicode/ures.h" 1.36 +#include "unicode/ucnv.h" 1.37 +#include "cstring.h" 1.38 +#include "cmemory.h" 1.39 + 1.40 +#if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno) 1.41 +/* Windows likes to rename Unix-like functions */ 1.42 +#define fileno _fileno 1.43 +#endif 1.44 + 1.45 +static UFILE* 1.46 +finit_owner(FILE *f, 1.47 + const char *locale, 1.48 + const char *codepage, 1.49 + UBool take 1.50 + ) 1.51 +{ 1.52 + UErrorCode status = U_ZERO_ERROR; 1.53 + UFILE *result; 1.54 + if(f == NULL) { 1.55 + return 0; 1.56 + } 1.57 + result = (UFILE*) uprv_malloc(sizeof(UFILE)); 1.58 + if(result == NULL) { 1.59 + return 0; 1.60 + } 1.61 + 1.62 + uprv_memset(result, 0, sizeof(UFILE)); 1.63 + result->fFileno = fileno(f); 1.64 + 1.65 +#if U_PLATFORM_USES_ONLY_WIN32_API 1.66 + if (0 <= result->fFileno && result->fFileno <= 2) { 1.67 + /* stdin, stdout and stderr need to be special cased for Windows 98 */ 1.68 +#if _MSC_VER >= 1400 1.69 + result->fFile = &__iob_func()[_fileno(f)]; 1.70 +#else 1.71 + result->fFile = &_iob[_fileno(f)]; 1.72 +#endif 1.73 + } 1.74 + else 1.75 +#endif 1.76 + { 1.77 + result->fFile = f; 1.78 + } 1.79 + 1.80 + result->str.fBuffer = result->fUCBuffer; 1.81 + result->str.fPos = result->fUCBuffer; 1.82 + result->str.fLimit = result->fUCBuffer; 1.83 + 1.84 +#if !UCONFIG_NO_FORMATTING 1.85 + /* if locale is 0, use the default */ 1.86 + if(u_locbund_init(&result->str.fBundle, locale) == 0) { 1.87 + /* DO NOT FCLOSE HERE! */ 1.88 + uprv_free(result); 1.89 + return 0; 1.90 + } 1.91 +#endif 1.92 + 1.93 + /* If the codepage is not "" use the ucnv_open default behavior */ 1.94 + if(codepage == NULL || *codepage != '\0') { 1.95 + result->fConverter = ucnv_open(codepage, &status); 1.96 + } 1.97 + /* else result->fConverter is already memset'd to NULL. */ 1.98 + 1.99 + if(U_SUCCESS(status)) { 1.100 + result->fOwnFile = take; 1.101 + } 1.102 + else { 1.103 +#if !UCONFIG_NO_FORMATTING 1.104 + u_locbund_close(&result->str.fBundle); 1.105 +#endif 1.106 + /* DO NOT fclose here!!!!!! */ 1.107 + uprv_free(result); 1.108 + result = NULL; 1.109 + } 1.110 + 1.111 + return result; 1.112 +} 1.113 + 1.114 +U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.115 +u_finit(FILE *f, 1.116 + const char *locale, 1.117 + const char *codepage) 1.118 +{ 1.119 + return finit_owner(f, locale, codepage, FALSE); 1.120 +} 1.121 + 1.122 +U_CAPI UFILE* U_EXPORT2 1.123 +u_fadopt(FILE *f, 1.124 + const char *locale, 1.125 + const char *codepage) 1.126 +{ 1.127 + return finit_owner(f, locale, codepage, TRUE); 1.128 +} 1.129 + 1.130 +U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.131 +u_fopen(const char *filename, 1.132 + const char *perm, 1.133 + const char *locale, 1.134 + const char *codepage) 1.135 +{ 1.136 + UFILE *result; 1.137 + FILE *systemFile = fopen(filename, perm); 1.138 + if(systemFile == 0) { 1.139 + return 0; 1.140 + } 1.141 + 1.142 + result = finit_owner(systemFile, locale, codepage, TRUE); 1.143 + 1.144 + if (!result) { 1.145 + /* Something bad happened. 1.146 + Maybe the converter couldn't be opened. */ 1.147 + fclose(systemFile); 1.148 + } 1.149 + 1.150 + return result; /* not a file leak */ 1.151 +} 1.152 + 1.153 +U_CAPI UFILE* U_EXPORT2 1.154 +u_fstropen(UChar *stringBuf, 1.155 + int32_t capacity, 1.156 + const char *locale) 1.157 +{ 1.158 + UFILE *result; 1.159 + 1.160 + if (capacity < 0) { 1.161 + return NULL; 1.162 + } 1.163 + 1.164 + result = (UFILE*) uprv_malloc(sizeof(UFILE)); 1.165 + /* Null pointer test */ 1.166 + if (result == NULL) { 1.167 + return NULL; /* Just get out. */ 1.168 + } 1.169 + uprv_memset(result, 0, sizeof(UFILE)); 1.170 + result->str.fBuffer = stringBuf; 1.171 + result->str.fPos = stringBuf; 1.172 + result->str.fLimit = stringBuf+capacity; 1.173 + 1.174 +#if !UCONFIG_NO_FORMATTING 1.175 + /* if locale is 0, use the default */ 1.176 + if(u_locbund_init(&result->str.fBundle, locale) == 0) { 1.177 + /* DO NOT FCLOSE HERE! */ 1.178 + uprv_free(result); 1.179 + return 0; 1.180 + } 1.181 +#endif 1.182 + 1.183 + return result; 1.184 +} 1.185 + 1.186 +U_CAPI UBool U_EXPORT2 1.187 +u_feof(UFILE *f) 1.188 +{ 1.189 + UBool endOfBuffer; 1.190 + if (f == NULL) { 1.191 + return TRUE; 1.192 + } 1.193 + endOfBuffer = (UBool)(f->str.fPos >= f->str.fLimit); 1.194 + if (f->fFile != NULL) { 1.195 + return endOfBuffer && feof(f->fFile); 1.196 + } 1.197 + return endOfBuffer; 1.198 +} 1.199 + 1.200 +U_CAPI void U_EXPORT2 1.201 +u_fflush(UFILE *file) 1.202 +{ 1.203 + ufile_flush_translit(file); 1.204 + ufile_flush_io(file); 1.205 + if (file->fFile) { 1.206 + fflush(file->fFile); 1.207 + } 1.208 + else if (file->str.fPos < file->str.fLimit) { 1.209 + *(file->str.fPos++) = 0; 1.210 + } 1.211 + /* TODO: flush input */ 1.212 +} 1.213 + 1.214 +U_CAPI void 1.215 +u_frewind(UFILE *file) 1.216 +{ 1.217 + u_fflush(file); 1.218 + ucnv_reset(file->fConverter); 1.219 + if (file->fFile) { 1.220 + rewind(file->fFile); 1.221 + file->str.fLimit = file->fUCBuffer; 1.222 + file->str.fPos = file->fUCBuffer; 1.223 + } 1.224 + else { 1.225 + file->str.fPos = file->str.fBuffer; 1.226 + } 1.227 +} 1.228 + 1.229 +U_CAPI void U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.230 +u_fclose(UFILE *file) 1.231 +{ 1.232 + if (file) { 1.233 + u_fflush(file); 1.234 + ufile_close_translit(file); 1.235 + 1.236 + if(file->fOwnFile) 1.237 + fclose(file->fFile); 1.238 + 1.239 +#if !UCONFIG_NO_FORMATTING 1.240 + u_locbund_close(&file->str.fBundle); 1.241 +#endif 1.242 + 1.243 + ucnv_close(file->fConverter); 1.244 + uprv_free(file); 1.245 + } 1.246 +} 1.247 + 1.248 +U_CAPI FILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.249 +u_fgetfile( UFILE *f) 1.250 +{ 1.251 + return f->fFile; 1.252 +} 1.253 + 1.254 +#if !UCONFIG_NO_FORMATTING 1.255 + 1.256 +U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.257 +u_fgetlocale( UFILE *file) 1.258 +{ 1.259 + return file->str.fBundle.fLocale; 1.260 +} 1.261 + 1.262 +U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.263 +u_fsetlocale(UFILE *file, 1.264 + const char *locale) 1.265 +{ 1.266 + u_locbund_close(&file->str.fBundle); 1.267 + 1.268 + return u_locbund_init(&file->str.fBundle, locale) == 0 ? -1 : 0; 1.269 +} 1.270 + 1.271 +#endif 1.272 + 1.273 +U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.274 +u_fgetcodepage(UFILE *file) 1.275 +{ 1.276 + UErrorCode status = U_ZERO_ERROR; 1.277 + const char *codepage = NULL; 1.278 + 1.279 + if (file->fConverter) { 1.280 + codepage = ucnv_getName(file->fConverter, &status); 1.281 + if(U_FAILURE(status)) 1.282 + return 0; 1.283 + } 1.284 + return codepage; 1.285 +} 1.286 + 1.287 +U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.288 +u_fsetcodepage( const char *codepage, 1.289 + UFILE *file) 1.290 +{ 1.291 + UErrorCode status = U_ZERO_ERROR; 1.292 + int32_t retVal = -1; 1.293 + 1.294 + /* We use the normal default codepage for this system, and not the one for the locale. */ 1.295 + if ((file->str.fPos == file->str.fBuffer) && (file->str.fLimit == file->str.fBuffer)) { 1.296 + ucnv_close(file->fConverter); 1.297 + file->fConverter = ucnv_open(codepage, &status); 1.298 + if(U_SUCCESS(status)) { 1.299 + retVal = 0; 1.300 + } 1.301 + } 1.302 + return retVal; 1.303 +} 1.304 + 1.305 + 1.306 +U_CAPI UConverter * U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ 1.307 +u_fgetConverter(UFILE *file) 1.308 +{ 1.309 + return file->fConverter; 1.310 +} 1.311 +#if !UCONFIG_NO_FORMATTING 1.312 +U_CAPI const UNumberFormat* U_EXPORT2 u_fgetNumberFormat(UFILE *file) 1.313 +{ 1.314 + return u_locbund_getNumberFormat(&file->str.fBundle, UNUM_DECIMAL); 1.315 +} 1.316 +#endif 1.317 +