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