/*
 *  ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ====================================================================
 */

package org.apache.poi.hssf.record.cont;

import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.util.LittleEndianInput;

/**
 * A decorated {@link RecordInputStream} that can read primitive data types
 * (short, int, long, etc.) spanned across a {@link ContinueRecord } boundary.
 *
 * <p>
 *  Most records construct themselves from {@link RecordInputStream}.
 *  This class assumes that a {@link ContinueRecord} record break always occurs at the type boundary,
 *  however, it is not always so.
 * </p>
 *  Two  attachments to <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=50779">Bugzilla 50779</a>
 *  demonstrate that a CONTINUE break can appear right in between two bytes of a unicode character
 *  or between two bytes of a <code>short</code>. The problematic portion of the data is
 *  in a Asian Phonetic Settings Block (ExtRst) of a UnicodeString.
 * <p>
 *  {@link RecordInputStream} greedily requests the bytes to be read and stumbles on such files with a
 *  "Not enough data (1) to read requested (2) bytes" exception.  The <code>ContinuableRecordInput</code>
 *   class circumvents this "type boundary" rule and reads data byte-by-byte rolling over CONTINUE if necessary.
 * </p>
 *
 * <p>
 * YK: For now (March 2011) this class is only used to read
 *   @see org.apache.poi.hssf.record.common.ExtRst blocks of a UnicodeString.
 *
 * </p>
 */
public class ContinuableRecordInput implements LittleEndianInput {
    private final RecordInputStream _in;

    public ContinuableRecordInput(RecordInputStream in){
        _in = in;
    }
    @Override
    public int available(){
        return _in.available();
    }

    @Override
    public byte readByte(){
        return _in.readByte();
    }

    @Override
    public int readUByte(){
        return _in.readUByte();
    }

    @Override
    public short readShort(){
        return _in.readShort();
    }

    @Override
    public int readUShort(){
        int ch1 = readUByte();
        int ch2 = readUByte();
        return (ch2 << 8) + (ch1);
    }

    @Override
    public int readInt(){
        int ch1 = _in.readUByte();
        int ch2 = _in.readUByte();
        int ch3 = _in.readUByte();
        int ch4 = _in.readUByte();
        return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1);
    }

    @Override
    public long readLong(){
        int b0 = _in.readUByte();
        int b1 = _in.readUByte();
        int b2 = _in.readUByte();
        int b3 = _in.readUByte();
        int b4 = _in.readUByte();
        int b5 = _in.readUByte();
        int b6 = _in.readUByte();
        int b7 = _in.readUByte();
        return (((long)b7 << 56) +
                ((long)b6 << 48) +
                ((long)b5 << 40) +
                ((long)b4 << 32) +
                ((long)b3 << 24) +
                (b2 << 16) +
                (b1 <<  8) +
                (b0));
    }

    @Override
    public double readDouble(){
        return _in.readDouble();
    }

    @Override
    public void readFully(byte[] buf){
        _in.readFully(buf);
    }

    @Override
    public void readFully(byte[] buf, int off, int len){
        _in.readFully(buf, off, len);
    }

    @Override
    public void readPlain(byte[] buf, int off, int len) {
        readFully(buf, off, len);
    }
}
