org.richfaces.request.ByteSequenceMatcher Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.request;
import java.io.IOException;
import java.io.InputStream;
public class ByteSequenceMatcher {
public interface BytesHandler {
void handle(byte[] bytes, int length) throws IOException;
}
private static final int ZERO_READS_NUMBER = 20;
private byte[] buffer;
private int readLength = 0;
private int zeroReadCounter = ZERO_READS_NUMBER;
private boolean bufferEOF = false;
private boolean isEOF = false;
private boolean isMatched = false;
private InputStream inputStream;
private BytesHandler bytesHandler;
public ByteSequenceMatcher(InputStream inputStream, int bufferSize) {
this.inputStream = inputStream;
this.buffer = new byte[bufferSize];
}
public BytesHandler getBytesHandler() {
return bytesHandler;
}
public void setBytesHandler(BytesHandler bytesHandler) {
this.bytesHandler = bytesHandler;
}
protected void prefillBuffer(int usedLength) throws IOException {
if (usedLength > readLength) {
throw new IllegalArgumentException();
}
if (usedLength != readLength && usedLength != 0) {
System.arraycopy(buffer, usedLength, buffer, 0, readLength - usedLength);
}
readLength -= usedLength;
while (!bufferEOF) {
int remaining = buffer.length - readLength;
if (remaining <= 0) {
break;
}
int read = inputStream.read(buffer, readLength, remaining);
if (read > 0) {
readLength += read;
} else if (read == 0) {
--zeroReadCounter;
if (zeroReadCounter == 0) {
throw new IllegalStateException("Maximum number of zero reads reached");
}
} else if (read < 0) {
bufferEOF = true;
}
}
}
private boolean match(int startOffset, byte[]... sequences) {
int index = startOffset;
for (byte[] bs : sequences) {
for (byte b : bs) {
if (index >= readLength) {
return false;
}
if (buffer[index] != b) {
return false;
}
index++;
}
}
return true;
}
public void findSequence(int limit, byte[]... sequences) throws IOException {
isMatched = false;
int userLimit = limit;
if (userLimit <= 0) {
userLimit = Integer.MAX_VALUE;
}
prefillBuffer(0);
int sequencesLength = 0;
for (byte[] bs : sequences) {
sequencesLength += bs.length;
}
int i = 0;
while (!isMatched && i <= readLength - sequencesLength) {
if (match(i, sequences)) {
isMatched = true;
bytesHandler.handle(buffer, i);
prefillBuffer(i + sequencesLength);
} else {
int sequenceLimit = readLength - sequencesLength + 1;
int realLimit;
if (sequenceLimit < userLimit) {
realLimit = sequenceLimit;
} else {
realLimit = userLimit;
}
if (realLimit > 0 && i == realLimit - 1) {
// report limit
bytesHandler.handle(buffer, realLimit);
prefillBuffer(realLimit);
i = 0;
} else {
i++;
}
}
}
flushUnmatchedBytes();
if (this.readLength == 0) {
this.isEOF = true;
}
}
private void flushUnmatchedBytes() throws IOException {
if (!isMatched) {
if (readLength > 0) {
bytesHandler.handle(buffer, readLength);
prefillBuffer(readLength);
}
}
}
public boolean isEOF() {
return isEOF;
}
public boolean isMatched() {
return isMatched;
}
public boolean isMatchedAndNotEOF() {
return isMatched() && !isEOF();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy