%PDF- %PDF-
Direktori : /home/waritko/yacy/libbuild/J7Zip-modified/src/SevenZip/Archive/SevenZip/ |
Current File : //home/waritko/yacy/libbuild/J7Zip-modified/src/SevenZip/Archive/SevenZip/InStream.java |
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 size) throws 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 numItems) throws 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 */ } }