/*
 * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 *******************************************************************************
 * (C) Copyright IBM Corp. 1996-2005 - All Rights Reserved                     *
 *                                                                             *
 * The original version of this source code and documentation is copyrighted   *
 * and owned by IBM, These materials are provided under terms of a License     *
 * Agreement between IBM and Sun. This technology is protected by multiple     *
 * US and International patents. This notice and attribution to IBM may not    *
 * to removed.                                                                 *
 *******************************************************************************
 */

package sun.text.normalizer;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Arrays;

public final class ICUBinary
{
    // public inner interface ------------------------------------------------

    
Special interface for data authentication
/** * Special interface for data authentication */
public static interface Authenticate {
Method used in ICUBinary.readHeader() to provide data format authentication.
Params:
  • version – version of the current data
Returns:true if dataformat is an acceptable version, false otherwise
/** * Method used in ICUBinary.readHeader() to provide data format * authentication. * @param version version of the current data * @return true if dataformat is an acceptable version, false otherwise */
public boolean isDataVersionAcceptable(byte version[]); } // public methods --------------------------------------------------------

ICU data header reader method. Takes a ICU generated big-endian input stream, parse the ICU standard file header and authenticates them.

Header format:

  • Header size (char)
  • Magic number 1 (byte)
  • Magic number 2 (byte)
  • Rest of the header size (char)
  • Reserved word (char)
  • Big endian indicator (byte)
  • Character set family indicator (byte)
  • Size of a char (byte) for c++ and c use
  • Reserved byte (byte)
  • Data format identifier (4 bytes), each ICU data has its own identifier to distinguish them. [0] major [1] minor [2] milli [3] micro
  • Data version (4 bytes), the change version of the ICU data [0] major [1] minor [2] milli [3] micro
  • Unicode version (4 bytes) this ICU is based on.

Example of use:

try {
   FileInputStream input = new FileInputStream(filename);
   If (Utility.readICUDataHeader(input, dataformat, dataversion,
                                 unicode) {
       System.out.println("Verified file header, this is a ICU data file");
   }
} catch (IOException e) {
   System.out.println("This is not a ICU data file");
}

Params:
  • inputStream – input stream that contains the ICU data header
  • dataFormatIDExpected – Data format expected. An array of 4 bytes information about the data format. E.g. data format ID 1.2.3.4. will became an array of {1, 2, 3, 4}
  • authenticate – user defined extra data authentication. This value can be null, if no extra authentication is needed.
Throws:
  • IOException – thrown if there is a read error or when header authentication fails.
@draft2.1
/** * <p>ICU data header reader method. * Takes a ICU generated big-endian input stream, parse the ICU standard * file header and authenticates them.</p> * <p>Header format: * <ul> * <li> Header size (char) * <li> Magic number 1 (byte) * <li> Magic number 2 (byte) * <li> Rest of the header size (char) * <li> Reserved word (char) * <li> Big endian indicator (byte) * <li> Character set family indicator (byte) * <li> Size of a char (byte) for c++ and c use * <li> Reserved byte (byte) * <li> Data format identifier (4 bytes), each ICU data has its own * identifier to distinguish them. [0] major [1] minor * [2] milli [3] micro * <li> Data version (4 bytes), the change version of the ICU data * [0] major [1] minor [2] milli [3] micro * <li> Unicode version (4 bytes) this ICU is based on. * </ul> * </p> * <p> * Example of use:<br> * <pre> * try { * FileInputStream input = new FileInputStream(filename); * If (Utility.readICUDataHeader(input, dataformat, dataversion, * unicode) { * System.out.println("Verified file header, this is a ICU data file"); * } * } catch (IOException e) { * System.out.println("This is not a ICU data file"); * } * </pre> * </p> * @param inputStream input stream that contains the ICU data header * @param dataFormatIDExpected Data format expected. An array of 4 bytes * information about the data format. * E.g. data format ID 1.2.3.4. will became an array of * {1, 2, 3, 4} * @param authenticate user defined extra data authentication. This value * can be null, if no extra authentication is needed. * @exception IOException thrown if there is a read error or * when header authentication fails. * @draft 2.1 */
public static final byte[] readHeader(InputStream inputStream, byte dataFormatIDExpected[], Authenticate authenticate) throws IOException { DataInputStream input = new DataInputStream(inputStream); char headersize = input.readChar(); int readcount = 2; //reading the header format byte magic1 = input.readByte(); readcount ++; byte magic2 = input.readByte(); readcount ++; if (magic1 != MAGIC1 || magic2 != MAGIC2) { throw new IOException(MAGIC_NUMBER_AUTHENTICATION_FAILED_); } input.readChar(); // reading size readcount += 2; input.readChar(); // reading reserved word readcount += 2; byte bigendian = input.readByte(); readcount ++; byte charset = input.readByte(); readcount ++; byte charsize = input.readByte(); readcount ++; input.readByte(); // reading reserved byte readcount ++; byte dataFormatID[] = new byte[4]; input.readFully(dataFormatID); readcount += 4; byte dataVersion[] = new byte[4]; input.readFully(dataVersion); readcount += 4; byte unicodeVersion[] = new byte[4]; input.readFully(unicodeVersion); readcount += 4; if (headersize < readcount) { throw new IOException("Internal Error: Header size error"); } input.skipBytes(headersize - readcount); if (bigendian != BIG_ENDIAN_ || charset != CHAR_SET_ || charsize != CHAR_SIZE_ || !Arrays.equals(dataFormatIDExpected, dataFormatID) || (authenticate != null && !authenticate.isDataVersionAcceptable(dataVersion))) { throw new IOException(HEADER_AUTHENTICATION_FAILED_); } return unicodeVersion; } // private variables -------------------------------------------------
Magic numbers to authenticate the data file
/** * Magic numbers to authenticate the data file */
private static final byte MAGIC1 = (byte)0xda; private static final byte MAGIC2 = (byte)0x27;
File format authentication values
/** * File format authentication values */
private static final byte BIG_ENDIAN_ = 1; private static final byte CHAR_SET_ = 0; private static final byte CHAR_SIZE_ = 2;
Error messages
/** * Error messages */
private static final String MAGIC_NUMBER_AUTHENTICATION_FAILED_ = "ICU data file error: Not an ICU data file"; private static final String HEADER_AUTHENTICATION_FAILED_ = "ICU data file error: Header authentication failed, please check if you have a valid ICU data file"; }