/* * 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.chans.infinity; import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import nya.miku.wishmaster.api.models.SimpleBoardModel; public class InfinityBoardsListReader implements Closeable { private final Reader _in; private final StringBuilder buf = new StringBuilder(); private final static int MAX_BOARDS_COUNT = 150; private static final char[][] FILTERS = { "\"uri\":\"".toCharArray(), "\"title\":\"".toCharArray(), "\"sfw\":\"0\"".toCharArray(), }; public InfinityBoardsListReader(Reader reader) { _in = reader; } public InfinityBoardsListReader(InputStream in) { this(new BufferedReader(new InputStreamReader(in))); } public SimpleBoardModel[] readBoardsList() throws IOException { ArrayList<SimpleBoardModel> list = new ArrayList<>(); SimpleBoardModel current = new SimpleBoardModel(); int filtersCount = FILTERS.length; int[] pos = new int[filtersCount]; int[] len = new int[filtersCount]; for (int i=0; i<filtersCount; ++i) len[i] = FILTERS[i].length; int curChar; while ((curChar = _in.read()) != -1) { if (curChar == '}') { list.add(current); if (list.size() == MAX_BOARDS_COUNT) break; current = new SimpleBoardModel(); } for (int i=0; i<filtersCount; ++i) { if (curChar == FILTERS[i][pos[i]]) { ++pos[i]; if (pos[i] == len[i]) { switch (i) { case 0: current.boardName = readJsonString(); break; case 1: current.boardDescription = readJsonString(); break; case 2: current.nsfw = true; } pos[i] = 0; } } else { if (pos[i] != 0) pos[i] = curChar == FILTERS[i][0] ? 1 : 0; } } } return list.toArray(new SimpleBoardModel[list.size()]); } private String readJsonString() throws IOException { int curChar; while ((curChar = _in.read()) != -1) { if (curChar == '"') { break; } else if (curChar == '\\') { curChar = _in.read(); switch (curChar) { case 'b': buf.append('\b'); break; case 't': buf.append('\t'); break; case 'n': buf.append('\n'); break; case 'f': buf.append('\f'); break; case 'r': buf.append('\r'); break; case '"': case '\'': case '\\': case '/': buf.append((char) curChar); break; case 'u': char[] unicode = new char[4]; _in.read(unicode); buf.append((char)Integer.parseInt(String.valueOf(unicode), 16)); break; } } else { buf.append((char) curChar); } } String result = buf.toString(); buf.setLength(0); return result; } @Override public void close() throws IOException { _in.close(); } }