package at.gv.egiz.asic.impl; import java.io.IOException; import java.io.InputStream; /** * Created by afitzek on 6/15/16. */ public class ZipCommentReaderStream extends InputStream { private final InputStream inputStream; private final int[] tempBuffer = new int[22]; private int[] commentBuffer = null; private int commentBufferContentLen = 0; private int commentBufferContentOff = 0; private int tempBufferContentLen = 0; private int tempBufferContentOff = 0; private String fileComment = null; private static final byte[] directoryRecord = new byte[] { (byte) 0x50, (byte) 0x4b, 0x05, 0x06 }; public ZipCommentReaderStream(InputStream inputStream) { this.inputStream = inputStream; } private int readIntIntoBuffer() throws IOException { final int tValue = this.inputStream.read(); if (this.tempBuffer.length <= tempBufferContentOff) { throw new IOException("Temp Buffer is out of space! @ " + tempBufferContentOff); } this.tempBuffer[tempBufferContentOff] = tValue; tempBufferContentOff++; tempBufferContentLen++; return tValue; } private int readIntIntoCommentBuffer() throws IOException { final int tValue = this.inputStream.read(); if (this.commentBuffer.length <= commentBufferContentOff) { throw new IOException("Comment Buffer is out of space! @ " + commentBufferContentOff); } this.commentBuffer[commentBufferContentOff] = tValue; commentBufferContentOff++; commentBufferContentLen++; return tValue; } private void checkMagicBytes() throws IOException { boolean foundMagic = true; tempBufferContentOff = 0; tempBufferContentLen = 0; for (int i = 1; i < directoryRecord.length; i++) { final int tValue = readIntIntoBuffer(); if (tValue != directoryRecord[i]) { foundMagic = false; break; } if (tValue < 0) { // Found EOF return; } } if (foundMagic) { // read input stream until comment length for (int i = 0; i < 16; i++) { final int tValue = readIntIntoBuffer(); if (tValue < 0) { // Found EOF return; } } final int commentlengthHigh = readIntIntoBuffer(); if (commentlengthHigh < 0) { // Found EOF return; } final int commentlengthLow = readIntIntoBuffer(); if (commentlengthLow < 0) { // Found EOF return; } final int commentLength = commentlengthLow * 255 + commentlengthHigh; if (commentLength == 0) { return; } this.commentBuffer = new int[commentLength]; commentBufferContentOff = 0; commentBufferContentLen = 0; // read comment buffer string for (int i = 0; i < commentLength; i++) { final int tValue = readIntIntoCommentBuffer(); if (tValue < 0) { // Found EOF return; } } final byte[] stringBuffer = new byte[this.commentBuffer.length]; for (int i = 0; i < stringBuffer.length; i++) { stringBuffer[i] = (byte) this.commentBuffer[i]; } this.fileComment = new String(stringBuffer); } } @Override public int read() throws IOException { int value = -1; if (tempBufferContentLen > 0) { value = this.tempBuffer[tempBufferContentOff]; tempBufferContentOff++; // reset temp buffer if (tempBufferContentOff >= tempBufferContentLen) { tempBufferContentOff = 0; tempBufferContentLen = 0; } return value; } if (this.commentBuffer != null) { value = this.commentBuffer[commentBufferContentOff]; commentBufferContentOff++; // reset comment buffer if (commentBufferContentOff >= commentBufferContentLen) { commentBufferContentOff = 0; commentBufferContentLen = 0; this.commentBuffer = null; } return value; } value = this.inputStream.read(); if (value == directoryRecord[0] && this.fileComment == null) { // might have found start of magic bytes checkMagicBytes(); // reset buffer offsets tempBufferContentOff = 0; commentBufferContentOff = 0; } return value; } public String getFileComment() { return this.fileComment; } }