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