Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

ufile.c

00001 /*
00002 *******************************************************************************
00003 *
00004 *   Copyright (C) 1998-1999, International Business Machines
00005 *   Corporation and others.  All Rights Reserved.
00006 *
00007 *******************************************************************************
00008 *
00009 * File ufile.c
00010 *
00011 * Modification History:
00012 *
00013 *   Date        Name        Description
00014 *   11/19/98    stephen     Creation.
00015 *   03/12/99    stephen     Modified for new C API.
00016 *   06/16/99    stephen     Changed T_LocaleBundle to u_locbund
00017 *   07/19/99    stephen     Fixed to use ucnv's default codepage.
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 /* the data in the following two functions should REALLY be somewhere else */
00034 /* convert from a country code (only the first 2 chars are significant)  */
00035 /* to an IBM codepage */
00036 
00037 /* thanks to http://czyborra.com/charsets/iso8859.htm for most of this info */
00038 static const char ufile_locale2codepage[][256] = {
00039   "af", "latin-1",  /* Afrikaans */
00040   "ar", "ibm-1256", /* arabic */
00041 
00042   "be", "ibm-915"  , /*  Byelorussian */
00043   "bg", "ibm-915"  , /* Bulgarian */
00044     
00045   "ca", "latin-1"  , /* catalan */
00046   "cs", "ibm-912"  , /* Czech */
00047   
00048   "da", "latin-1"  ,  /* danish */
00049   "de", "latin-1"  ,  /* german */
00050   
00051   "el", "ibm-813"  , /* Greek */
00052   "en", "latin-1"  ,  /* English */
00053   "eo", "ibm-913"  , /* Esperanto */
00054   "es", "latin-1"  ,  /* Spanish */
00055   "eu", "latin-1"  , /* basque */
00056   "et", "ibm-914"  , /* Estonian  */
00057   
00058   "fi", "latin-1"  ,  /* Finnish */
00059   "fo", "latin-1"  ,  /* faroese */
00060   "fr", "latin-1"  ,  /* French */
00061   
00062   "ga", "latin-1"  ,  /* Irish (Gaelic) */
00063   "gd", "latin-1"  ,  /* Scottish */
00064   
00065   "hr", "ibm-912"  , /* Croatian */
00066   "hu", "ibm-912"  , /* Hungarian */
00067   
00068   "in", "latin-1"  , /* Indonesian */
00069   "is", "latin-1"  ,  /* Icelandic */
00070   "it", "latin-1"  ,  /* Italian  */
00071   "iw", "ibm-916", /* hebrew */
00072   
00073   "ja", "ibm-943", /* Japanese */
00074   "ji", "ibm-916", /* Yiddish */
00075   
00076   "kl", "ibm-914", /* Greenlandic */
00077   "ko", "ibm-949", /* korean  */
00078   
00079   "lt", "ibm-914", /* Lithuanian */
00080   "lv", "ibm-914", /* latvian (lettish) */
00081   
00082   "mk", "ibm-915"  , /* Macedonian */
00083   "mt", "ibm-1208"  , /* Maltese [UTF8] */
00084   
00085   "nl", "latin-1"  ,  /* dutch */
00086   "no", "latin-1"  ,  /* Norwegian */
00087   
00088   "pl", "ibm-912"  , /* Polish */
00089   "pt", "latin-1"  ,  /* Portugese */
00090   
00091   "rm", "latin-1"  ,  /* Rhaeto-romanic (?) */
00092   "ro", "ibm-912"  , /* Romanian */
00093   "ru", "ibm-878"  , /* Russian */
00094   
00095   "sk", "ibm-912"  , /* Slovak */
00096 
00097   "sl", "ibm-912"  , /* Slovenian */
00098   "sq", "latin-1"  ,  /* albanian */
00099   "sr", "ibm-915"  , /* Serbian */
00100   "sv", "latin-1"  ,  /* Swedish */
00101   "sw", "latin-1"  ,  /* Swahili */
00102   
00103   "th", "ibm-1208" , /* Thai - UTF8 */
00104   
00105   "tr", "ibm-920",  /* Turkish */
00106   
00107   "uk", "ibm-915"  , /* pre 1990 Ukranian (?) */
00108   
00109   "zh", "Big-5",  /* Chinese */
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   /* if locale is 0, use the default */
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   /* if the codepage is 0, use the default for the locale */
00184   if(codepage == 0) {
00185     codepage = ufile_lookup_codepage(locale);
00186   
00187     /* if the codepage is still 0, the default codepage will be used */
00188   }
00189   
00190   /* if both locale and codepage are 0, use the system default codepage */
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       /* if locale is 0, use the default */
00230       if(locale == 0)
00231         locale = uloc_getDefault();
00232 
00233       result->fBundle = u_loccache_get(locale);
00234       if(result->fBundle == 0) {
00235         /* DO NOT FCLOSE HERE! */
00236         free(result);
00237         return 0;
00238       }
00239   } else {
00240       /* bootstrap mode */
00241       return result;
00242   }
00243 
00244   /* if the codepage is 0, use the default for the locale */
00245   if(codepage == 0) {
00246     codepage = ufile_lookup_codepage(locale); 
00247 
00248 
00249 
00250     /* if the codepage is still 0, the default codepage will be used */
00251     if(codepage == 0) {
00252         result->fConverter = ucnv_open(0, &status);
00253         if(U_FAILURE(status) || result->fConverter == 0) {
00254         /* DO NOT fclose here!!!!!! */
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         /* DO NOT fclose here!!!!!! */
00263         free(result);
00264         return 0;
00265       }
00266   } else if(useSysCP) { /* if both locale and codepage are 0, use the system default codepage */
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   /* if the codepage is 0, use the default for the locale */
00331   if(codepage == 0) {
00332     codepage = ufile_lookup_codepage(file->fBundle->fLocale);
00333   
00334     /* if the codepage is still 0, fall back on the default codepage */
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 }

Generated at Tue Dec 5 10:48:05 2000 for ICU by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000