/* * Overchan Android (Meta Imageboard Client) * Copyright (C) 2014-2016 miku-nyan <https://github.com/miku-nyan> * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package nya.miku.wishmaster.api.util; import java.io.IOException; import java.io.Reader; /** * Обёртка Reader, заменяющая при чтении одну последовательность символов на другую. * Рекомендуется использовать с буферизованным ридером (этот класс не содержит в себе буфер и читает по одному символу). * @author miku-nyan * */ public class ReplacingReader extends Reader { private final Reader in; private final CharSequence from, to; private char[] buf; private int bufCurrentLen = 0; private boolean bufReading = false; private int bufReadingPos = 0; private boolean replacementReading = false; private int replacementReadingPos = 0; /** * Конструктор * @param in исходный Reader * @param from последовательность символов, которую требуется заменять * @param to последовательность, на которую требуется заменять from */ public ReplacingReader(Reader in, CharSequence from, CharSequence to) { this.in = in; this.from = from; this.to = to; buf = new char[from.length()]; } @Override public void close() throws IOException { in.close(); } @Override public int read() throws IOException { if (replacementReading) { char fromReplacement = to.charAt(replacementReadingPos++); if (replacementReadingPos >= to.length()) { replacementReading = false; replacementReadingPos = 0; } return fromReplacement; } if (bufReading) { char fromBuf = buf[bufReadingPos++]; if (bufReadingPos >= bufCurrentLen) { bufReading = false; bufCurrentLen = 0; } return fromBuf; } bufCurrentLen = 0; int curFromPos = 0; int ch; while ((ch = in.read()) != -1) { buf[bufCurrentLen++] = (char) ch; if (ch != from.charAt(curFromPos++)) break; if (curFromPos == from.length()) { replacementReading = true; break; } } if (replacementReading) { if (to.length() > 1) { replacementReadingPos = 1; } else { replacementReading = false; } return to.charAt(0); } if (bufCurrentLen > 1) { bufReading = true; bufReadingPos = 1; } else { bufReading = false; } if (bufCurrentLen == 0) return -1; return buf[0]; } @Override public int read(char[] buffer, int offset, int count) throws IOException { int charsRead = 0; for (int i = 0; i < count; i++) { charsRead = i; int nextChar = read(); if (nextChar == -1) { break; } buffer[offset + i] = (char) nextChar; } return charsRead; } }