/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library 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 library 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.
*/
package com.liferay.portal.security.xml;
import com.liferay.portal.kernel.util.ArrayUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
/**
* @author Tomas Polesovsky
*/
public class StripDoctypeFilter {
public StripDoctypeFilter(InputStream inputStream) {
this(inputStream, null);
}
public StripDoctypeFilter(Reader reader) {
this(null, reader);
}
public int read() throws IOException {
if (_bufferLength > 0) {
return readFromBuffer();
}
int c = readFromSource();
if (_documentStarted) {
return c;
}
if (c == '<') {
int[] buffer = new int[2];
buffer[0] = readFromSource();
buffer[1] = readFromSource();
if (buffer[0] == '?') {
setBuffer(buffer);
return c;
}
if ((buffer[0] == '!') && (buffer[1] == '-')) {
setBuffer(buffer);
return c;
}
if ((buffer[0] == '!') && (buffer[1] == 'D')) {
while (true) {
int doctypeContent = readFromSource();
if (doctypeContent == '[') {
_entityDeclaration = true;
}
else if (doctypeContent == ']') {
_entityDeclaration = false;
}
else if (doctypeContent == '>') {
if (!_entityDeclaration) {
_documentStarted = true;
return readFromSource();
}
}
}
}
setBuffer(buffer);
_documentStarted = true;
}
return c;
}
public int read(byte[] bytes, int offset, int length) throws IOException {
if (_documentStarted && (length > _bufferLength)) {
int bufferLength = _bufferLength;
for (int i = 0; i < bufferLength; i++) {
bytes[offset++] = (byte)(readFromBuffer() & 0xFF);
}
return _inputStream.read(bytes, offset, length - bufferLength) +
bufferLength;
}
int read = 0;
for (read = 0; read < length; read++) {
int c = read();
if (c == -1) {
if (read == 0) {
return -1;
}
return read;
}
bytes[offset + read] = (byte)(c & 0xFF);
}
return read;
}
public int read(char[] chars, int offset, int length) throws IOException {
if (_documentStarted && (length > _bufferLength)) {
int bufferLength = _bufferLength;
for (int i = 0; i < bufferLength; i++) {
chars[offset++] = (char)readFromBuffer();
}
return _reader.read(chars, offset, length - bufferLength) +
bufferLength;
}
int read = 0;
for (read = 0; read < length; read++) {
int c = read();
if (c == -1) {
if (read == 0) {
return -1;
}
return read;
}
chars[offset + read] = (char)c;
}
return read;
}
protected StripDoctypeFilter(InputStream inputStream, Reader reader) {
_inputStream = inputStream;
_reader = reader;
}
protected int readFromBuffer() {
_bufferLength--;
return _buffer[_bufferLength];
}
protected int readFromSource() throws IOException {
if (_inputStream != null) {
return _inputStream.read();
}
if (_reader != null) {
return _reader.read();
}
throw new IllegalStateException("No underlying source available");
}
protected void setBuffer(int[] buffer) {
_buffer = buffer;
ArrayUtil.reverse(_buffer);
_bufferLength = _buffer.length;
}
private int[] _buffer;
private int _bufferLength;
private boolean _documentStarted;
private boolean _entityDeclaration;
private final InputStream _inputStream;
private final Reader _reader;
}