00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "uhash.h"
00022 #include "unicode/ustdio.h"
00023 #include "ufile.h"
00024 #include "unicode/uloc.h"
00025 #include "loccache.h"
00026 #include "unicode/ures.h"
00027 #include "unicode/ucnv.h"
00028
00029 #include <string.h>
00030 #include <stdlib.h>
00031
00032
00033
00034
00035
00036
00037
00038 static const char ufile_locale2codepage[][256] = {
00039 "af", "latin-1",
00040 "ar", "ibm-1256",
00041
00042 "be", "ibm-915" ,
00043 "bg", "ibm-915" ,
00044
00045 "ca", "latin-1" ,
00046 "cs", "ibm-912" ,
00047
00048 "da", "latin-1" ,
00049 "de", "latin-1" ,
00050
00051 "el", "ibm-813" ,
00052 "en", "latin-1" ,
00053 "eo", "ibm-913" ,
00054 "es", "latin-1" ,
00055 "eu", "latin-1" ,
00056 "et", "ibm-914" ,
00057
00058 "fi", "latin-1" ,
00059 "fo", "latin-1" ,
00060 "fr", "latin-1" ,
00061
00062 "ga", "latin-1" ,
00063 "gd", "latin-1" ,
00064
00065 "hr", "ibm-912" ,
00066 "hu", "ibm-912" ,
00067
00068 "in", "latin-1" ,
00069 "is", "latin-1" ,
00070 "it", "latin-1" ,
00071 "iw", "ibm-916",
00072
00073 "ja", "ibm-943",
00074 "ji", "ibm-916",
00075
00076 "kl", "ibm-914",
00077 "ko", "ibm-949",
00078
00079 "lt", "ibm-914",
00080 "lv", "ibm-914",
00081
00082 "mk", "ibm-915" ,
00083 "mt", "ibm-1208" ,
00084
00085 "nl", "latin-1" ,
00086 "no", "latin-1" ,
00087
00088 "pl", "ibm-912" ,
00089 "pt", "latin-1" ,
00090
00091 "rm", "latin-1" ,
00092 "ro", "ibm-912" ,
00093 "ru", "ibm-878" ,
00094
00095 "sk", "ibm-912" ,
00096
00097 "sl", "ibm-912" ,
00098 "sq", "latin-1" ,
00099 "sr", "ibm-915" ,
00100 "sv", "latin-1" ,
00101 "sw", "latin-1" ,
00102
00103 "th", "ibm-1208" ,
00104
00105 "tr", "ibm-920",
00106
00107 "uk", "ibm-915" ,
00108
00109 "zh", "Big-5",
00110 0, 0
00111 };
00112
00113 static const char*
00114 ufile_lookup_codepage(const char *locale)
00115 {
00116 int32_t i;
00117 for(i = 0; ufile_locale2codepage[i][0]; i+= 2)
00118 if( ! strncmp(ufile_locale2codepage[i], locale, 2))
00119 return ufile_locale2codepage[i + 1];
00120 return 0;
00121 }
00122
00123 UBool hasICUData(const char *cp) {
00124 UErrorCode status = U_ZERO_ERROR;
00125 UConverter *cnv = NULL;
00126 #if 0
00127 UResourceBundle *r = NULL;
00128
00129 r = ures_open(NULL, NULL, &status);
00130 if(U_FAILURE(status)) {
00131 return FALSE;
00132 } else {
00133 ures_close(r);
00134 }
00135 #endif
00136 cnv = ucnv_open(cp, &status);
00137 if(cnv == NULL) {
00138 return FALSE;
00139 } else {
00140 ucnv_close(cnv);
00141 }
00142
00143 return TRUE;
00144 }
00145
00146
00147
00148 UFILE*
00149 u_fopen(const char *filename,
00150 const char *perm,
00151 const char *locale,
00152 const char *codepage)
00153 {
00154 UErrorCode status = U_ZERO_ERROR;
00155 UBool useSysCP = (UBool)(locale == 0 && codepage == 0);
00156 UFILE *result = (UFILE*) malloc(sizeof(UFILE));
00157 if(result == 0)
00158 return 0;
00159
00160 result->fFile = fopen(filename, perm);
00161 if(result->fFile == 0) {
00162 free(result);
00163 return 0;
00164 }
00165
00166 result->fOwnFile = TRUE;
00167
00168
00169 if(locale == 0)
00170 locale = uloc_getDefault();
00171
00172 result->fBundle = u_loccache_get(locale);
00173 if(result->fBundle == 0) {
00174 fclose(result->fFile);
00175 free(result);
00176 return 0;
00177 }
00178
00179 result->fOwnBundle = FALSE;
00180 result->fUCPos = result->fUCBuffer;
00181 result->fUCLimit = result->fUCBuffer;
00182
00183
00184 if(codepage == 0) {
00185 codepage = ufile_lookup_codepage(locale);
00186
00187
00188 }
00189
00190
00191 else if(useSysCP)
00192 codepage = 0;
00193
00194 result->fConverter = ucnv_open(codepage, &status);
00195 if(U_FAILURE(status) || result->fConverter == 0) {
00196 fclose(result->fFile);
00197 free(result);
00198 return 0;
00199 }
00200
00201 return result;
00202 }
00203
00204 UFILE*
00205 u_finit(FILE *f,
00206 const char *locale,
00207 const char *codepage)
00208 {
00209 UErrorCode status = U_ZERO_ERROR;
00210 UBool useSysCP = (UBool)(locale == NULL && codepage == NULL);
00211 UFILE *result = (UFILE*) malloc(sizeof(UFILE));
00212 if(result == 0)
00213 return 0;
00214
00215
00216 #ifdef WIN32
00217 result->fFile = &_iob[_fileno(f)];
00218 #else
00219 result->fFile = f;
00220 #endif
00221 result->fOwnFile = FALSE;
00222 result->fOwnBundle = FALSE;
00223 result->fUCPos = result->fUCBuffer;
00224 result->fUCLimit = result->fUCBuffer;
00225 result->fConverter = NULL;
00226 result->fBundle = NULL;
00227
00228 if(hasICUData(codepage) == TRUE) {
00229
00230 if(locale == 0)
00231 locale = uloc_getDefault();
00232
00233 result->fBundle = u_loccache_get(locale);
00234 if(result->fBundle == 0) {
00235
00236 free(result);
00237 return 0;
00238 }
00239 } else {
00240
00241 return result;
00242 }
00243
00244
00245 if(codepage == 0) {
00246 codepage = ufile_lookup_codepage(locale);
00247
00248
00249
00250
00251 if(codepage == 0) {
00252 result->fConverter = ucnv_open(0, &status);
00253 if(U_FAILURE(status) || result->fConverter == 0) {
00254
00255 free(result);
00256 return 0;
00257 }
00258 }
00259 } else if (*codepage != '\0') {
00260 result->fConverter = ucnv_open(codepage, &status);
00261 if(U_FAILURE(status) || result->fConverter == 0) {
00262
00263 free(result);
00264 return 0;
00265 }
00266 } else if(useSysCP) {
00267 codepage = 0;
00268 }
00269 return result;
00270 }
00271
00272 void
00273 u_fclose(UFILE *file)
00274 {
00275 fflush(file->fFile);
00276
00277 if(file->fOwnFile)
00278 fclose(file->fFile);
00279
00280 if(file->fOwnBundle)
00281 u_locbund_delete(file->fBundle);
00282
00283 ucnv_close(file->fConverter);
00284
00285 free(file);
00286 }
00287
00288 FILE*
00289 u_fgetfile( UFILE *f)
00290 {
00291 return f->fFile;
00292 }
00293
00294 const char*
00295 u_fgetlocale( UFILE *file)
00296 {
00297 return file->fBundle->fLocale;
00298 }
00299
00300 int32_t
00301 u_fsetlocale(const char *locale,
00302 UFILE *file)
00303 {
00304 if(file->fOwnBundle)
00305 u_locbund_delete(file->fBundle);
00306
00307 file->fBundle = u_loccache_get(locale);
00308 file->fOwnBundle = FALSE;
00309
00310 return file->fBundle == 0 ? -1 : 0;
00311 }
00312
00313 const char*
00314 u_fgetcodepage(UFILE *file)
00315 {
00316 UErrorCode status = U_ZERO_ERROR;
00317 const char *codepage;
00318
00319 codepage = ucnv_getName(file->fConverter, &status);
00320 if(U_FAILURE(status)) return 0;
00321 return codepage;
00322 }
00323
00324 int32_t
00325 u_fsetcodepage( const char *codepage,
00326 UFILE *file)
00327 {
00328 UErrorCode status = U_ZERO_ERROR;
00329
00330
00331 if(codepage == 0) {
00332 codepage = ufile_lookup_codepage(file->fBundle->fLocale);
00333
00334
00335 }
00336
00337 ucnv_close(file->fConverter);
00338 file->fConverter = ucnv_open(codepage, &status);
00339 if(U_FAILURE(status))
00340 return -1;
00341 return 0;
00342 }
00343
00344
00345 UConverter * u_fgetConverter(UFILE *file)
00346 {
00347 return file->fConverter;
00348 }