// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 ******************************************************************************
 * Copyright (C) 2003-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************
 *
 * Created on May 2, 2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */

package com.ibm.icu.impl;

import java.io.IOException;
import java.nio.ByteBuffer;


/**
 * @author ram
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public final class StringPrepDataReader implements ICUBinary.Authenticate {
    private final static boolean debug = ICUDebug.enabled("NormalizerDataReader");

   /**
    * <p>private constructor.</p>
    * @param bytes ICU StringPrep data file buffer
    * @exception IOException throw if data file fails authentication
    */
    public StringPrepDataReader(ByteBuffer bytes)
                                        throws IOException{
        if(debug) System.out.println("Bytes in buffer " + bytes.remaining());

        byteBuffer = bytes;
        unicodeVersion = ICUBinary.readHeader(byteBuffer, DATA_FORMAT_ID, this);

        if(debug) System.out.println("Bytes left in byteBuffer " + byteBuffer.remaining());
    }

    public char[] read(int length) throws IOException{
        //Read the extra data
        return ICUBinary.getChars(byteBuffer, length, 0);
    }

    @Override
    public boolean isDataVersionAcceptable(byte version[]){
        return version[0] == DATA_FORMAT_VERSION[0]
               && version[2] == DATA_FORMAT_VERSION[2]
               && version[3] == DATA_FORMAT_VERSION[3];
    }
    public int[] readIndexes(int length)throws IOException{
        int[] indexes = new int[length];
        //Read the indexes
        for (int i = 0; i <length ; i++) {
             indexes[i] = byteBuffer.getInt();
        }
        return indexes;
    }

    public byte[] getUnicodeVersion(){
        return ICUBinary.getVersionByteArrayFromCompactInt(unicodeVersion);
    }
    // private data members -------------------------------------------------


    /**
    * ICU data file input stream
    */
    private ByteBuffer byteBuffer;
    private int unicodeVersion;
    /**
    * File format version that this class understands.
    * No guarantees are made if a older version is used
    * see store.c of gennorm for more information and values
    */
    ///* dataFormat="SPRP" 0x53, 0x50, 0x52, 0x50  */
    private static final int DATA_FORMAT_ID = 0x53505250;
    private static final byte DATA_FORMAT_VERSION[] = {(byte)0x3, (byte)0x2,
                                                        (byte)0x5, (byte)0x2};
}
