001: /**
002: *******************************************************************************
003: * Copyright (C) 2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: *
007: *******************************************************************************
008: */package com.ibm.icu.charset;
009:
010: /*
011: * Defines the UConverterSharedData struct,
012: * the immutable, shared part of UConverter.
013: */
014: final class UConverterSharedData {
015: //uint32_t structSize; /* Size of this structure */
016: int structSize; /* Size of this structure */
017: //uint32_t referenceCounter; /* used to count number of clients, 0xffffffff for static SharedData */
018: int referenceCounter; /* used to count number of clients, 0xffffffff for static SharedData */
019:
020: //agljport:todo const void *dataMemory; /* from udata_openChoice() - for cleanup */
021: //agljport:todo void *table; /* Unused. This used to be a UConverterTable - Pointer to conversion data - see mbcs below */
022:
023: //const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
024: UConverterStaticData staticData; /* pointer to the static (non changing) data. */
025:
026: //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 */
027: boolean 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 */
028: /*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. */
029:
030: //const UConverterImpl *impl; /* vtable-style struct of mostly function pointers */
031: // UConverterImpl impl; /* vtable-style struct of mostly function pointers */
032: /*initial values of some members of the mutable part of object */
033: //uint32_t toUnicodeStatus;
034: long toUnicodeStatus;
035:
036: /*
037: * Shared data structures currently come in two flavors:
038: * - readonly for built-in algorithmic converters
039: * - allocated for MBCS, with a pointer to an allocated UConverterTable
040: * which always has a UConverterMBCSTable
041: *
042: * To eliminate one allocation, I am making the UConverterMBCSTable
043: * a member of the shared data. It is the last member so that static
044: * definitions of UConverterSharedData work as before.
045: * The table field above also remains to avoid updating all static
046: * definitions, but is now unused.
047: *
048: */
049: CharsetMBCS.UConverterMBCSTable mbcs;
050:
051: UConverterSharedData() {
052: mbcs = new CharsetMBCS.UConverterMBCSTable();
053: }
054:
055: UConverterSharedData(int structSize_, int referenceCounter_,
056: UConverterStaticData staticData_,
057: boolean sharedDataCached_,/* UConverterImpl impl_,*/
058: long toUnicodeStatus_) {
059: this ();
060: structSize = structSize_;
061: referenceCounter = referenceCounter_;
062: staticData = staticData_;
063: sharedDataCached = sharedDataCached_;
064: //impl = impl_;
065: toUnicodeStatus = toUnicodeStatus_;
066: }
067:
068: /**
069: * UConverterImpl contains all the data and functions for a converter type.
070: * Its function pointers work much like a C++ vtable.
071: * Many converter types need to define only a subset of the functions;
072: * when a function pointer is NULL, then a default action will be performed.
073: *
074: * Every converter type must implement toUnicode, fromUnicode, and getNextUChar,
075: * otherwise the converter may crash.
076: * Every converter type that has variable-length codepage sequences should
077: * also implement toUnicodeWithOffsets and fromUnicodeWithOffsets for
078: * correct offset handling.
079: * All other functions may or may not be implemented - it depends only on
080: * whether the converter type needs them.
081: *
082: * When open() fails, then close() will be called, if present.
083: */
084: // class UConverterImpl {
085: //UConverterType type;
086: //UConverterToUnicode toUnicode;
087: /* protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
088: {
089: }
090:
091: final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
092: {
093: doToUnicode(args, pErrorCode);
094: }
095:
096: //UConverterFromUnicode fromUnicode;
097: protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
098: {
099: }
100:
101: final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
102: {
103: doFromUnicode(args, pErrorCode);
104: }
105:
106: protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
107: {
108: return 0;
109: }
110:
111: //UConverterGetNextUChar getNextUChar;
112: final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
113: {
114: return doGetNextUChar(args, pErrorCode);
115: }
116:
117: // interface UConverterImplLoadable extends UConverterImpl
118: protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode)
119: {
120: }
121:
122: */
123: protected void doUnload() {
124: }
125:
126: /*
127: // interface UConverterImplOpenable extends UConverterImpl
128: protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
129: {
130: }
131:
132: //UConverterOpen open;
133: final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
134: {
135: doOpen(cnv, name, locale, options, pErrorCode);
136: }
137:
138: protected void doClose(UConverter cnv)
139: {
140: }
141:
142: //UConverterClose close;
143: final void close(UConverter cnv)
144: {
145: doClose(cnv);
146: }
147:
148: protected void doReset(UConverter cnv, int choice)
149: {
150: }
151:
152: //typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice);
153: //UConverterReset reset;
154: final void reset(UConverter cnv, int choice)
155: {
156: doReset(cnv, choice);
157: }
158:
159: // interface UConverterImplVariableLength extends UConverterImpl
160: protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
161: {
162: }
163:
164: //UConverterToUnicode toUnicodeWithOffsets;
165: final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
166: {
167: doToUnicodeWithOffsets(args, pErrorCode);
168: }
169:
170: protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
171: {
172: }
173:
174: //UConverterFromUnicode fromUnicodeWithOffsets;
175: final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
176: {
177: doFromUnicodeWithOffsets(args, pErrorCode);
178: }
179:
180: // interface UConverterImplMisc extends UConverterImpl
181: protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode)
182: {
183: }
184:
185: //UConverterGetStarters getStarters;
186: final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode)
187: {
188: doGetStarters(converter, starters, pErrorCode);
189: }
190:
191: protected String doGetName(UConverter cnv)
192: {
193: return "";
194: }
195:
196: //UConverterGetName getName;
197: final String getName(UConverter cnv)
198: {
199: return doGetName(cnv);
200: }
201:
202: protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
203: {
204: }
205:
206: //UConverterWriteSub writeSub;
207: final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
208: {
209: doWriteSub(pArgs, offsetIndex, pErrorCode);
210: }
211:
212: protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
213: {
214: return new UConverter();
215: }
216:
217: //UConverterSafeClone safeClone;
218: final UConverter safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
219: {
220: return doSafeClone(cnv, stackBuffer, pBufferSize, status);
221: }
222:
223: protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
224: {
225: }
226:
227: //UConverterGetUnicodeSet getUnicodeSet;
228: // final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
229: //{
230: // doGetUnicodeSet(cnv, sa, which, pErrorCode);
231: //}
232:
233: //}
234:
235: static final String DATA_TYPE = "cnv";
236: private static final int CNV_DATA_BUFFER_SIZE = 25000;
237: static final int sizeofUConverterSharedData = 100;
238:
239: //static UDataMemoryIsAcceptable isCnvAcceptable;
240:
241: /**
242: * Load a non-algorithmic converter.
243: * If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
244:
245: // UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err)
246: static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err)
247: {
248: UConverterSharedData mySharedConverterData = null;
249:
250: if(err == null || ErrorCode.isFailure(err[0])) {
251: return null;
252: }
253:
254: if(pArgs.pkg != null && pArgs.pkg.length() != 0) {
255: application-provided converters are not currently cached
256: return UConverterSharedData.createConverterFromFile(pArgs, err);
257: }
258:
259: //agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name);
260: if (mySharedConverterData == null)
261: {
262: Not cached, we need to stream it in from file
263: mySharedConverterData = UConverterSharedData.createConverterFromFile(pArgs, err);
264: if (ErrorCode.isFailure(err[0]) || (mySharedConverterData == null))
265: {
266: return null;
267: }
268: else
269: {
270: share it with other library clients
271: //agljport:fix shareConverterData(mySharedConverterData);
272: }
273: }
274: else
275: {
276: The data for this converter was already in the cache.
277: Update the reference counter on the shared data: one more client
278: mySharedConverterData.referenceCounter++;
279: }
280:
281: return mySharedConverterData;
282: }
283:
284: Takes an alias name gets an actual converter file name
285: *goes to disk and opens it.
286: *allocates the memory and returns a new UConverter object
287:
288: //static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err)
289: static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err)
290: {
291: UDataMemory data = null;
292: UConverterSharedData sharedData = null;
293:
294: //agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD);
295:
296: if (err == null || ErrorCode.isFailure(err[0])) {
297: //agljport:todo UTRACE_EXIT_STATUS(*err);
298: return null;
299: }
300:
301: //agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg);
302:
303: //agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err);
304: if(ErrorCode.isFailure(err[0]))
305: {
306: //agljport:todo UTRACE_EXIT_STATUS(*err);
307: return null;
308: }
309:
310: sharedData = data_unFlattenClone(pArgs, data, err);
311: if(ErrorCode.isFailure(err[0]))
312: {
313: //agljport:fix udata_close(data);
314: //agljport:todo UTRACE_EXIT_STATUS(*err);
315: return null;
316: }
317:
318:
319: * TODO Store pkg in a field in the shared data so that delta-only converters
320: * can load base converters from the same package.
321: * If the pkg name is longer than the field, then either do not load the converter
322: * in the first place, or just set the pkg field to "".
323:
324:
325: return sharedData;
326: }
327: */
328: UConverterDataReader dataReader = null;
329:
330: /*returns a converter type from a string
331: */
332: // static const UConverterSharedData * getAlgorithmicTypeFromName(const char *realName)
333: /* static final UConverterSharedData getAlgorithmicTypeFromName(String realName)
334: {
335: long mid, start, limit;
336: long lastMid;
337: int result;
338: StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH);
339:
340: // Lower case and remove ignoreable characters.
341: UConverterAlias.stripForCompare(strippedName, realName);
342:
343: // do a binary search for the alias
344: start = 0;
345: limit = cnvNameType.length;
346: mid = limit;
347: lastMid = -1;
348:
349: for (;;) {
350: mid = (long)((start + limit) / 2);
351: if (lastMid == mid) { // Have we moved?
352: break; // We haven't moved, and it wasn't found.
353: }
354: lastMid = mid;
355: result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name);
356:
357: if (result < 0) {
358: limit = mid;
359: } else if (result > 0) {
360: start = mid;
361: } else {
362: return converterData[cnvNameType[(int)mid].type];
363: }
364: }
365:
366: return null;
367: }*/
368: /*
369: * Enum for specifying basic types of converters
370: * @see getType
371: * @draft ICU 3.6
372: */
373: static final class UConverterType {
374: static final int UNSUPPORTED_CONVERTER = -1;
375: static final int SBCS = 0;
376: static final int DBCS = 1;
377: static final int MBCS = 2;
378: static final int LATIN_1 = 3;
379: static final int UTF8 = 4;
380: static final int UTF16_BigEndian = 5;
381: static final int UTF16_LittleEndian = 6;
382: static final int UTF32_BigEndian = 7;
383: static final int UTF32_LittleEndian = 8;
384: static final int EBCDIC_STATEFUL = 9;
385: static final int ISO_2022 = 10;
386:
387: static final int LMBCS_1 = 11;
388: static final int LMBCS_2 = LMBCS_1 + 1; //12
389: static final int LMBCS_3 = LMBCS_2 + 1; //13
390: static final int LMBCS_4 = LMBCS_3 + 1; //14
391: static final int LMBCS_5 = LMBCS_4 + 1; //15
392: static final int LMBCS_6 = LMBCS_5 + 1; //16
393: static final int LMBCS_8 = LMBCS_6 + 1; //17
394: static final int LMBCS_11 = LMBCS_8 + 1; //18
395: static final int LMBCS_16 = LMBCS_11 + 1; //19
396: static final int LMBCS_17 = LMBCS_16 + 1; //20
397: static final int LMBCS_18 = LMBCS_17 + 1; //21
398: static final int LMBCS_19 = LMBCS_18 + 1; //22
399: static final int LMBCS_LAST = LMBCS_19; //22
400: static final int HZ = LMBCS_LAST + 1; //23
401: static final int SCSU = HZ + 1; //24
402: static final int ISCII = SCSU + 1; //25
403: static final int US_ASCII = ISCII + 1; //26
404: static final int UTF7 = US_ASCII + 1; //27
405: static final int BOCU1 = UTF7 + 1; //28
406: static final int UTF16 = BOCU1 + 1; //29
407: static final int UTF32 = UTF16 + 1; //30
408: static final int CESU8 = UTF32 + 1; //31
409: static final int IMAP_MAILBOX = CESU8 + 1; //32
410: //static final int MAC_ARABIC = IMAP_MAILBOX + 1; //33 Not in ICU4C
411: //static final int MAC_HEBREW = MAC_ARABIC + 1; //34 Not in ICU4C
412:
413: // Number of converter types for which we have conversion routines.
414: //static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = MAC_HEBREW + 1;
415: }
416:
417: /**
418: * Enum for specifying which platform a converter ID refers to.
419: * The use of platform/CCSID is not recommended. See openCCSID().
420: * @draft ICU 3.6
421: */
422: static final class UConverterPlatform {
423: static final int UNKNOWN = -1;
424: static final int IBM = 0;
425: }
426:
427: static UConverterSharedData _MBCSData = null, /*_Latin1Data = null,*//*_UTF8Data = null,*//*_UTF16BEData = null,*//*_UTF16LEData = null,*//*_UTF32BEData = null,*//*_UTF32LEData = null,*//*_ISO2022Data = null,*/
428: _LMBCSData1 = null, _LMBCSData2 = null, _LMBCSData3 = null,
429: _LMBCSData4 = null, _LMBCSData5 = null, _LMBCSData6 = null,
430: _LMBCSData8 = null, _LMBCSData11 = null,
431: _LMBCSData16 = null, _LMBCSData17 = null,
432: _LMBCSData18 = null, _LMBCSData19 = null, _HZData = null,
433: _SCSUData = null, /*_ISCIIData = null,*//*_ASCIIData = null,*/
434: _UTF7Data = null, _Bocu1Data = null, /*_UTF16Data = null, _UTF32Data = null,*/
435: _CESU8Data = null, _IMAPData = null;
436: static UConverterSharedData[] converterData;
437: /* static class cnvNameTypeClass {
438: String name;
439: int type;
440: cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; }
441: }
442:
443: static cnvNameTypeClass cnvNameType[];*/
444:
445: static final String DATA_TYPE = "cnv";
446: //static final int CNV_DATA_BUFFER_SIZE = 25000;
447: static final int SIZE_OF_UCONVERTER_SHARED_DATA = 100;
448:
449: static final int MAXIMUM_UCS2 = 0x0000FFFF;
450: static final int MAXIMUM_UTF = 0x0010FFFF;
451: static final int MAXIMUM_UCS4 = 0x7FFFFFFF;
452: static final int HALF_SHIFT = 10;
453: static final int HALF_BASE = 0x0010000;
454: static final int HALF_MASK = 0x3FF;
455: static final int SURROGATE_HIGH_START = 0xD800;
456: static final int SURROGATE_HIGH_END = 0xDBFF;
457: static final int SURROGATE_LOW_START = 0xDC00;
458: static final int SURROGATE_LOW_END = 0xDFFF;
459:
460: /* -SURROGATE_LOW_START + HALF_BASE */
461: static final int SURROGATE_LOW_BASE = 9216;
462: }
|