com.sun.syndication.io.impl.XmlFixerReader Maven / Gradle / Ivy
/*
* Copyright 2005 Sun Microsystems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.sun.syndication.io.impl;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* @author Alejandro Abdelnur
*/
public class XmlFixerReader extends Reader {
protected Reader in;
public XmlFixerReader(Reader in) {
super(in);
this.in = in;
_buffer = new StringBuffer();
_state = 0;
}
private boolean trimmed;
private StringBuffer _buffer;
private int _bufferPos;
private int _state = 0;
private boolean trimStream() throws IOException {
boolean hasContent = true;
int state = 0;
boolean loop;
int c;
do {
switch (state) {
case 0:
c = in.read();
if (c==-1) {
loop = false;
hasContent = false;
}
else
if (c==' ' || c=='\n' || c=='\r' || c=='\t') {
loop = true;
}
else
if (c=='<') {
state = 1;
_buffer.setLength(0);
_bufferPos = 0;
_buffer.append((char)c);
loop = true;
}
else {
_buffer.setLength(0);
_bufferPos = 0;
_buffer.append((char)c);
loop = false;
hasContent = true;
_state = 3;
}
break;
case 1:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c!='!') {
_buffer.append((char)c);
_state = 3;
loop = false;
hasContent = true;
_state = 3;
}
else {
_buffer.append((char)c);
state = 2;
loop = true;
}
break;
case 2:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c=='-') {
_buffer.append((char)c);
state = 3;
loop = true;
}
else {
_buffer.append((char)c);
loop = false;
hasContent = true;
_state = 3;
}
break;
case 3:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c=='-') {
_buffer.append((char)c);
state = 4;
loop = true;
}
else {
_buffer.append((char)c);
loop = false;
hasContent = true;
_state = 3;
}
break;
case 4:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c!='-') {
_buffer.append((char)c);
loop = true;
}
else {
_buffer.append((char)c);
state = 5;
loop = true;
}
break;
case 5:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c!='-') {
_buffer.append((char)c);
loop = true;
state = 4;
}
else {
_buffer.append((char)c);
state = 6;
loop = true;
}
break;
case 6:
c = in.read();
if (c==-1) {
loop = false;
hasContent = true;
_state = 3;
}
else
if (c!='>') {
_buffer.append((char)c);
loop = true;
state = 4;
}
else {
_buffer.setLength(0);
state = 0;
loop = true;
}
break;
default:
throw new IOException("It shouldn't happen");
}
} while (loop);
return hasContent;
}
public int read() throws IOException {
boolean loop;
if (!trimmed) { // trims XML stream
trimmed = true;
if (!trimStream()) {
return -1;
}
}
int c;
do { // converts literal entities to coded entities
switch (_state) {
case 0: // reading chars from stream
c = in.read();
if (c>-1) {
if (c=='&') {
_state = 1;
_buffer.setLength(0);
_bufferPos = 0;
_buffer.append((char)c);
_state = 1;
loop = true;
}
else {
loop = false;
}
}
else {
loop = false;
}
break;
case 1: // reading entity from stream
c = in.read();
if (c>-1) {
if (c==';') {
_buffer.append((char)c);
_state = 2;
loop = true;
}
else
if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c=='#') || (c>='0' && c<='9')) {
_buffer.append((char)c);
loop = true;
}
else {
// no ';' to match the '&' lets just make the '&'
// a legal xml character entity '&'
_buffer.insert(1, "amp;");
_buffer.append((char)c);
_state = 3;
loop = true;
}
}
else {
// no ';' to match the '&' lets just make the '&'
// a legal xml character entity '&'
_buffer.insert(1, "amp;");
_state = 3;
loop = true;
}
break;
case 2: // replacing entity
c = 0;
String literalEntity = _buffer.toString();
String codedEntity = (String) CODED_ENTITIES.get(literalEntity);
if (codedEntity!=null) {
_buffer.setLength(0);
_buffer.append(codedEntity);
} // else we leave what was in the stream
_state = 3;
loop = true;
break;
case 3: // consuming buffer
if (_bufferPos<_buffer.length()) {
c = _buffer.charAt(_bufferPos++);
loop = false;
}
else {
c = 0;
_state = 0;
loop = true;
}
break;
default:
throw new IOException("It shouldn't happen");
}
} while (loop);
return c;
}
public int read(char[] buffer,int offset,int len) throws IOException {
int charsRead = 0;
int c = read();
if (c==-1) {
return -1;
}
buffer[offset+(charsRead++)] = (char) c;
while (charsRead-1) {
buffer[offset+(charsRead++)] = (char) c;
}
return charsRead;
}
public long skip(long n) throws IOException {
if (n==0) {
return 0;
}
else
if (n<0) {
throw new IllegalArgumentException("'n' cannot be negative");
}
int c = read();
long counter = 1;
while (c>-1 && counterpos) {
sb.append(s.substring(pos,b));
pos = b;
}
chunck = s.substring(pos,e);
String codedEntity = (String) CODED_ENTITIES.get(chunck);
if (codedEntity==null) {
codedEntity = chunck;
}
sb.append(codedEntity);
pos = e;
}
else {
sb.append(chunck);
pos += chunck.length();
}
}
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy