/* ******************************************************************************* * Copyright (C) 2006-2008, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.charset; /** * Defines the UConverterSharedData struct, the immutable, shared part of * UConverter. */ final class UConverterSharedData { // uint32_t structSize; /* Size of this structure */ // int structSize; /* Size of this structure */ /** * used to count number of clients, 0xffffffff for static SharedData */ int referenceCounter; // agljport:todo const void *dataMemory; /* from udata_openChoice() - for cleanup */ // agljport:todo void *table; /* Unused. This used to be a UConverterTable - Pointer to conversion data - see mbcs below */ // const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */ /** * pointer to the static (non changing) * data. */ UConverterStaticData staticData; // UBool sharedDataCached; /* TRUE: shared data is in cache, don't destroy // on close() if 0 ref. FALSE: shared data isn't in the cache, do attempt to // clean it up if the ref is 0 */ /** * TRUE: shared data is in cache, don't destroy * on close() if 0 ref. FALSE: shared data isn't * in the cache, do attempt to clean it up if * the ref is 0 */ boolean sharedDataCached; /* * UBool staticDataOwned; TRUE if static data owned by shared data & should * be freed with it, NEVER true for udata() loaded statics. This ignored * variable was removed to make space for sharedDataCached. */ // const UConverterImpl *impl; /* vtable-style struct of mostly function pointers */ // UConverterImpl impl; /* vtable-style struct of mostly function pointers */ /** initial values of some members of the mutable part of object */ long toUnicodeStatus; /** * Shared data structures currently come in two flavors: * - readonly for built-in algorithmic converters * - allocated for MBCS, with a pointer to an allocated UConverterTable * which always has a UConverterMBCSTable * * To eliminate one allocation, I am making the UConverterMBCSTable a member * of the shared data. It is the last member so that static definitions of * UConverterSharedData work as before. The table field above also remains * to avoid updating all static definitions, but is now unused. * */ CharsetMBCS.UConverterMBCSTable mbcs; UConverterSharedData() { mbcs = new CharsetMBCS.UConverterMBCSTable(); } UConverterSharedData(int referenceCounter_, UConverterStaticData staticData_, boolean sharedDataCached_, long toUnicodeStatus_) { this(); referenceCounter = referenceCounter_; staticData = staticData_; sharedDataCached = sharedDataCached_; // impl = impl_; toUnicodeStatus = toUnicodeStatus_; } /** * UConverterImpl contains all the data and functions for a converter type. * Its function pointers work much like a C++ vtable. Many converter types * need to define only a subset of the functions; when a function pointer is * NULL, then a default action will be performed. * * Every converter type must implement toUnicode, fromUnicode, and * getNextUChar, otherwise the converter may crash. Every converter type * that has variable-length codepage sequences should also implement * toUnicodeWithOffsets and fromUnicodeWithOffsets for correct offset * handling. All other functions may or may not be implemented - it depends * only on whether the converter type needs them. * * When open() fails, then close() will be called, if present. */ /* class UConverterImpl { UConverterType type; UConverterToUnicode toUnicode; protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode) { } final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode) { doToUnicode(args, pErrorCode); } //UConverterFromUnicode fromUnicode; protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode) { } final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode) { doFromUnicode(args, pErrorCode); } protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode) { return 0; } //UConverterGetNextUChar getNextUChar; final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode) { return doGetNextUChar(args, pErrorCode); } // interface UConverterImplLoadable extends UConverterImpl protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode) { } protected void doUnload() { } // interface UConverterImplOpenable extends UConverterImpl protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode) { } //UConverterOpen open; final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode) { doOpen(cnv, name, locale, options, pErrorCode); } protected void doClose(UConverter cnv) { } //UConverterClose close; final void close(UConverter cnv) { doClose(cnv); } protected void doReset(UConverter cnv, int choice) { } //typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice); //UConverterReset reset; final void reset(UConverter cnv, int choice) { doReset(cnv, choice); } // interface UConverterImplVariableLength extends UConverterImpl protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode) { } //UConverterToUnicode toUnicodeWithOffsets; final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode) { doToUnicodeWithOffsets(args, pErrorCode); } protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode) { } //UConverterFromUnicode fromUnicodeWithOffsets; final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode) { doFromUnicodeWithOffsets(args, pErrorCode); } // interface UConverterImplMisc extends UConverterImpl protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode) { } //UConverterGetStarters getStarters; final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode) { doGetStarters(converter, starters, pErrorCode); } protected String doGetName(UConverter cnv) { return ""; } //UConverterGetName getName; final String getName(UConverter cnv) { return doGetName(cnv); } protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode) { } //UConverterWriteSub writeSub; final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode) { doWriteSub(pArgs, offsetIndex, pErrorCode); } protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status) { return new UConverter(); } //UConverterSafeClone safeClone; final UConverter safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status) { return doSafeClone(cnv, stackBuffer, pBufferSize, status); } protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode) { } //UConverterGetUnicodeSet getUnicodeSet; // final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode) //{ // doGetUnicodeSet(cnv, sa, which, pErrorCode); //} //} static final String DATA_TYPE = "cnv"; private static final int CNV_DATA_BUFFER_SIZE = 25000; static final int sizeofUConverterSharedData = 100; //static UDataMemoryIsAcceptable isCnvAcceptable; /** * Load a non-algorithmic converter. * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex). // UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err) static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err) { UConverterSharedData mySharedConverterData = null; if(err == null || ErrorCode.isFailure(err[0])) { return null; } if(pArgs.pkg != null && pArgs.pkg.length() != 0) { application-provided converters are not currently cached return UConverterSharedData.createConverterFromFile(pArgs, err); } //agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name); if (mySharedConverterData == null) { Not cached, we need to stream it in from file mySharedConverterData = UConverterSharedData.createConverterFromFile(pArgs, err); if (ErrorCode.isFailure(err[0]) || (mySharedConverterData == null)) { return null; } else { share it with other library clients //agljport:fix shareConverterData(mySharedConverterData); } } else { The data for this converter was already in the cache. Update the reference counter on the shared data: one more client mySharedConverterData.referenceCounter++; } return mySharedConverterData; } Takes an alias name gets an actual converter file name *goes to disk and opens it. *allocates the memory and returns a new UConverter object //static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err) static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err) { UDataMemory data = null; UConverterSharedData sharedData = null; //agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD); if (err == null || ErrorCode.isFailure(err[0])) { //agljport:todo UTRACE_EXIT_STATUS(*err); return null; } //agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg); //agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err); if(ErrorCode.isFailure(err[0])) { //agljport:todo UTRACE_EXIT_STATUS(*err); return null; } sharedData = data_unFlattenClone(pArgs, data, err); if(ErrorCode.isFailure(err[0])) { //agljport:fix udata_close(data); //agljport:todo UTRACE_EXIT_STATUS(*err); return null; } * TODO Store pkg in a field in the shared data so that delta-only converters * can load base converters from the same package. * If the pkg name is longer than the field, then either do not load the converter * in the first place, or just set the pkg field to "". return sharedData; } */ UConverterDataReader dataReader = null; /* * returns a converter type from a string */ /* static final UConverterSharedData getAlgorithmicTypeFromName(String realName) { long mid, start, limit; long lastMid; int result; StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH); // Lower case and remove ignoreable characters. UConverterAlias.stripForCompare(strippedName, realName); // do a binary search for the alias start = 0; limit = cnvNameType.length; mid = limit; lastMid = -1; for (;;) { mid = (long)((start + limit) / 2); if (lastMid == mid) { // Have we moved? break; // We haven't moved, and it wasn't found. } lastMid = mid; result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name); if (result < 0) { limit = mid; } else if (result > 0) { start = mid; } else { return converterData[cnvNameType[(int)mid].type]; } } return null; }*/ /* * Enum for specifying basic types of converters */ static final class UConverterType { static final int UNSUPPORTED_CONVERTER = -1; static final int SBCS = 0; static final int DBCS = 1; static final int MBCS = 2; static final int LATIN_1 = 3; static final int UTF8 = 4; static final int UTF16_BigEndian = 5; static final int UTF16_LittleEndian = 6; static final int UTF32_BigEndian = 7; static final int UTF32_LittleEndian = 8; static final int EBCDIC_STATEFUL = 9; static final int ISO_2022 = 10; static final int LMBCS_1 = 11; static final int LMBCS_2 = LMBCS_1 + 1; // 12 static final int LMBCS_3 = LMBCS_2 + 1; // 13 static final int LMBCS_4 = LMBCS_3 + 1; // 14 static final int LMBCS_5 = LMBCS_4 + 1; // 15 static final int LMBCS_6 = LMBCS_5 + 1; // 16 static final int LMBCS_8 = LMBCS_6 + 1; // 17 static final int LMBCS_11 = LMBCS_8 + 1; // 18 static final int LMBCS_16 = LMBCS_11 + 1; // 19 static final int LMBCS_17 = LMBCS_16 + 1; // 20 static final int LMBCS_18 = LMBCS_17 + 1; // 21 static final int LMBCS_19 = LMBCS_18 + 1; // 22 static final int LMBCS_LAST = LMBCS_19; // 22 static final int HZ = LMBCS_LAST + 1; // 23 static final int SCSU = HZ + 1; // 24 static final int ISCII = SCSU + 1; // 25 static final int US_ASCII = ISCII + 1; // 26 static final int UTF7 = US_ASCII + 1; // 27 static final int BOCU1 = UTF7 + 1; // 28 static final int UTF16 = BOCU1 + 1; // 29 static final int UTF32 = UTF16 + 1; // 30 static final int CESU8 = UTF32 + 1; // 31 static final int IMAP_MAILBOX = CESU8 + 1; // 32 // Number of converter types for which we have conversion routines. static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = IMAP_MAILBOX + 1; } /** * Enum for specifying which platform a converter ID refers to. The use of * platform/CCSID is not recommended. See openCCSID(). */ static final class UConverterPlatform { static final int UNKNOWN = -1; static final int IBM = 0; } // static UConverterSharedData[] converterData; /* static class cnvNameTypeClass { String name; int type; cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; } } static cnvNameTypeClass cnvNameType[];*/ static final String DATA_TYPE = "cnv"; //static final int CNV_DATA_BUFFER_SIZE = 25000; //static final int SIZE_OF_UCONVERTER_SHARED_DATA = 228; }