/*
This file is part of RouteConverter.
RouteConverter is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
RouteConverter 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with RouteConverter; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 2007 Christian Pesch. All Rights Reserved.
*/
package slash.common.io;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
import java.nio.CharBuffer;
/**
* A reader that replaces tokens.
*
* Based on http://tutorials.jenkov.com/java-howto/replace-strings-in-streams-arrays-files.html
*
* @author Jakob Jenkov
*/
class TokenReplacingReader extends Reader {
private PushbackReader pushbackReader;
private TokenResolver tokenResolver;
private StringBuilder tokenNameBuffer = new StringBuilder();
private String tokenValue = null;
private int tokenValueIndex = 0;
TokenReplacingReader(Reader source, TokenResolver resolver) {
this.pushbackReader = new PushbackReader(source, 2);
this.tokenResolver = resolver;
}
public int read(CharBuffer target) throws IOException {
throw new UnsupportedOperationException();
}
public int read() throws IOException {
if (tokenValue != null) {
if (tokenValueIndex < tokenValue.length()) {
return tokenValue.charAt(tokenValueIndex++);
}
if (tokenValueIndex == tokenValue.length()) {
tokenValue = null;
tokenValueIndex = 0;
}
}
int data = pushbackReader.read();
if (data != '$')
return data;
data = pushbackReader.read();
if (data != '{') {
pushbackReader.unread(data);
return '$';
}
tokenNameBuffer.delete(0, tokenNameBuffer.length());
data = pushbackReader.read();
while (data != '}') {
tokenNameBuffer.append((char) data);
data = pushbackReader.read();
}
tokenValue = tokenResolver.resolveToken(tokenNameBuffer.toString());
if (tokenValue == null)
tokenValue = "${" + tokenNameBuffer.toString() + "}";
// token replaces to empty string
else if (tokenValueIndex >= tokenValue.length())
tokenValue = " ";
return tokenValue.charAt(tokenValueIndex++);
}
public int read(char cbuf[], int off, int len) throws IOException {
int charsRead = -1;
for (int i = 0; i < len; i++) {
int nextChar = read();
if (nextChar == -1) {
break;
}
charsRead = i + 1;
cbuf[off + i] = (char) nextChar;
}
return charsRead;
}
public void close() throws IOException {
pushbackReader.close();
}
public long skip(long n) throws IOException {
throw new UnsupportedOperationException();
}
public boolean ready() throws IOException {
return pushbackReader.ready();
}
public boolean markSupported() {
return false;
}
public void mark(int readAheadLimit) throws IOException {
throw new UnsupportedOperationException();
}
public void reset() throws IOException {
throw new UnsupportedOperationException();
}
}