Package SevenZip.Archive.SevenZip

Source Code of SevenZip.Archive.SevenZip.InStream

package SevenZip.Archive.SevenZip;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Vector;

import Common.BoolVector;
import Common.IntVector;

import SevenZip.IInStream;
import SevenZip.Common.StreamUtils;

public class InStream {
   
  public static final int kNumMax   = 0x7FFFFFFF;
   
    final IInStream stream;
   
    private final Vector _inByteVector = new Vector();
    private /* TODO: final */ InByte2 _inByteBack = null;
   
    final long archiveBeginStreamPosition;
    long position;
   
    public InStream(IInStream stream, long searchHeaderSizeLimit) throws IOException {
        this.stream = stream;
        this.position = stream.Seek(0, IInStream.STREAM_SEEK_CUR);
        this.archiveBeginStreamPosition = FindAndReadSignature(searchHeaderSizeLimit);
    }
   
    private long FindAndReadSignature(
            long searchHeaderSizeLimit) throws IOException {
       
        this.stream.Seek(this.position, IInStream.STREAM_SEEK_SET);
       
        byte[] signature = new byte[Header.kSignatureSize];
       
        int processedSize = ReadDirect(this.stream, signature, 0, Header.kSignatureSize);
        if (processedSize != Header.kSignatureSize)
            throw new IOException("detected illegal signature length: " + processedSize + " at byte " + this.position);
       
        if (TestSignatureCandidate(signature, 0))
            return this.position;
       
        // SFX support
        final int kBufferSize = 1 << 16;
        byte [] buffer = new byte[kBufferSize];
        int numPrevBytes = Header.kSignatureSize - 1;
       
        System.arraycopy(signature, 1, buffer, 0, numPrevBytes);
       
        long curTestPos = this.position + 1;
        while (searchHeaderSizeLimit == -1 ||
            curTestPos - this.position <= searchHeaderSizeLimit) {
           
          int numReadBytes = kBufferSize - numPrevBytes;
            processedSize = ReadDirect(this.stream, buffer, numPrevBytes, numReadBytes);
            if (processedSize == -1)
              throw new IOException("unexpected EOF during search for signature");
           
            int numBytesInBuffer = numPrevBytes + processedSize;
            if (numBytesInBuffer < Header.kSignatureSize)
                throw new IOException("detected illegal signature length: " + numBytesInBuffer + " at byte " + this.position);
           
            int numTests = numBytesInBuffer - Header.kSignatureSize + 1;
            for (int pos=0; pos<numTests; pos++, curTestPos++) {
                if (TestSignatureCandidate(buffer, pos)) {
                    this.position = curTestPos + Header.kSignatureSize;
                    this.stream.Seek(this.position, IInStream.STREAM_SEEK_SET);
                    return curTestPos;
                }
            }
            numPrevBytes = numBytesInBuffer - numTests;
            System.arraycopy(buffer, numTests, buffer, 0, numPrevBytes);
        }
       
        throw new IOException("signature not found within the given " + searchHeaderSizeLimit + " bytes");
    }
   
    public void AddByteStream(byte [] buffer, int size) {
        this._inByteVector.add(this._inByteBack = new InByte2(buffer, size));
    }
   
    public void DeleteByteStream() {
        this._inByteVector.removeElementAt(this._inByteVector.size() - 1);
        if (!this._inByteVector.isEmpty())
            this._inByteBack = (InByte2)this._inByteVector.lastElement();
    }
   
    public static boolean TestSignatureCandidate(byte[] testBytes, int off) {
      if (off == 0)
        return Arrays.equals(testBytes, Header.kSignature);
        for (int i=0; i<Header.kSignatureSize; i++) {
            // System.out.println(" " + i + ":" + testBytes[i] + " " + kSignature[i]);
            if (testBytes[i + off] != Header.kSignature[i])
                return false;
        }
        return true;
    }
   
    public int ReadDirect(
        IInStream stream,
            byte[] data,
            int off,
            int size) throws IOException {
        int realProcessedSize = StreamUtils.ReadStream(stream, data, off, size);
        if (realProcessedSize != -1)
          this.position += realProcessedSize;
        return realProcessedSize;
    }
   
    public int ReadDirect(byte[] data, int size) throws IOException {
        return ReadDirect(this.stream, data, 0, size);
    }
   
    public boolean SafeReadDirect(byte[] data, int size) throws IOException {
      return (ReadDirect(data, size) == size);
    }
   
    public int SafeReadDirectUInt32() throws IOException {
        int val = 0;
        byte[] b = new byte[4];
       
        int realProcessedSize = ReadDirect(b, 4);
        if (realProcessedSize != 4)
            throw new IOException("Unexpected End Of Archive"); // throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
       
        for (int i = 0; i < 4; i++)
            val |= (b[i] & 0xFF) << (8 * i);
        return val;
    }
   
    public int ReadUInt32() throws IOException {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int b = ReadByte();
            value |= ((b) << (8 * i));
        }
        return value;
    }
   
    public long ReadUInt64() throws IOException {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            int b = ReadByte();
            value |= (((long)b) << (8 * i));
        }
        return value;
    }
   
    public boolean ReadBytes(byte data[], int sizethrows IOException {
        return this._inByteBack.ReadBytes(data, size);
    }
   
    public boolean ReadBytes(ByteArrayOutputStream baos, int size) throws IOException {
      return this._inByteBack.readBytes(baos, size) == size;
    }
   
    public int ReadByte()  throws IOException {
        return this._inByteBack.ReadByte();
    }
   
    public long SafeReadDirectUInt64() throws IOException {
        long val = 0;
        byte [] b = new byte[8];
       
        int realProcessedSize = ReadDirect(b, 8);
        if (realProcessedSize != 8)
            throw new IOException("Unexpected End Of Archive"); // throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
       
        for (int i = 0; i < 8; i++) {
            val |= ((long)(b[i] & 0xFF) << (8 * i));
        }
        return val;
    }
   
    public char ReadWideCharLE()   throws IOException {
        int b1 = this._inByteBack.ReadByte();
        int b2 = this._inByteBack.ReadByte();
        char c = (char)(((char)(b2) << 8) + b1);
        return c;
    }
   
    public long ReadNumber() throws IOException {
        int firstByte = ReadByte();
       
        int mask = 0x80;
        long value = 0;
        for (int i = 0; i < 8; i++) {
            if ((firstByte & mask) == 0) {
                long highPart = firstByte & (mask - 1);
                value += (highPart << (i * 8));
                return value;
            }
            int b = ReadByte();
            if (b < 0)
                throw new IOException("ReadNumber - Can't read stream");
           
            value |= (((long)b) << (8 * i));
            mask >>= 1;
        }
        return value;
    }
   
    public int ReadNum()  throws IOException { // CNum
        long value64 = ReadNumber();
        if (value64 > InStream.kNumMax)
            throw new IOException("ReadNum - value > CNum.kNumMax"); // return E_FAIL;
       
        return (int)value64;
    }
   
    public long ReadID() throws IOException {
        return ReadNumber();
    }
   
    public void SkeepData(long size) throws IOException {
        for (long i = 0; i < size; i++)
            ReadByte();
    }
   
    public void SkeepData() throws IOException {
        long size = ReadNumber();
        SkeepData(size);
    }
   
    public void skipToAttribute(long attribute) throws IOException {
        long type;
      while ((type = ReadID()) != attribute) {
            if (type == Header.NID.kEnd)
                throw new IOException("unexpected end of archive");
            SkeepData();
        }
    }
   
    public void close() throws IOException {
        if (this.stream != null) this.stream.close(); // _stream.Release();
    }
   
    public BoolVector ReadBoolVector(int numItems) throws IOException {
        BoolVector v = new BoolVector(numItems);
        int b = 0;
        int mask = 0;
        for (int i=0; i<numItems; i++) {
            if (mask == 0) {
                b = ReadByte();
                mask = 0x80;
            }
            v.add((b & mask) != 0);
            mask >>= 1;
        }
        return v;
    }
   
    public BoolVector ReadBoolVector2(int numItemsthrows IOException { // CBoolVector
        int allAreDefined = ReadByte();
        if (allAreDefined == 0)
            return ReadBoolVector(numItems);
        BoolVector v = new BoolVector(numItems);
        for (int i = 0; i < numItems; i++)
            v.add(true);
        return v;
    }
   
    public IntVector ReadHashDigests(
        int numItems,
            BoolVector digestsDefined) throws IOException {
        digestsDefined.setBoolVector(ReadBoolVector2(numItems));
        final IntVector digests = new IntVector(numItems);
        digests.clear();
        digests.Reserve(numItems);
        for (int i=0; i<numItems; i++) {
            int crc = 0;
            if (digestsDefined.get(i))
                crc = ReadUInt32();
            digests.add(crc);
        }
        return digests;
    }
   
    public static final long SECS_BETWEEN_EPOCHS = 11644473600L;
    public static final long SECS_TO_100NS = 10000000L; /* 10^7 */
   
    public static long FileTimeToLong(int dwHighDateTime, int dwLowDateTime) {
        // The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1
        long tm = dwHighDateTime;
        tm <<=32;
        tm |= (dwLowDateTime & 0xFFFFFFFFL);
        return (tm - (SECS_BETWEEN_EPOCHS * SECS_TO_100NS)) / (10000L); /* now convert to milliseconds */
    }
}
TOP

Related Classes of SevenZip.Archive.SevenZip.InStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.