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