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

ufmt_cmn.c

00001 /*
00002 *******************************************************************************
00003 *
00004 *   Copyright (C) 1998-1999, International Business Machines
00005 *   Corporation and others.  All Rights Reserved.
00006 *
00007 *******************************************************************************
00008 *
00009 * File ufmt_cmn.c
00010 *
00011 * Modification History:
00012 *
00013 *   Date        Name        Description
00014 *   12/02/98    stephen     Creation.
00015 *   03/12/99    stephen     Modified for new C API.
00016 *   03/15/99    stephen     Added defaultCPToUnicode, unicodeToDefaultCP
00017 *   07/19/99    stephen     Fixed bug in defaultCPToUnicode
00018 *******************************************************************************
00019 */
00020 
00021 #include <stdlib.h>
00022 #include "ufmt_cmn.h"
00023 #include "unicode/uchar.h"
00024 #include "unicode/ucnv.h"
00025 #include "umutex.h"
00026 
00027 int
00028 ufmt_digitvalue(UChar c)
00029 {
00030   return c - 0x0030 - (c >= 0x0041 ? (c >= 0x0061 ? 39 : 7) : 0);
00031 }
00032 
00033 UBool
00034 ufmt_isdigit(UChar     c,
00035          int32_t     radix)
00036 {
00037   int digitVal = ufmt_digitvalue(c);
00038   
00039   return (UBool)(digitVal < radix && digitVal >= 0);
00040 }
00041 
00042 #define TO_UC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 7)
00043 #define TO_LC_DIGIT(a) a <= 9 ? (0x0030 + a) : (0x0030 + a + 39)
00044 
00045 void 
00046 ufmt_ltou(UChar     *buffer, 
00047       int32_t     *len,
00048       long         value, 
00049       int32_t     radix,
00050       UBool    uselower,
00051       int32_t    minDigits)
00052 {
00053   int32_t     length     = 0;
00054   long         q;
00055   int8_t     digit;
00056   UChar    *left, *right, temp;
00057   
00058   while(value > radix && length < *len) {
00059     q = value / radix;
00060     digit = (int8_t)(value - q * radix);
00061     buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(digit) 
00062                  : TO_UC_DIGIT(digit));
00063     value = q;
00064   }
00065 
00066   if(length < *len) {
00067     buffer[length++] = (UChar)(uselower ? TO_LC_DIGIT(value) 
00068                  : TO_UC_DIGIT(value));
00069   }
00070 
00071   /* pad with zeroes to make it minDigits long */
00072   if(minDigits != -1 && length < minDigits) {
00073     while(length < minDigits && length < *len)
00074       buffer[length++] = 0x0030;
00075   }
00076 
00077   /* reverse the buffer */
00078   left     = buffer;
00079   right = buffer + length;
00080   while(left < --right) {
00081     temp     = *left;
00082     *left++     = *right;
00083     *right     = temp;
00084   }
00085 
00086   *len = length;
00087 }
00088 
00089 long
00090 ufmt_utol(const UChar     *buffer, 
00091       int32_t     *len,
00092       int32_t     radix)
00093 {
00094   const UChar     *limit;
00095   int32_t         count;
00096   long        result;
00097 
00098 
00099   /* intialize parameters */
00100   limit     = buffer + *len;
00101   count     = 0;
00102   result     = 0;
00103 
00104   /* iterate through buffer */
00105   while(ufmt_isdigit(*buffer, radix) && buffer < limit) {
00106     
00107     /* read the next digit */
00108     result *= radix;
00109     result += ufmt_digitvalue(*buffer++);
00110     
00111     /* increment our count */
00112     ++count;
00113   }
00114 
00115   *len = count;
00116   return result;
00117 }
00118 
00119 UBool
00120 ufmt_isws(UChar c)
00121 {
00122   return (UBool)(c == 0x0020 || /* space */
00123       c == 0x0009 || /* tab */
00124       c == 0x000D || /* CR */
00125       c == 0x000A || /* LF */
00126       c == 0x000B || /* vertical tab */
00127       c == 0x000C || /* form feed */
00128       u_isspace(c));
00129 }
00130 
00131 UConverter *gDef = NULL;
00132 
00133 UChar*
00134 ufmt_defaultCPToUnicode(const char *s,
00135             int32_t len)
00136 {
00137   int32_t size;
00138   UChar *target, *alias;
00139   UConverter *defConverter = NULL;
00140   UErrorCode status = U_ZERO_ERROR;
00141 
00142   umtx_lock(NULL);
00143     if(gDef != NULL)
00144       {
00145         defConverter = gDef;
00146         gDef = NULL;
00147       }
00148   umtx_unlock(NULL);
00149 
00150   if(defConverter == NULL)
00151     defConverter = ucnv_open(ucnv_getDefaultName(), &status);
00152 
00153   if(U_FAILURE(status) || defConverter == 0)
00154     return 0;
00155 
00156   /* perform the conversion in one swoop */
00157   size = (len + 1) / ucnv_getMinCharSize(defConverter);
00158   target = (UChar*) malloc(size * sizeof(UChar));
00159   if(target != 0) {
00160 
00161     alias = target;
00162     ucnv_toUnicode(defConverter, &alias, alias + size, &s, s + len, 
00163                    NULL, TRUE, &status);
00164     
00165 
00166     /* add the null terminator */
00167     *alias = 0x0000;
00168   }
00169 
00170   umtx_lock(NULL);
00171     if(gDef == NULL)
00172     {
00173       gDef = defConverter;
00174       defConverter = NULL;
00175     }
00176   umtx_unlock(NULL);
00177 
00178   if(defConverter != NULL) {
00179     ucnv_close(defConverter);
00180   }
00181 
00182   return target;
00183 }
00184 
00185 char*
00186 ufmt_unicodeToDefaultCP(const UChar *s,
00187             int32_t len)
00188 {
00189   int32_t size;
00190   char *target, *alias;
00191   UConverter *defConverter = NULL;
00192   UErrorCode status = U_ZERO_ERROR;
00193 
00194   umtx_lock(NULL);
00195     if(gDef != NULL)
00196       {
00197         defConverter = gDef;
00198         gDef = NULL;
00199       }
00200   umtx_unlock(NULL);
00201 
00202   if(defConverter == NULL)
00203     defConverter = ucnv_open(ucnv_getDefaultName(), &status);
00204 
00205   if(U_FAILURE(status) || defConverter == 0)
00206     return 0;
00207 
00208   /* perform the conversion in one swoop */
00209   target = (char*) 
00210     malloc((len + 1) * ucnv_getMaxCharSize(defConverter) * sizeof(char));
00211   size = (len) * ucnv_getMaxCharSize(defConverter) * sizeof(char);
00212   if(target != 0) {
00213 
00214     alias = target;
00215     ucnv_fromUnicode(defConverter, &alias, alias + size, &s, s + len, 
00216                      NULL, TRUE, &status);
00217     
00218     
00219     /* add the null terminator */
00220     *alias = 0x00;
00221   }
00222 
00223   umtx_lock(NULL);
00224     if(gDef == NULL)
00225     {
00226       gDef = defConverter;
00227       defConverter = NULL;
00228     }
00229   umtx_unlock(NULL);
00230 
00231   if(defConverter != NULL) {
00232     ucnv_close(defConverter);
00233   }
00234 
00235   return target;
00236 }
00237 
00238 
00239 
00240 

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