KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > impl > ICUBinary


1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2004, International Business Machines Corporation and *
4  * others. All Rights Reserved. *
5  *******************************************************************************
6  */

7 package com.ibm.icu.impl;
8
9 import java.io.InputStream JavaDoc;
10 import java.io.DataInputStream JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.util.Arrays JavaDoc;
13
14 public final class ICUBinary
15 {
16     // public inner interface ------------------------------------------------
17

18     /**
19      * Special interface for data authentication
20      */

21     public static interface Authenticate
22     {
23         /**
24          * Method used in ICUBinary.readHeader() to provide data format
25          * authentication.
26          * @param version version of the current data
27          * @return true if dataformat is an acceptable version, false otherwise
28          */

29         public boolean isDataVersionAcceptable(byte version[]);
30     }
31     
32     // public methods --------------------------------------------------------
33

34     /**
35     * <p>ICU data header reader method.
36     * Takes a ICU generated big-endian input stream, parse the ICU standard
37     * file header and authenticates them.</p>
38     * <p>Header format:
39     * <ul>
40     * <li> Header size (char)
41     * <li> Magic number 1 (byte)
42     * <li> Magic number 2 (byte)
43     * <li> Rest of the header size (char)
44     * <li> Reserved word (char)
45     * <li> Big endian indicator (byte)
46     * <li> Character set family indicator (byte)
47     * <li> Size of a char (byte) for c++ and c use
48     * <li> Reserved byte (byte)
49     * <li> Data format identifier (4 bytes), each ICU data has its own
50     * identifier to distinguish them. [0] major [1] minor
51     * [2] milli [3] micro
52     * <li> Data version (4 bytes), the change version of the ICU data
53     * [0] major [1] minor [2] milli [3] micro
54     * <li> Unicode version (4 bytes) this ICU is based on.
55     * </ul>
56     * </p>
57     * <p>
58     * Example of use:<br>
59     * <pre>
60     * try {
61     * FileInputStream input = new FileInputStream(filename);
62     * If (Utility.readICUDataHeader(input, dataformat, dataversion,
63     * unicode) {
64     * System.out.println("Verified file header, this is a ICU data file");
65     * }
66     * } catch (IOException e) {
67     * System.out.println("This is not a ICU data file");
68     * }
69     * </pre>
70     * </p>
71     * @param inputStream input stream that contains the ICU data header
72     * @param dataFormatIDExpected Data format expected. An array of 4 bytes
73     * information about the data format.
74     * E.g. data format ID 1.2.3.4. will became an array of
75     * {1, 2, 3, 4}
76     * @param authenticate user defined extra data authentication. This value
77     * can be null, if no extra authentication is needed.
78     * @exception IOException thrown if there is a read error or
79     * when header authentication fails.
80     * @draft 2.1
81     */

82     public static final byte[] readHeader(InputStream JavaDoc inputStream,
83                                         byte dataFormatIDExpected[],
84                                         Authenticate authenticate)
85                                                           throws IOException JavaDoc
86     {
87         DataInputStream JavaDoc input = new DataInputStream JavaDoc(inputStream);
88         char headersize = input.readChar();
89         int readcount = 2;
90         //reading the header format
91
byte magic1 = input.readByte();
92         readcount ++;
93         byte magic2 = input.readByte();
94         readcount ++;
95         if (magic1 != MAGIC1 || magic2 != MAGIC2) {
96             throw new IOException JavaDoc(MAGIC_NUMBER_AUTHENTICATION_FAILED_);
97         }
98         
99         input.readChar(); // reading size
100
readcount += 2;
101         input.readChar(); // reading reserved word
102
readcount += 2;
103         byte bigendian = input.readByte();
104         readcount ++;
105         byte charset = input.readByte();
106         readcount ++;
107         byte charsize = input.readByte();
108         readcount ++;
109         input.readByte(); // reading reserved byte
110
readcount ++;
111                 
112         byte dataFormatID[] = new byte[4];
113         input.readFully(dataFormatID);
114         readcount += 4;
115         byte dataVersion[] = new byte[4];
116         input.readFully(dataVersion);
117         readcount += 4;
118         byte unicodeVersion[] = new byte[4];
119         input.readFully(unicodeVersion);
120         readcount += 4;
121         if (headersize < readcount) {
122             throw new IOException JavaDoc("Internal Error: Header size error");
123         }
124         input.skipBytes(headersize - readcount);
125
126         if (bigendian != BIG_ENDIAN_ || charset != CHAR_SET_
127             || charsize != CHAR_SIZE_
128             || !Arrays.equals(dataFormatIDExpected, dataFormatID)
129             || (authenticate != null
130                 && !authenticate.isDataVersionAcceptable(dataVersion))) {
131             throw new IOException JavaDoc(HEADER_AUTHENTICATION_FAILED_);
132         }
133         return unicodeVersion;
134     }
135      
136     // private variables -------------------------------------------------
137

138     /**
139     * Magic numbers to authenticate the data file
140     */

141     private static final byte MAGIC1 = (byte)0xda;
142     private static final byte MAGIC2 = (byte)0x27;
143       
144     /**
145     * File format authentication values
146     */

147     private static final byte BIG_ENDIAN_ = 1;
148     private static final byte CHAR_SET_ = 0;
149     private static final byte CHAR_SIZE_ = 2;
150                                                     
151     /**
152     * Error messages
153     */

154     private static final String JavaDoc MAGIC_NUMBER_AUTHENTICATION_FAILED_ =
155                        "ICU data file error: Not an ICU data file";
156     private static final String JavaDoc HEADER_AUTHENTICATION_FAILED_ =
157         "ICU data file error: Header authentication failed, please check if you have a valid ICU data file";
158 }
159
Popular Tags