jdk/src/java.base/share/classes/sun/text/normalizer/ICUBinary.java
changeset 25859 3317bb8137f4
parent 5506 202f599c92aa
child 30655 d83f50188ca9
equal deleted inserted replaced
25858:836adbf7a2cd 25859:3317bb8137f4
       
     1 /*
       
     2  * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 /*
       
    27  *******************************************************************************
       
    28  * (C) Copyright IBM Corp. 1996-2005 - All Rights Reserved                     *
       
    29  *                                                                             *
       
    30  * The original version of this source code and documentation is copyrighted   *
       
    31  * and owned by IBM, These materials are provided under terms of a License     *
       
    32  * Agreement between IBM and Sun. This technology is protected by multiple     *
       
    33  * US and International patents. This notice and attribution to IBM may not    *
       
    34  * to removed.                                                                 *
       
    35  *******************************************************************************
       
    36  */
       
    37 
       
    38 package sun.text.normalizer;
       
    39 
       
    40 import java.io.InputStream;
       
    41 import java.io.DataInputStream;
       
    42 import java.io.IOException;
       
    43 import java.util.Arrays;
       
    44 
       
    45 public final class ICUBinary
       
    46 {
       
    47     // public inner interface ------------------------------------------------
       
    48 
       
    49     /**
       
    50      * Special interface for data authentication
       
    51      */
       
    52     public static interface Authenticate
       
    53     {
       
    54         /**
       
    55          * Method used in ICUBinary.readHeader() to provide data format
       
    56          * authentication.
       
    57          * @param version version of the current data
       
    58          * @return true if dataformat is an acceptable version, false otherwise
       
    59          */
       
    60         public boolean isDataVersionAcceptable(byte version[]);
       
    61     }
       
    62 
       
    63     // public methods --------------------------------------------------------
       
    64 
       
    65     /**
       
    66     * <p>ICU data header reader method.
       
    67     * Takes a ICU generated big-endian input stream, parse the ICU standard
       
    68     * file header and authenticates them.</p>
       
    69     * <p>Header format:
       
    70     * <ul>
       
    71     *     <li> Header size (char)
       
    72     *     <li> Magic number 1 (byte)
       
    73     *     <li> Magic number 2 (byte)
       
    74     *     <li> Rest of the header size (char)
       
    75     *     <li> Reserved word (char)
       
    76     *     <li> Big endian indicator (byte)
       
    77     *     <li> Character set family indicator (byte)
       
    78     *     <li> Size of a char (byte) for c++ and c use
       
    79     *     <li> Reserved byte (byte)
       
    80     *     <li> Data format identifier (4 bytes), each ICU data has its own
       
    81     *          identifier to distinguish them. [0] major [1] minor
       
    82     *                                          [2] milli [3] micro
       
    83     *     <li> Data version (4 bytes), the change version of the ICU data
       
    84     *                             [0] major [1] minor [2] milli [3] micro
       
    85     *     <li> Unicode version (4 bytes) this ICU is based on.
       
    86     * </ul>
       
    87     * </p>
       
    88     * <p>
       
    89     * Example of use:<br>
       
    90     * <pre>
       
    91     * try {
       
    92     *    FileInputStream input = new FileInputStream(filename);
       
    93     *    If (Utility.readICUDataHeader(input, dataformat, dataversion,
       
    94     *                                  unicode) {
       
    95     *        System.out.println("Verified file header, this is a ICU data file");
       
    96     *    }
       
    97     * } catch (IOException e) {
       
    98     *    System.out.println("This is not a ICU data file");
       
    99     * }
       
   100     * </pre>
       
   101     * </p>
       
   102     * @param inputStream input stream that contains the ICU data header
       
   103     * @param dataFormatIDExpected Data format expected. An array of 4 bytes
       
   104     *                     information about the data format.
       
   105     *                     E.g. data format ID 1.2.3.4. will became an array of
       
   106     *                     {1, 2, 3, 4}
       
   107     * @param authenticate user defined extra data authentication. This value
       
   108     *                     can be null, if no extra authentication is needed.
       
   109     * @exception IOException thrown if there is a read error or
       
   110     *            when header authentication fails.
       
   111     * @draft 2.1
       
   112     */
       
   113     public static final byte[] readHeader(InputStream inputStream,
       
   114                                         byte dataFormatIDExpected[],
       
   115                                         Authenticate authenticate)
       
   116                                                           throws IOException
       
   117     {
       
   118         DataInputStream input = new DataInputStream(inputStream);
       
   119         char headersize = input.readChar();
       
   120         int readcount = 2;
       
   121         //reading the header format
       
   122         byte magic1 = input.readByte();
       
   123         readcount ++;
       
   124         byte magic2 = input.readByte();
       
   125         readcount ++;
       
   126         if (magic1 != MAGIC1 || magic2 != MAGIC2) {
       
   127             throw new IOException(MAGIC_NUMBER_AUTHENTICATION_FAILED_);
       
   128         }
       
   129 
       
   130         input.readChar(); // reading size
       
   131         readcount += 2;
       
   132         input.readChar(); // reading reserved word
       
   133         readcount += 2;
       
   134         byte bigendian    = input.readByte();
       
   135         readcount ++;
       
   136         byte charset      = input.readByte();
       
   137         readcount ++;
       
   138         byte charsize     = input.readByte();
       
   139         readcount ++;
       
   140         input.readByte(); // reading reserved byte
       
   141         readcount ++;
       
   142 
       
   143         byte dataFormatID[] = new byte[4];
       
   144         input.readFully(dataFormatID);
       
   145         readcount += 4;
       
   146         byte dataVersion[] = new byte[4];
       
   147         input.readFully(dataVersion);
       
   148         readcount += 4;
       
   149         byte unicodeVersion[] = new byte[4];
       
   150         input.readFully(unicodeVersion);
       
   151         readcount += 4;
       
   152         if (headersize < readcount) {
       
   153             throw new IOException("Internal Error: Header size error");
       
   154         }
       
   155         input.skipBytes(headersize - readcount);
       
   156 
       
   157         if (bigendian != BIG_ENDIAN_ || charset != CHAR_SET_
       
   158             || charsize != CHAR_SIZE_
       
   159             || !Arrays.equals(dataFormatIDExpected, dataFormatID)
       
   160             || (authenticate != null
       
   161                 && !authenticate.isDataVersionAcceptable(dataVersion))) {
       
   162             throw new IOException(HEADER_AUTHENTICATION_FAILED_);
       
   163         }
       
   164         return unicodeVersion;
       
   165     }
       
   166 
       
   167     // private variables -------------------------------------------------
       
   168 
       
   169     /**
       
   170     * Magic numbers to authenticate the data file
       
   171     */
       
   172     private static final byte MAGIC1 = (byte)0xda;
       
   173     private static final byte MAGIC2 = (byte)0x27;
       
   174 
       
   175     /**
       
   176     * File format authentication values
       
   177     */
       
   178     private static final byte BIG_ENDIAN_ = 1;
       
   179     private static final byte CHAR_SET_ = 0;
       
   180     private static final byte CHAR_SIZE_ = 2;
       
   181 
       
   182     /**
       
   183     * Error messages
       
   184     */
       
   185     private static final String MAGIC_NUMBER_AUTHENTICATION_FAILED_ =
       
   186                        "ICU data file error: Not an ICU data file";
       
   187     private static final String HEADER_AUTHENTICATION_FAILED_ =
       
   188         "ICU data file error: Header authentication failed, please check if you have a valid ICU data file";
       
   189 }