]>
git.saurik.com Git - apple/icu.git/blob - icuSources/io/ufile.c
2 ******************************************************************************
4 * Copyright (C) 1998-2015, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
11 * Modification History:
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 ******************************************************************************
22 * fileno is not declared when building with GCC in strict mode.
24 #if defined(__GNUC__) && defined(__STRICT_ANSI__)
25 #undef __STRICT_ANSI__
29 #include "unicode/ustdio.h"
31 #if !UCONFIG_NO_CONVERSION
34 #include "unicode/uloc.h"
35 #include "unicode/ures.h"
36 #include "unicode/ucnv.h"
37 #include "unicode/ustring.h"
41 #if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno)
42 /* Windows likes to rename Unix-like functions */
43 #define fileno _fileno
53 UErrorCode status
= U_ZERO_ERROR
;
58 result
= (UFILE
*) uprv_malloc(sizeof(UFILE
));
63 uprv_memset(result
, 0, sizeof(UFILE
));
64 result
->fFileno
= fileno(f
);
66 #if U_PLATFORM_USES_ONLY_WIN32_API && _MSC_VER < 1900
68 * Below is a very old workaround (ICU ticket:231).
70 * Previously, 'FILE*' from inside and outside ICU's DLL
71 * were different, because they pointed into local copies
72 * of the io block. At least by VS 2015 the implementation
74 * stdio = _acrt_iob_func(0)
75 * .. which is a function call, so should return the same pointer
76 * regardless of call site.
77 * As of _MSC_VER 1900 this patch is retired, at 16 years old.
79 if (0 <= result
->fFileno
&& result
->fFileno
<= 2) {
80 /* stdin, stdout and stderr need to be special cased for Windows 98 */
82 result
->fFile
= &__iob_func()[_fileno(f
)];
84 result
->fFile
= &_iob
[_fileno(f
)];
93 result
->str
.fBuffer
= result
->fUCBuffer
;
94 result
->str
.fPos
= result
->fUCBuffer
;
95 result
->str
.fLimit
= result
->fUCBuffer
;
97 #if !UCONFIG_NO_FORMATTING
98 /* if locale is 0, use the default */
99 if(u_locbund_init(&result
->str
.fBundle
, locale
) == 0) {
100 /* DO NOT FCLOSE HERE! */
106 /* If the codepage is not "" use the ucnv_open default behavior */
107 if(codepage
== NULL
|| *codepage
!= '\0') {
108 result
->fConverter
= ucnv_open(codepage
, &status
);
110 /* else result->fConverter is already memset'd to NULL. */
112 if(U_SUCCESS(status
)) {
113 result
->fOwnFile
= takeOwnership
;
116 #if !UCONFIG_NO_FORMATTING
117 u_locbund_close(&result
->str
.fBundle
);
119 /* DO NOT fclose here!!!!!! */
127 U_CAPI UFILE
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
130 const char *codepage
)
132 return finit_owner(f
, locale
, codepage
, FALSE
);
135 U_CAPI UFILE
* U_EXPORT2
138 const char *codepage
)
140 return finit_owner(f
, locale
, codepage
, TRUE
);
143 U_CAPI UFILE
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
144 u_fopen(const char *filename
,
147 const char *codepage
)
150 FILE *systemFile
= fopen(filename
, perm
);
151 if(systemFile
== 0) {
155 result
= finit_owner(systemFile
, locale
, codepage
, TRUE
);
158 /* Something bad happened.
159 Maybe the converter couldn't be opened. */
163 return result
; /* not a file leak */
166 U_CAPI UFILE
* U_EXPORT2
167 u_fopen_u(const UChar
*filename
,
170 const char *codepage
)
175 u_austrcpy(buffer
, filename
);
177 result
= u_fopen(buffer
, perm
, locale
, codepage
);
178 #if U_PLATFORM_USES_ONLY_WIN32_API
179 /* Try Windows API _wfopen if the above fails. */
181 FILE *systemFile
= _wfopen(filename
, (UChar
*)perm
);
183 result
= finit_owner(systemFile
, locale
, codepage
, TRUE
);
186 /* Something bad happened.
187 Maybe the converter couldn't be opened. */
192 return result
; /* not a file leak */
195 U_CAPI UFILE
* U_EXPORT2
196 u_fstropen(UChar
*stringBuf
,
206 result
= (UFILE
*) uprv_malloc(sizeof(UFILE
));
207 /* Null pointer test */
208 if (result
== NULL
) {
209 return NULL
; /* Just get out. */
211 uprv_memset(result
, 0, sizeof(UFILE
));
212 result
->str
.fBuffer
= stringBuf
;
213 result
->str
.fPos
= stringBuf
;
214 result
->str
.fLimit
= stringBuf
+capacity
;
216 #if !UCONFIG_NO_FORMATTING
217 /* if locale is 0, use the default */
218 if(u_locbund_init(&result
->str
.fBundle
, locale
) == 0) {
219 /* DO NOT FCLOSE HERE! */
228 U_CAPI UBool U_EXPORT2
235 endOfBuffer
= (UBool
)(f
->str
.fPos
>= f
->str
.fLimit
);
236 if (f
->fFile
!= NULL
) {
237 return endOfBuffer
&& feof(f
->fFile
);
242 U_CAPI
void U_EXPORT2
243 u_fflush(UFILE
*file
)
245 ufile_flush_translit(file
);
246 ufile_flush_io(file
);
250 else if (file
->str
.fPos
< file
->str
.fLimit
) {
251 *(file
->str
.fPos
++) = 0;
253 /* TODO: flush input */
257 u_frewind(UFILE
*file
)
260 ucnv_reset(file
->fConverter
);
263 file
->str
.fLimit
= file
->fUCBuffer
;
264 file
->str
.fPos
= file
->fUCBuffer
;
267 file
->str
.fPos
= file
->str
.fBuffer
;
271 U_CAPI
void U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
272 u_fclose(UFILE
*file
)
276 ufile_close_translit(file
);
281 #if !UCONFIG_NO_FORMATTING
282 u_locbund_close(&file
->str
.fBundle
);
285 ucnv_close(file
->fConverter
);
290 U_CAPI
FILE* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
291 u_fgetfile( UFILE
*f
)
296 #if !UCONFIG_NO_FORMATTING
298 U_CAPI
const char* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
299 u_fgetlocale( UFILE
*file
)
301 return file
->str
.fBundle
.fLocale
;
304 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
305 u_fsetlocale(UFILE
*file
,
308 u_locbund_close(&file
->str
.fBundle
);
310 return u_locbund_init(&file
->str
.fBundle
, locale
) == 0 ? -1 : 0;
315 U_CAPI
const char* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
316 u_fgetcodepage(UFILE
*file
)
318 UErrorCode status
= U_ZERO_ERROR
;
319 const char *codepage
= NULL
;
321 if (file
->fConverter
) {
322 codepage
= ucnv_getName(file
->fConverter
, &status
);
323 if(U_FAILURE(status
))
329 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
330 u_fsetcodepage( const char *codepage
,
333 UErrorCode status
= U_ZERO_ERROR
;
336 /* We use the normal default codepage for this system, and not the one for the locale. */
337 if ((file
->str
.fPos
== file
->str
.fBuffer
) && (file
->str
.fLimit
== file
->str
.fBuffer
)) {
338 ucnv_close(file
->fConverter
);
339 file
->fConverter
= ucnv_open(codepage
, &status
);
340 if(U_SUCCESS(status
)) {
348 U_CAPI UConverter
* U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
349 u_fgetConverter(UFILE
*file
)
351 return file
->fConverter
;
353 #if !UCONFIG_NO_FORMATTING
354 U_CAPI
const UNumberFormat
* U_EXPORT2
u_fgetNumberFormat(UFILE
*file
)
356 return u_locbund_getNumberFormat(&file
->str
.fBundle
, UNUM_DECIMAL
);