]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/classes/charset/src/com/ibm/icu/charset/UConverterDataReader.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / classes / charset / src / com / ibm / icu / charset / UConverterDataReader.java
1 /*
2 *******************************************************************************
3 * Copyright (C) 2006-2010, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 */ 
7  
8 package com.ibm.icu.charset;
9
10 import java.io.DataInputStream;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.nio.ByteBuffer;
14
15 import com.ibm.icu.impl.ICUBinary;
16
17 /**
18  * ucnvmbcs.h
19  *
20  * ICU conversion (.cnv) data file structure, following the usual UDataInfo
21  * header.
22  *
23  * Format version: 6.2
24  *
25  * struct UConverterStaticData -- struct containing the converter name, IBM CCSID,
26  *                                min/max bytes per character, etc.
27  *                                see ucnv_bld.h
28  *
29  * --------------------
30  *
31  * The static data is followed by conversionType-specific data structures.
32  * At the moment, there are only variations of MBCS converters. They all have
33  * the same toUnicode structures, while the fromUnicode structures for SBCS
34  * differ from those for other MBCS-style converters.
35  *
36  * _MBCSHeader.version 4.2 adds an optional conversion extension data structure.
37  * If it is present, then an ICU version reading header versions 4.0 or 4.1
38  * will be able to use the base table and ignore the extension.
39  *
40  * The unicodeMask in the static data is part of the base table data structure.
41  * Especially, the UCNV_HAS_SUPPLEMENTARY flag determines the length of the
42  * fromUnicode stage 1 array.
43  * The static data unicodeMask refers only to the base table's properties if
44  * a base table is included.
45  * In an extension-only file, the static data unicodeMask is 0.
46  * The extension data indexes have a separate field with the unicodeMask flags.
47  *
48  * MBCS-style data structure following the static data.
49  * Offsets are counted in bytes from the beginning of the MBCS header structure.
50  * Details about usage in comments in ucnvmbcs.c.
51  *
52  * struct _MBCSHeader (see the definition in this header file below)
53  * contains 32-bit fields as follows:
54  * 8 values:
55  *  0   uint8_t[4]  MBCS version in UVersionInfo format (currently 4.2.0.0)
56  *  1   uint32_t    countStates
57  *  2   uint32_t    countToUFallbacks
58  *  3   uint32_t    offsetToUCodeUnits
59  *  4   uint32_t    offsetFromUTable
60  *  5   uint32_t    offsetFromUBytes
61  *  6   uint32_t    flags, bits:
62  *                      31.. 8 offsetExtension -- _MBCSHeader.version 4.2 (ICU 2.8) and higher
63  *                                                0 for older versions and if
64  *                                                there is not extension structure
65  *                       7.. 0 outputType
66  *  7   uint32_t    fromUBytesLength -- _MBCSHeader.version 4.1 (ICU 2.4) and higher
67  *                  counts bytes in fromUBytes[]
68  *
69  * if(outputType==MBCS_OUTPUT_EXT_ONLY) {
70  *     -- base table name for extension-only table
71  *     char baseTableName[variable]; -- with NUL plus padding for 4-alignment
72  *
73  *     -- all _MBCSHeader fields except for version and flags are 0
74  * } else {
75  *     -- normal base table with optional extension
76  *
77  *     int32_t stateTable[countStates][256];
78  *    
79  *     struct _MBCSToUFallback { (fallbacks are sorted by offset)
80  *         uint32_t offset;
81  *         UChar32 codePoint;
82  *     } toUFallbacks[countToUFallbacks];
83  *    
84  *     uint16_t unicodeCodeUnits[(offsetFromUTable-offsetToUCodeUnits)/2];
85  *                  (padded to an even number of units)
86  *    
87  *     -- stage 1 tables
88  *     if(staticData.unicodeMask&UCNV_HAS_SUPPLEMENTARY) {
89  *         -- stage 1 table for all of Unicode
90  *         uint16_t fromUTable[0x440]; (32-bit-aligned)
91  *     } else {
92  *         -- BMP-only tables have a smaller stage 1 table
93  *         uint16_t fromUTable[0x40]; (32-bit-aligned)
94  *     }
95  *    
96  *     -- stage 2 tables
97  *        length determined by top of stage 1 and bottom of stage 3 tables
98  *     if(outputType==MBCS_OUTPUT_1) {
99  *         -- SBCS: pure indexes
100  *         uint16_t stage 2 indexes[?];
101  *     } else {
102  *         -- DBCS, MBCS, EBCDIC_STATEFUL, ...: roundtrip flags and indexes
103  *         uint32_t stage 2 flags and indexes[?];
104  *     }
105  *    
106  *     -- stage 3 tables with byte results
107  *     if(outputType==MBCS_OUTPUT_1) {
108  *         -- SBCS: each 16-bit result contains flags and the result byte, see ucnvmbcs.c
109  *         uint16_t fromUBytes[fromUBytesLength/2];
110  *     } else {
111  *         -- DBCS, MBCS, EBCDIC_STATEFUL, ... 2/3/4 bytes result, see ucnvmbcs.c
112  *         uint8_t fromUBytes[fromUBytesLength]; or
113  *         uint16_t fromUBytes[fromUBytesLength/2]; or
114  *         uint32_t fromUBytes[fromUBytesLength/4];
115  *     }
116  * }
117  *
118  * -- extension table, details see ucnv_ext.h
119  * int32_t indexes[>=32]; ...
120  */
121 /*
122  * ucnv_ext.h
123  *
124  * See icuhtml/design/conversion/conversion_extensions.html
125  *
126  * Conversion extensions serve two purposes:
127  * 1. They support m:n mappings.
128  * 2. They support extension-only conversion files that are used together
129  *    with the regular conversion data in base files.
130  *
131  * A base file may contain an extension table (explicitly requested or
132  * implicitly generated for m:n mappings), but its extension table is not
133  * used when an extension-only file is used.
134  *
135  * It is an error if a base file contains any regular (not extension) mapping
136  * from the same sequence as a mapping in the extension file
137  * because the base mapping would hide the extension mapping.
138  *
139  *
140  * Data for conversion extensions:
141  *
142  * One set of data structures per conversion direction (to/from Unicode).
143  * The data structures are sorted by input units to allow for binary search.
144  * Input sequences of more than one unit are handled like contraction tables
145  * in collation:
146  * The lookup value of a unit points to another table that is to be searched
147  * for the next unit, recursively.
148  *
149  * For conversion from Unicode, the initial code point is looked up in
150  * a 3-stage trie for speed,
151  * with an additional table of unique results to save space.
152  *
153  * Long output strings are stored in separate arrays, with length and index
154  * in the lookup tables.
155  * Output results also include a flag distinguishing roundtrip from
156  * (reverse) fallback mappings.
157  *
158  * Input Unicode strings must not begin or end with unpaired surrogates
159  * to avoid problems with matches on parts of surrogate pairs.
160  *
161  * Mappings from multiple characters (code points or codepage state
162  * table sequences) must be searched preferring the longest match.
163  * For this to work and be efficient, the variable-width table must contain
164  * all mappings that contain prefixes of the multiple characters.
165  * If an extension table is built on top of a base table in another file
166  * and a base table entry is a prefix of a multi-character mapping, then
167  * this is an error.
168  *
169  *
170  * Implementation note:
171  *
172  * Currently, the parser and several checks in the code limit the number
173  * of UChars or bytes in a mapping to
174  * UCNV_EXT_MAX_UCHARS and UCNV_EXT_MAX_BYTES, respectively,
175  * which are output value limits in the data structure.
176  *
177  * For input, this is not strictly necessary - it is a hard limit only for the
178  * buffers in UConverter that are used to store partial matches.
179  *
180  * Input sequences could otherwise be arbitrarily long if partial matches
181  * need not be stored (i.e., if a sequence does not span several buffers with too
182  * many units before the last buffer), although then results would differ
183  * depending on whether partial matches exceed the limits or not,
184  * which depends on the pattern of buffer sizes.
185  *
186  *
187  * Data structure:
188  *
189  * int32_t indexes[>=32];
190  *
191  *   Array of indexes and lengths etc. The length of the array is at least 32.
192  *   The actual length is stored in indexes[0] to be forward compatible.
193  *
194  *   Each index to another array is the number of bytes from indexes[].
195  *   Each length of an array is the number of array base units in that array.
196  *
197  *   Some of the structures may not be present, in which case their indexes
198  *   and lengths are 0.
199  *
200  *   Usage of indexes[i]:
201  *   [0]  length of indexes[]
202  *
203  *   // to Unicode table
204  *   [1]  index of toUTable[] (array of uint32_t)
205  *   [2]  length of toUTable[]
206  *   [3]  index of toUUChars[] (array of UChar)
207  *   [4]  length of toUUChars[]
208  *
209  *   // from Unicode table, not for the initial code point
210  *   [5]  index of fromUTableUChars[] (array of UChar)
211  *   [6]  index of fromUTableValues[] (array of uint32_t)
212  *   [7]  length of fromUTableUChars[] and fromUTableValues[]
213  *   [8]  index of fromUBytes[] (array of char)
214  *   [9]  length of fromUBytes[]
215  *
216  *   // from Unicode trie for initial-code point lookup
217  *   [10] index of fromUStage12[] (combined array of uint16_t for stages 1 & 2)
218  *   [11] length of stage 1 portion of fromUStage12[]
219  *   [12] length of fromUStage12[]
220  *   [13] index of fromUStage3[] (array of uint16_t indexes into fromUStage3b[])
221  *   [14] length of fromUStage3[]
222  *   [15] index of fromUStage3b[] (array of uint32_t like fromUTableValues[])
223  *   [16] length of fromUStage3b[]
224  *
225  *   [17] Bit field containing numbers of bytes:
226  *        31..24 reserved, 0
227  *        23..16 maximum input bytes
228  *        15.. 8 maximum output bytes
229  *         7.. 0 maximum bytes per UChar
230  *
231  *   [18] Bit field containing numbers of UChars:
232  *        31..24 reserved, 0
233  *        23..16 maximum input UChars
234  *        15.. 8 maximum output UChars
235  *         7.. 0 maximum UChars per byte
236  *
237  *   [19] Bit field containing flags:
238  *               (extension table unicodeMask)
239  *         1     UCNV_HAS_SURROGATES flag for the extension table
240  *         0     UCNV_HAS_SUPPLEMENTARY flag for the extension table
241  *
242  *   [20]..[30] reserved, 0
243  *   [31] number of bytes for the entire extension structure
244  *   [>31] reserved; there are indexes[0] indexes
245  *
246  *
247  * uint32_t toUTable[];
248  *
249  *   Array of byte/value pairs for lookups for toUnicode conversion.
250  *   The array is partitioned into sections like collation contraction tables.
251  *   Each section contains one word with the number of following words and
252  *   a default value for when the lookup in this section yields no match.
253  *
254  *   A section is sorted in ascending order of input bytes,
255  *   allowing for fast linear or binary searches.
256  *   The builder may store entries for a contiguous range of byte values
257  *   (compare difference between the first and last one with count),
258  *   which then allows for direct array access.
259  *   The builder should always do this for the initial table section.
260  *
261  *   Entries may have 0 values, see below.
262  *   No two entries in a section have the same byte values.
263  *
264  *   Each uint32_t contains an input byte value in bits 31..24 and the
265  *   corresponding lookup value in bits 23..0.
266  *   Interpret the value as follows:
267  *     if(value==0) {
268  *       no match, see below
269  *     } else if(value<0x1f0000) {
270  *       partial match - use value as index to the next toUTable section
271  *       and match the next unit; (value indexes toUTable[value])
272  *     } else {
273  *       if(bit 23 set) {
274  *         roundtrip;
275  *       } else {
276  *         fallback;
277  *       }
278  *       unset value bit 23;
279  *       if(value<=0x2fffff) {
280  *         (value-0x1f0000) is a code point; (BMP: value<=0x1fffff)
281  *       } else {
282  *         bits 17..0 (value&0x3ffff) is an index to
283  *           the result UChars in toUUChars[]; (0 indexes toUUChars[0])
284  *         length of the result=((value>>18)-12); (length=0..19)
285  *       }
286  *     }
287  *
288  *   The first word in a section contains the number of following words in the
289  *   input byte position (bits 31..24, number=1..0xff).
290  *   The value of the initial word is used when the current byte is not found
291  *   in this section.
292  *   If the value is not 0, then it represents a result as above.
293  *   If the value is 0, then the search has to return a shorter match with an
294  *   earlier default value as the result, or result in "unmappable" even for the
295  *   initial bytes.
296  *   If the value is 0 for the initial toUTable entry, then the initial byte
297  *   does not start any mapping input.
298  *
299  *
300  * UChar toUUChars[];
301  *
302  *   Contains toUnicode mapping results, stored as sequences of UChars.
303  *   Indexes and lengths stored in the toUTable[].
304  *
305  *
306  * UChar fromUTableUChars[];
307  * uint32_t fromUTableValues[];
308  *
309  *   The fromUTable is split into two arrays, but works otherwise much like
310  *   the toUTable. The array is partitioned into sections like collation
311  *   contraction tables and toUTable.
312  *   A row in the table consists of same-index entries in fromUTableUChars[]
313  *   and fromUTableValues[].
314  *
315  *   Interpret a value as follows:
316  *     if(value==0) {
317  *       no match, see below
318  *     } else if(value<=0xffffff) { (bits 31..24 are 0)
319  *       partial match - use value as index to the next fromUTable section
320  *       and match the next unit; (value indexes fromUTable[value])
321  *     } else {
322  *       if(value==0x80000001) {
323  *         return no mapping, but request for <subchar1>;
324  *       }
325  *       if(bit 31 set) {
326  *         roundtrip;
327  *       } else {
328  *         fallback;
329  *       }
330  *       // bits 30..29 reserved, 0
331  *       length=(value>>24)&0x1f; (bits 28..24)
332  *       if(length==1..3) {
333  *         bits 23..0 contain 1..3 bytes, padded with 00s on the left;
334  *       } else {
335  *         bits 23..0 (value&0xffffff) is an index to
336  *           the result bytes in fromUBytes[]; (0 indexes fromUBytes[0])
337  *       }
338  *     }
339  *       
340  *   The first pair in a section contains the number of following pairs in the
341  *   UChar position (16 bits, number=1..0xffff).
342  *   The value of the initial pair is used when the current UChar is not found
343  *   in this section.
344  *   If the value is not 0, then it represents a result as above.
345  *   If the value is 0, then the search has to return a shorter match with an
346  *   earlier default value as the result, or result in "unmappable" even for the
347  *   initial UChars.
348  *
349  *   If the from Unicode trie is present, then the from Unicode search tables
350  *   are not used for initial code points.
351  *   In this case, the first entries (index 0) in the tables are not used
352  *   (reserved, set to 0) because a value of 0 is used in trie results
353  *   to indicate no mapping.
354  *
355  *
356  * uint16_t fromUStage12[];
357  *
358  *   Stages 1 & 2 of a trie that maps an initial code point.
359  *   Indexes in stage 1 are all offset by the length of stage 1 so that the
360  *   same array pointer can be used for both stages.
361  *   If (c>>10)>=(length of stage 1) then c does not start any mapping.
362  *   Same bit distribution as for regular conversion tries.
363  *
364  *
365  * uint16_t fromUStage3[];
366  * uint32_t fromUStage3b[];
367  *
368  *   Stage 3 of the trie. The first array simply contains indexes to the second,
369  *   which contains words in the same format as fromUTableValues[].
370  *   Use a stage 3 granularity of 4, which allows for 256k stage 3 entries,
371  *   and 16-bit entries in stage 3 allow for 64k stage 3b entries.
372  *   The stage 3 granularity means that the stage 2 entry needs to be left-shifted.
373  *
374  *   Two arrays are used because it is expected that more than half of the stage 3
375  *   entries will be zero. The 16-bit index stage 3 array saves space even
376  *   considering storing a total of 6 bytes per non-zero entry in both arrays
377  *   together.
378  *   Using a stage 3 granularity of >1 diminishes the compactability in that stage
379  *   but provides a larger effective addressing space in stage 2.
380  *   All but the final result stage use 16-bit entries to save space.
381  *
382  *   fromUStage3b[] contains a zero for "no mapping" at its index 0,
383  *   and may contain UCNV_EXT_FROM_U_SUBCHAR1 at index 1 for "<subchar1> SUB mapping"
384  *   (i.e., "no mapping" with preference for <subchar1> rather than <subchar>),
385  *   and all other items are unique non-zero results.
386  *
387  *   The default value of a fromUTableValues[] section that is referenced
388  *   _directly_ from a fromUStage3b[] item may also be UCNV_EXT_FROM_U_SUBCHAR1,
389  *   but this value must not occur anywhere else in fromUTableValues[]
390  *   because "no mapping" is always a property of a single code point,
391  *   never of multiple.
392  *
393  *
394  * char fromUBytes[];
395  *
396  *   Contains fromUnicode mapping results, stored as sequences of chars.
397  *   Indexes and lengths stored in the fromUTableValues[].
398  */
399
400 final class UConverterDataReader implements ICUBinary.Authenticate {
401     //private final static boolean debug = ICUDebug.enabled("UConverterDataReader");
402
403     /*
404      *  UConverterDataReader(UConverterDataReader r)
405         {
406             dataInputStream = new DataInputStream(r.dataInputStream);
407             unicodeVersion = r.unicodeVersion;
408         }
409         */
410    /* the number bytes read from the stream */ 
411    int bytesRead = 0;
412    /* the number of bytes read for static data */
413    int staticDataBytesRead = 0;
414    /**
415     * <p>Protected constructor.</p>
416     * @param inputStream ICU uprop.dat file input stream
417     * @exception IOException throw if data file fails authentication 
418     */
419     protected UConverterDataReader(InputStream inputStream) 
420                                         throws IOException{
421         //if(debug) System.out.println("Bytes in inputStream " + inputStream.available());
422         
423         /*unicodeVersion = */ICUBinary.readHeader(inputStream, DATA_FORMAT_ID, this);
424         
425         //if(debug) System.out.println("Bytes left in inputStream " +inputStream.available());
426         
427         dataInputStream = new DataInputStream(inputStream);
428         
429         //if(debug) System.out.println("Bytes left in dataInputStream " +dataInputStream.available());
430     }
431     
432     // protected methods -------------------------------------------------
433     
434     protected void readStaticData(UConverterStaticData sd) throws IOException
435     {
436         int bRead = 0;
437         sd.structSize = dataInputStream.readInt();
438         bRead +=4;
439         byte[] name = new byte[UConverterConstants.MAX_CONVERTER_NAME_LENGTH];
440         dataInputStream.readFully(name);
441         bRead +=name.length;
442         sd.name = new String(name, 0, name.length);
443         sd.codepage = dataInputStream.readInt();
444         bRead +=4;
445         sd.platform = dataInputStream.readByte();
446         bRead++;
447         sd.conversionType = dataInputStream.readByte();
448         bRead++;
449         sd.minBytesPerChar = dataInputStream.readByte();
450         bRead++;
451         sd.maxBytesPerChar = dataInputStream.readByte();
452         bRead++;
453         dataInputStream.readFully(sd.subChar);
454         bRead += sd.subChar.length;
455         sd.subCharLen = dataInputStream.readByte();
456         bRead++;
457         sd.hasToUnicodeFallback = dataInputStream.readByte();
458         bRead++;
459         sd.hasFromUnicodeFallback = dataInputStream.readByte();
460         bRead++;
461         sd.unicodeMask = (short)dataInputStream.readUnsignedByte();
462         bRead++;
463         sd.subChar1 = dataInputStream.readByte();
464         bRead++;
465         dataInputStream.readFully(sd.reserved);
466         bRead += sd.reserved.length;
467         staticDataBytesRead = bRead;
468         bytesRead += bRead;
469     }
470
471     protected void readMBCSHeader(CharsetMBCS.MBCSHeader h) throws IOException
472     {
473         dataInputStream.readFully(h.version);
474         bytesRead += h.version.length;
475         h.countStates = dataInputStream.readInt();
476         bytesRead+=4;
477         h.countToUFallbacks = dataInputStream.readInt();
478         bytesRead+=4;
479         h.offsetToUCodeUnits = dataInputStream.readInt();
480         bytesRead+=4;
481         h.offsetFromUTable = dataInputStream.readInt();
482         bytesRead+=4;
483         h.offsetFromUBytes = dataInputStream.readInt();
484         bytesRead+=4;
485         h.flags = dataInputStream.readInt();
486         bytesRead+=4;
487         h.fromUBytesLength = dataInputStream.readInt();
488         bytesRead+=4;
489         if (h.version[0] == 5 && h.version[1] >= 3) {
490             h.options = dataInputStream.readInt();
491             bytesRead+=4;
492             if ((h.options & CharsetMBCS.MBCS_OPT_NO_FROM_U) != 0) {
493                 h.fullStage2Length = dataInputStream.readInt();
494                 bytesRead+=4;
495             }
496         }
497     }
498     
499     protected void readMBCSTable(int[][] stateTableArray, CharsetMBCS.MBCSToUFallback[] toUFallbacksArray, char[] unicodeCodeUnitsArray, char[] fromUnicodeTableArray, byte[] fromUnicodeBytesArray) throws IOException
500     {
501         int i, j;
502         for(i = 0; i < stateTableArray.length; ++i){
503             for(j = 0; j < stateTableArray[i].length; ++j){
504                 stateTableArray[i][j] = dataInputStream.readInt();
505                 bytesRead+=4;
506             }
507         }
508         for(i = 0; i < toUFallbacksArray.length; ++i) {
509             toUFallbacksArray[i].offset = dataInputStream.readInt();
510             bytesRead+=4;
511             toUFallbacksArray[i].codePoint = dataInputStream.readInt();
512             bytesRead+=4;
513         }
514         for(i = 0; i < unicodeCodeUnitsArray.length; ++i){
515             unicodeCodeUnitsArray[i] = dataInputStream.readChar();
516             bytesRead+=2;
517         }
518         for(i = 0; i < fromUnicodeTableArray.length; ++i){
519             fromUnicodeTableArray[i] = dataInputStream.readChar();
520             bytesRead+=2;
521         }
522         for(i = 0; i < fromUnicodeBytesArray.length; ++i){
523             fromUnicodeBytesArray[i] = dataInputStream.readByte();
524             bytesRead++;
525         }
526     }
527
528     protected String readBaseTableName() throws IOException
529     {
530         char c;
531         StringBuilder name = new StringBuilder();
532         while((c = (char)dataInputStream.readByte()) !=  0){
533             name.append(c);
534             bytesRead++;
535         }
536         bytesRead++/*for null terminator*/;
537         return name.toString();
538     }
539
540     //protected int[] readExtIndexes(int skip) throws IOException
541     protected ByteBuffer readExtIndexes(int skip) throws IOException
542     {
543         int skipped = dataInputStream.skipBytes(skip);
544         if(skipped != skip){
545             throw new IOException("could not skip "+ skip +" bytes");
546         }
547         int n = dataInputStream.readInt();
548         bytesRead+=4;
549         int[] indexes = new int[n];
550         indexes[0] = n;
551         for(int i = 1; i < n; ++i) {
552             indexes[i] = dataInputStream.readInt();
553             bytesRead+=4;
554         }
555         //return indexes;
556
557         ByteBuffer b = ByteBuffer.allocate(indexes[31]);
558         for(int i = 0; i < n; ++i) {
559             b.putInt(indexes[i]);
560         }
561         int len = dataInputStream.read(b.array(), b.position(), b.remaining());
562         if(len==-1){
563             throw new IOException("Read failed");
564         }
565         bytesRead += len;
566         return b;
567     }
568
569     /*protected byte[] readExtTables(int n) throws IOException
570     {
571         byte[] tables = new byte[n];
572         int len =dataInputStream.read(tables);
573         if(len==-1){
574             throw new IOException("Read failed");
575         }
576         bytesRead += len;
577         return tables;
578     }*/
579
580     byte[] getDataFormatVersion(){
581         return DATA_FORMAT_VERSION;
582     }
583     /**
584      * Inherited method
585      */
586     public boolean isDataVersionAcceptable(byte version[]){
587         return version[0] == DATA_FORMAT_VERSION[0];
588     }
589     
590 /*    byte[] getUnicodeVersion(){
591         return unicodeVersion;    
592     }*/
593     // private data members -------------------------------------------------
594       
595     /**
596     * ICU data file input stream
597     */
598     DataInputStream dataInputStream;
599     
600 //    private byte[] unicodeVersion;
601                                        
602     /**
603     * File format version that this class understands.
604     * No guarantees are made if a older version is used
605     * see store.c of gennorm for more information and values
606     */
607     // DATA_FORMAT_ID_ values taken from icu4c isCnvAcceptable (ucnv_bld.c)
608     private static final byte DATA_FORMAT_ID[] = {(byte)0x63, (byte)0x6e, (byte)0x76, (byte)0x74}; // dataFormat="cnvt"
609     private static final byte DATA_FORMAT_VERSION[] = {(byte)0x6};
610
611 }
612