package at.gv.egiz.asic.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; /** * Created by afitzek on 6/15/16. */ public class ZipCommentReaderStream extends InputStream { private InputStream inputStream; private 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 { 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 { 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++) { 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++) { int tValue = readIntIntoBuffer(); if(tValue < 0) { // Found EOF return; } } int commentlengthHigh = readIntIntoBuffer(); if(commentlengthHigh < 0) { // Found EOF return; } int commentlengthLow = readIntIntoBuffer(); if(commentlengthLow < 0) { // Found EOF return; } 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++) { int tValue = readIntIntoCommentBuffer(); if(tValue < 0) { // Found EOF return; } } 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; } }