Home | History | Annotate | Download | only in charset
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2006-2008, International Business Machines Corporation and    *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  */
      7 package com.ibm.icu.charset;
      8 
      9 /**
     10  * Defines the UConverterSharedData struct, the immutable, shared part of
     11  * UConverter.
     12  */
     13 final class UConverterSharedData {
     14     // uint32_t structSize; /* Size of this structure */
     15     // int structSize; /* Size of this structure */
     16     /**
     17      * used to count number of clients, 0xffffffff for static SharedData
     18      */
     19     int referenceCounter;
     20 
     21     // agljport:todo const void *dataMemory; /* from udata_openChoice() - for cleanup */
     22     // agljport:todo void *table; /* Unused. This used to be a UConverterTable - Pointer to conversion data - see mbcs below */
     23 
     24     // const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
     25     /**
     26      * pointer to the static (non changing)
     27      * data.
     28      */
     29     UConverterStaticData staticData;
     30 
     31     // UBool sharedDataCached; /* TRUE: shared data is in cache, don't destroy
     32     // on close() if 0 ref. FALSE: shared data isn't in the cache, do attempt to
     33     // clean it up if the ref is 0 */
     34 
     35     /**
     36      * TRUE: shared data is in cache, don't destroy
     37      * on close() if 0 ref. FALSE: shared data isn't
     38      * in the cache, do attempt to clean it up if
     39      * the ref is 0
     40      */
     41     boolean sharedDataCached;
     42 
     43     /*
     44      * UBool staticDataOwned; TRUE if static data owned by shared data & should
     45      * be freed with it, NEVER true for udata() loaded statics. This ignored
     46      * variable was removed to make space for sharedDataCached.
     47      */
     48 
     49     // const UConverterImpl *impl; /* vtable-style struct of mostly function pointers */
     50     // UConverterImpl impl; /* vtable-style struct of mostly function pointers */
     51     /** initial values of some members of the mutable part of object */
     52     long toUnicodeStatus;
     53 
     54     /**
     55      * Shared data structures currently come in two flavors:
     56      * - readonly for built-in algorithmic converters
     57      * - allocated for MBCS, with a pointer to an allocated UConverterTable
     58      *   which always has a UConverterMBCSTable
     59      *
     60      * To eliminate one allocation, I am making the UConverterMBCSTable a member
     61      * of the shared data. It is the last member so that static definitions of
     62      * UConverterSharedData work as before. The table field above also remains
     63      * to avoid updating all static definitions, but is now unused.
     64      *
     65      */
     66     CharsetMBCS.UConverterMBCSTable mbcs;
     67 
     68     UConverterSharedData() {
     69         mbcs = new CharsetMBCS.UConverterMBCSTable();
     70     }
     71 
     72     UConverterSharedData(int referenceCounter_, UConverterStaticData staticData_, boolean sharedDataCached_, long toUnicodeStatus_)
     73     {
     74         this();
     75         referenceCounter = referenceCounter_;
     76         staticData = staticData_;
     77         sharedDataCached = sharedDataCached_;
     78         // impl = impl_;
     79         toUnicodeStatus = toUnicodeStatus_;
     80     }
     81 
     82     /**
     83      * UConverterImpl contains all the data and functions for a converter type.
     84      * Its function pointers work much like a C++ vtable. Many converter types
     85      * need to define only a subset of the functions; when a function pointer is
     86      * NULL, then a default action will be performed.
     87      *
     88      * Every converter type must implement toUnicode, fromUnicode, and
     89      * getNextUChar, otherwise the converter may crash. Every converter type
     90      * that has variable-length codepage sequences should also implement
     91      * toUnicodeWithOffsets and fromUnicodeWithOffsets for correct offset
     92      * handling. All other functions may or may not be implemented - it depends
     93      * only on whether the converter type needs them.
     94      *
     95      * When open() fails, then close() will be called, if present.
     96      */
     97 /* class UConverterImpl {
     98     UConverterType type;
     99     UConverterToUnicode toUnicode;
    100     protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
    101     {
    102     }
    103 
    104      final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
    105     {
    106         doToUnicode(args, pErrorCode);
    107     }
    108 
    109     //UConverterFromUnicode fromUnicode;
    110     protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
    111     {
    112     }
    113 
    114      final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
    115     {
    116         doFromUnicode(args, pErrorCode);
    117     }
    118 
    119     protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
    120     {
    121         return 0;
    122     }
    123 
    124     //UConverterGetNextUChar getNextUChar;
    125      final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
    126     {
    127         return doGetNextUChar(args, pErrorCode);
    128     }
    129 
    130     // interface UConverterImplLoadable extends UConverterImpl
    131     protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode)
    132     {
    133     }
    134 
    135     protected void doUnload()
    136     {
    137     }
    138 
    139     // interface UConverterImplOpenable extends UConverterImpl
    140     protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
    141     {
    142     }
    143 
    144     //UConverterOpen open;
    145      final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
    146     {
    147         doOpen(cnv, name, locale, options, pErrorCode);
    148     }
    149 
    150     protected void doClose(UConverter cnv)
    151     {
    152     }
    153 
    154     //UConverterClose close;
    155      final void close(UConverter cnv)
    156     {
    157         doClose(cnv);
    158     }
    159 
    160     protected void doReset(UConverter cnv, int choice)
    161     {
    162     }
    163 
    164     //typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice);
    165     //UConverterReset reset;
    166      final void reset(UConverter cnv, int choice)
    167     {
    168         doReset(cnv, choice);
    169     }
    170 
    171     // interface UConverterImplVariableLength extends UConverterImpl
    172     protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
    173     {
    174     }
    175 
    176     //UConverterToUnicode toUnicodeWithOffsets;
    177      final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
    178     {
    179         doToUnicodeWithOffsets(args, pErrorCode);
    180     }
    181 
    182     protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
    183     {
    184     }
    185 
    186     //UConverterFromUnicode fromUnicodeWithOffsets;
    187      final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
    188     {
    189         doFromUnicodeWithOffsets(args, pErrorCode);
    190     }
    191 
    192     // interface UConverterImplMisc extends UConverterImpl
    193     protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode)
    194     {
    195     }
    196 
    197     //UConverterGetStarters getStarters;
    198      final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode)
    199     {
    200         doGetStarters(converter, starters, pErrorCode);
    201     }
    202 
    203     protected String doGetName(UConverter cnv)
    204     {
    205         return "";
    206     }
    207 
    208     //UConverterGetName getName;
    209      final String getName(UConverter cnv)
    210     {
    211         return doGetName(cnv);
    212     }
    213 
    214     protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
    215     {
    216     }
    217 
    218     //UConverterWriteSub writeSub;
    219      final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
    220     {
    221         doWriteSub(pArgs, offsetIndex, pErrorCode);
    222     }
    223 
    224     protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
    225     {
    226         return new UConverter();
    227     }
    228 
    229     //UConverterSafeClone safeClone;
    230      final UConverter  safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
    231     {
    232         return doSafeClone(cnv, stackBuffer, pBufferSize, status);
    233     }
    234 
    235     protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
    236     {
    237     }
    238 
    239     //UConverterGetUnicodeSet getUnicodeSet;
    240     // final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
    241     //{
    242     //  doGetUnicodeSet(cnv, sa, which, pErrorCode);
    243     //}
    244 
    245     //}
    246 
    247     static final String DATA_TYPE = "cnv";
    248     private static final int CNV_DATA_BUFFER_SIZE = 25000;
    249      static final int sizeofUConverterSharedData = 100;
    250 
    251     //static UDataMemoryIsAcceptable isCnvAcceptable;
    252 
    253     /**
    254      * Load a non-algorithmic converter.
    255      * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
    256 
    257     // UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err)
    258      static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err)
    259     {
    260         UConverterSharedData mySharedConverterData = null;
    261 
    262         if(err == null || ErrorCode.isFailure(err[0])) {
    263             return null;
    264         }
    265 
    266         if(pArgs.pkg != null && pArgs.pkg.length() != 0) {
    267              application-provided converters are not currently cached
    268             return UConverterSharedData.createConverterFromFile(pArgs, err);
    269         }
    270 
    271         //agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name);
    272         if (mySharedConverterData == null)
    273         {
    274             Not cached, we need to stream it in from file
    275             mySharedConverterData = UConverterSharedData.createConverterFromFile(pArgs, err);
    276             if (ErrorCode.isFailure(err[0]) || (mySharedConverterData == null))
    277             {
    278                 return null;
    279             }
    280             else
    281             {
    282                  share it with other library clients
    283                 //agljport:fix shareConverterData(mySharedConverterData);
    284             }
    285         }
    286         else
    287         {
    288              The data for this converter was already in the cache.
    289              Update the reference counter on the shared data: one more client
    290             mySharedConverterData.referenceCounter++;
    291         }
    292 
    293         return mySharedConverterData;
    294     }
    295 
    296     Takes an alias name gets an actual converter file name
    297      *goes to disk and opens it.
    298      *allocates the memory and returns a new UConverter object
    299 
    300     //static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err)
    301      static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err)
    302     {
    303         UDataMemory data = null;
    304         UConverterSharedData sharedData = null;
    305 
    306         //agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD);
    307 
    308         if (err == null || ErrorCode.isFailure(err[0])) {
    309             //agljport:todo UTRACE_EXIT_STATUS(*err);
    310             return null;
    311         }
    312 
    313         //agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg);
    314 
    315         //agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err);
    316         if(ErrorCode.isFailure(err[0]))
    317         {
    318             //agljport:todo UTRACE_EXIT_STATUS(*err);
    319             return null;
    320         }
    321 
    322         sharedData = data_unFlattenClone(pArgs, data, err);
    323         if(ErrorCode.isFailure(err[0]))
    324         {
    325             //agljport:fix udata_close(data);
    326             //agljport:todo UTRACE_EXIT_STATUS(*err);
    327             return null;
    328         }
    329 
    330 
    331          * TODO Store pkg in a field in the shared data so that delta-only converters
    332          * can load base converters from the same package.
    333          * If the pkg name is longer than the field, then either do not load the converter
    334          * in the first place, or just set the pkg field to "".
    335 
    336 
    337         return sharedData;
    338     }
    339 */
    340     UConverterDataReader dataReader = null;
    341 
    342     /*
    343      * returns a converter type from a string
    344      */
    345     /*   static final UConverterSharedData getAlgorithmicTypeFromName(String realName)
    346     {
    347         long mid, start, limit;
    348         long lastMid;
    349         int result;
    350         StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH);
    351 
    352         // Lower case and remove ignoreable characters.
    353         UConverterAlias.stripForCompare(strippedName, realName);
    354 
    355         // do a binary search for the alias
    356         start = 0;
    357         limit = cnvNameType.length;
    358         mid = limit;
    359         lastMid = -1;
    360 
    361         for (;;) {
    362             mid = (long)((start + limit) / 2);
    363             if (lastMid == mid) {   // Have we moved?
    364                 break;  // We haven't moved, and it wasn't found.
    365             }
    366             lastMid = mid;
    367             result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name);
    368 
    369             if (result < 0) {
    370                 limit = mid;
    371             } else if (result > 0) {
    372                 start = mid;
    373             } else {
    374                 return converterData[cnvNameType[(int)mid].type];
    375             }
    376         }
    377 
    378         return null;
    379     }*/
    380 
    381     /*
    382      * Enum for specifying basic types of converters
    383      */
    384     static final class UConverterType {
    385         static final int UNSUPPORTED_CONVERTER = -1;
    386         static final int SBCS = 0;
    387         static final int DBCS = 1;
    388         static final int MBCS = 2;
    389         static final int LATIN_1 = 3;
    390         static final int UTF8 = 4;
    391         static final int UTF16_BigEndian = 5;
    392         static final int UTF16_LittleEndian = 6;
    393         static final int UTF32_BigEndian = 7;
    394         static final int UTF32_LittleEndian = 8;
    395         static final int EBCDIC_STATEFUL = 9;
    396         static final int ISO_2022 = 10;
    397         static final int LMBCS_1 = 11;
    398         static final int LMBCS_2 = LMBCS_1 + 1; // 12
    399         static final int LMBCS_3 = LMBCS_2 + 1; // 13
    400         static final int LMBCS_4 = LMBCS_3 + 1; // 14
    401         static final int LMBCS_5 = LMBCS_4 + 1; // 15
    402         static final int LMBCS_6 = LMBCS_5 + 1; // 16
    403         static final int LMBCS_8 = LMBCS_6 + 1; // 17
    404         static final int LMBCS_11 = LMBCS_8 + 1; // 18
    405         static final int LMBCS_16 = LMBCS_11 + 1; // 19
    406         static final int LMBCS_17 = LMBCS_16 + 1; // 20
    407         static final int LMBCS_18 = LMBCS_17 + 1; // 21
    408         static final int LMBCS_19 = LMBCS_18 + 1; // 22
    409         static final int LMBCS_LAST = LMBCS_19; // 22
    410         static final int HZ = LMBCS_LAST + 1; // 23
    411         static final int SCSU = HZ + 1; // 24
    412         static final int ISCII = SCSU + 1; // 25
    413         static final int US_ASCII = ISCII + 1; // 26
    414         static final int UTF7 = US_ASCII + 1; // 27
    415         static final int BOCU1 = UTF7 + 1; // 28
    416         static final int UTF16 = BOCU1 + 1; // 29
    417         static final int UTF32 = UTF16 + 1; // 30
    418         static final int CESU8 = UTF32 + 1; // 31
    419         static final int IMAP_MAILBOX = CESU8 + 1; // 32
    420 
    421         // Number of converter types for which we have conversion routines.
    422         static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = IMAP_MAILBOX + 1;
    423     }
    424 
    425     /**
    426      * Enum for specifying which platform a converter ID refers to. The use of
    427      * platform/CCSID is not recommended. See openCCSID().
    428      */
    429     static final class UConverterPlatform {
    430         static final int UNKNOWN = -1;
    431         static final int IBM = 0;
    432     }
    433 
    434     // static UConverterSharedData[] converterData;
    435     /*  static class cnvNameTypeClass {
    436       String name;
    437         int type;
    438         cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; }
    439     }
    440 
    441     static cnvNameTypeClass cnvNameType[];*/
    442 
    443 
    444     static final String DATA_TYPE = "cnv";
    445     //static final int CNV_DATA_BUFFER_SIZE = 25000;
    446     //static final int SIZE_OF_UCONVERTER_SHARED_DATA = 228;
    447 
    448 }
    449