]>
git.saurik.com Git - apple/icu.git/blob - icuSources/io/ufile.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ******************************************************************************
6 * Copyright (C) 1998-2015, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 ******************************************************************************
13 * Modification History:
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 ******************************************************************************
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.
28 #undef __STRICT_ANSI__
32 #include "unicode/ustdio.h"
34 #if !UCONFIG_NO_CONVERSION
39 #include "unicode/uloc.h"
40 #include "unicode/ures.h"
41 #include "unicode/ucnv.h"
42 #include "unicode/ustring.h"
46 #if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno)
47 /* Windows likes to rename Unix-like functions */
48 #define fileno _fileno
58 UErrorCode status
= U_ZERO_ERROR
;
63 result
= (UFILE
*) uprv_malloc(sizeof(UFILE
));
68 uprv_memset(result
, 0, sizeof(UFILE
));
69 result
->fFileno
= fileno(f
);
72 result
->str
.fBuffer
= result
->fUCBuffer
;
73 result
->str
.fPos
= result
->fUCBuffer
;
74 result
->str
.fLimit
= result
->fUCBuffer
;
76 #if !UCONFIG_NO_FORMATTING
77 /* if locale is 0, use the default */
78 if(u_locbund_init(&result
->str
.fBundle
, locale
) == 0) {
79 /* DO NOT FCLOSE HERE! */
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
);
89 /* else result->fConverter is already memset'd to NULL. */
91 if(U_SUCCESS(status
)) {
92 result
->fOwnFile
= takeOwnership
;
95 #if !UCONFIG_NO_FORMATTING
96 u_locbund_close(&result
->str
.fBundle
);
98 /* DO NOT fclose here!!!!!! */
106 U_CAPI UFILE
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
109 const char *codepage
)
111 return finit_owner(f
, locale
, codepage
, FALSE
);
114 U_CAPI UFILE
* U_EXPORT2
117 const char *codepage
)
119 return finit_owner(f
, locale
, codepage
, TRUE
);
122 U_CAPI UFILE
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
123 u_fopen(const char *filename
,
126 const char *codepage
)
129 FILE *systemFile
= fopen(filename
, perm
);
130 if(systemFile
== 0) {
134 result
= finit_owner(systemFile
, locale
, codepage
, TRUE
);
137 /* Something bad happened.
138 Maybe the converter couldn't be opened. */
142 return result
; /* not a file leak */
145 U_CAPI UFILE
* U_EXPORT2
146 u_fopen_u(const UChar
*filename
,
149 const char *codepage
)
154 u_austrcpy(buffer
, filename
);
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. */
160 // TODO: test this code path, including wperm.
161 wchar_t wperm
[40] = {};
163 mbstowcs_s(&retVal
, wperm
, UPRV_LENGTHOF(wperm
), perm
, _TRUNCATE
);
164 FILE *systemFile
= _wfopen((const wchar_t *)filename
, wperm
);
166 result
= finit_owner(systemFile
, locale
, codepage
, TRUE
);
169 /* Something bad happened.
170 Maybe the converter couldn't be opened. */
175 return result
; /* not a file leak */
178 U_CAPI UFILE
* U_EXPORT2
179 u_fstropen(UChar
*stringBuf
,
189 result
= (UFILE
*) uprv_malloc(sizeof(UFILE
));
190 /* Null pointer test */
191 if (result
== NULL
) {
192 return NULL
; /* Just get out. */
194 uprv_memset(result
, 0, sizeof(UFILE
));
195 result
->str
.fBuffer
= stringBuf
;
196 result
->str
.fPos
= stringBuf
;
197 result
->str
.fLimit
= stringBuf
+capacity
;
199 #if !UCONFIG_NO_FORMATTING
200 /* if locale is 0, use the default */
201 if(u_locbund_init(&result
->str
.fBundle
, locale
) == 0) {
202 /* DO NOT FCLOSE HERE! */
211 U_CAPI UBool U_EXPORT2
218 endOfBuffer
= (UBool
)(f
->str
.fPos
>= f
->str
.fLimit
);
219 if (f
->fFile
!= NULL
) {
220 return endOfBuffer
&& feof(f
->fFile
);
225 U_CAPI
void U_EXPORT2
226 u_fflush(UFILE
*file
)
228 ufile_flush_translit(file
);
229 ufile_flush_io(file
);
233 else if (file
->str
.fPos
< file
->str
.fLimit
) {
234 *(file
->str
.fPos
++) = 0;
236 /* TODO: flush input */
240 u_frewind(UFILE
*file
)
243 ucnv_reset(file
->fConverter
);
246 file
->str
.fLimit
= file
->fUCBuffer
;
247 file
->str
.fPos
= file
->fUCBuffer
;
250 file
->str
.fPos
= file
->str
.fBuffer
;
254 U_CAPI
void U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
255 u_fclose(UFILE
*file
)
259 ufile_close_translit(file
);
264 #if !UCONFIG_NO_FORMATTING
265 u_locbund_close(&file
->str
.fBundle
);
268 ucnv_close(file
->fConverter
);
273 U_CAPI
FILE* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
274 u_fgetfile( UFILE
*f
)
279 #if !UCONFIG_NO_FORMATTING
281 U_CAPI
const char* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
282 u_fgetlocale( UFILE
*file
)
284 return file
->str
.fBundle
.fLocale
;
287 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
288 u_fsetlocale(UFILE
*file
,
291 u_locbund_close(&file
->str
.fBundle
);
293 return u_locbund_init(&file
->str
.fBundle
, locale
) == 0 ? -1 : 0;
298 U_CAPI
const char* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
299 u_fgetcodepage(UFILE
*file
)
301 UErrorCode status
= U_ZERO_ERROR
;
302 const char *codepage
= NULL
;
304 if (file
->fConverter
) {
305 codepage
= ucnv_getName(file
->fConverter
, &status
);
306 if(U_FAILURE(status
))
312 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
313 u_fsetcodepage( const char *codepage
,
316 UErrorCode status
= U_ZERO_ERROR
;
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
)) {
331 U_CAPI UConverter
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
332 u_fgetConverter(UFILE
*file
)
334 return file
->fConverter
;
336 #if !UCONFIG_NO_FORMATTING
337 U_CAPI
const UNumberFormat
* U_EXPORT2
u_fgetNumberFormat(UFILE
*file
)
339 return u_locbund_getNumberFormat(&file
->str
.fBundle
, UNUM_DECIMAL
);