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