2 *******************************************************************************
3 * Copyright (C) 2006-2008, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.charset;
10 * Defines the UConverterSharedData struct, the immutable, shared part of
13 final class UConverterSharedData {
14 // uint32_t structSize; /* Size of this structure */
15 // int structSize; /* Size of this structure */
17 * used to count number of clients, 0xffffffff for static SharedData
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 */
24 // const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
26 * pointer to the static (non changing)
29 UConverterStaticData staticData;
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 */
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
41 boolean sharedDataCached;
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.
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 */
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
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.
66 CharsetMBCS.UConverterMBCSTable mbcs;
68 UConverterSharedData() {
69 mbcs = new CharsetMBCS.UConverterMBCSTable();
72 UConverterSharedData(int referenceCounter_, UConverterStaticData staticData_, boolean sharedDataCached_, long toUnicodeStatus_)
75 referenceCounter = referenceCounter_;
76 staticData = staticData_;
77 sharedDataCached = sharedDataCached_;
79 toUnicodeStatus = toUnicodeStatus_;
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.
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.
95 * When open() fails, then close() will be called, if present.
97 /* class UConverterImpl {
99 UConverterToUnicode toUnicode;
100 protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
104 final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
106 doToUnicode(args, pErrorCode);
109 //UConverterFromUnicode fromUnicode;
110 protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
114 final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
116 doFromUnicode(args, pErrorCode);
119 protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
124 //UConverterGetNextUChar getNextUChar;
125 final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
127 return doGetNextUChar(args, pErrorCode);
130 // interface UConverterImplLoadable extends UConverterImpl
131 protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode)
135 protected void doUnload()
139 // interface UConverterImplOpenable extends UConverterImpl
140 protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
144 //UConverterOpen open;
145 final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
147 doOpen(cnv, name, locale, options, pErrorCode);
150 protected void doClose(UConverter cnv)
154 //UConverterClose close;
155 final void close(UConverter cnv)
160 protected void doReset(UConverter cnv, int choice)
164 //typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice);
165 //UConverterReset reset;
166 final void reset(UConverter cnv, int choice)
168 doReset(cnv, choice);
171 // interface UConverterImplVariableLength extends UConverterImpl
172 protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
176 //UConverterToUnicode toUnicodeWithOffsets;
177 final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
179 doToUnicodeWithOffsets(args, pErrorCode);
182 protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
186 //UConverterFromUnicode fromUnicodeWithOffsets;
187 final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
189 doFromUnicodeWithOffsets(args, pErrorCode);
192 // interface UConverterImplMisc extends UConverterImpl
193 protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode)
197 //UConverterGetStarters getStarters;
198 final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode)
200 doGetStarters(converter, starters, pErrorCode);
203 protected String doGetName(UConverter cnv)
208 //UConverterGetName getName;
209 final String getName(UConverter cnv)
211 return doGetName(cnv);
214 protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
218 //UConverterWriteSub writeSub;
219 final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
221 doWriteSub(pArgs, offsetIndex, pErrorCode);
224 protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
226 return new UConverter();
229 //UConverterSafeClone safeClone;
230 final UConverter safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
232 return doSafeClone(cnv, stackBuffer, pBufferSize, status);
235 protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
239 //UConverterGetUnicodeSet getUnicodeSet;
240 // final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
242 // doGetUnicodeSet(cnv, sa, which, pErrorCode);
247 static final String DATA_TYPE = "cnv";
248 private static final int CNV_DATA_BUFFER_SIZE = 25000;
249 static final int sizeofUConverterSharedData = 100;
251 //static UDataMemoryIsAcceptable isCnvAcceptable;
254 * Load a non-algorithmic converter.
255 * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
257 // UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err)
258 static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err)
260 UConverterSharedData mySharedConverterData = null;
262 if(err == null || ErrorCode.isFailure(err[0])) {
266 if(pArgs.pkg != null && pArgs.pkg.length() != 0) {
267 application-provided converters are not currently cached
268 return UConverterSharedData.createConverterFromFile(pArgs, err);
271 //agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name);
272 if (mySharedConverterData == null)
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))
282 share it with other library clients
283 //agljport:fix shareConverterData(mySharedConverterData);
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++;
293 return mySharedConverterData;
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
300 //static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err)
301 static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err)
303 UDataMemory data = null;
304 UConverterSharedData sharedData = null;
306 //agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD);
308 if (err == null || ErrorCode.isFailure(err[0])) {
309 //agljport:todo UTRACE_EXIT_STATUS(*err);
313 //agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg);
315 //agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err);
316 if(ErrorCode.isFailure(err[0]))
318 //agljport:todo UTRACE_EXIT_STATUS(*err);
322 sharedData = data_unFlattenClone(pArgs, data, err);
323 if(ErrorCode.isFailure(err[0]))
325 //agljport:fix udata_close(data);
326 //agljport:todo UTRACE_EXIT_STATUS(*err);
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 "".
340 UConverterDataReader dataReader = null;
343 * returns a converter type from a string
345 /* static final UConverterSharedData getAlgorithmicTypeFromName(String realName)
347 long mid, start, limit;
350 StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH);
352 // Lower case and remove ignoreable characters.
353 UConverterAlias.stripForCompare(strippedName, realName);
355 // do a binary search for the alias
357 limit = cnvNameType.length;
362 mid = (long)((start + limit) / 2);
363 if (lastMid == mid) { // Have we moved?
364 break; // We haven't moved, and it wasn't found.
367 result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name);
371 } else if (result > 0) {
374 return converterData[cnvNameType[(int)mid].type];
382 * Enum for specifying basic types of converters
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
421 // Number of converter types for which we have conversion routines.
422 static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = IMAP_MAILBOX + 1;
426 * Enum for specifying which platform a converter ID refers to. The use of
427 * platform/CCSID is not recommended. See openCCSID().
429 static final class UConverterPlatform {
430 static final int UNKNOWN = -1;
431 static final int IBM = 0;
434 // static UConverterSharedData[] converterData;
435 /* static class cnvNameTypeClass {
438 cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; }
441 static cnvNameTypeClass cnvNameType[];*/
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;