Move to a parser combinator
.idea/gradle.xml
| 4 | 4 | <component name="GradleSettings"> | |
| 5 | 5 | <option name="linkedExternalProjectsSettings"> | |
| 6 | 6 | <GradleProjectSettings> | |
| 7 | - | <option name="testRunner" value="PLATFORM" /> | |
| 7 | + | <option name="testRunner" value="GRADLE" /> | |
| 8 | 8 | <option name="distributionType" value="DEFAULT_WRAPPED" /> | |
| 9 | 9 | <option name="externalProjectPath" value="$PROJECT_DIR$" /> | |
| 10 | 10 | <option name="modules"> | |
… | |||
| 14 | 14 | <option value="$PROJECT_DIR$/rubytextview" /> | |
| 15 | 15 | </set> | |
| 16 | 16 | </option> | |
| 17 | - | <option name="resolveModulePerSourceSet" value="false" /> | |
| 18 | 17 | </GradleProjectSettings> | |
| 19 | 18 | </option> | |
| 20 | 19 | </component> | |
.idea/runConfigurations.xml unknown status 2
| 1 | - | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | - | <project version="4"> | |
| 3 | - | <component name="RunConfigurationProducerService"> | |
| 4 | - | <option name="ignoredProducers"> | |
| 5 | - | <set> | |
| 6 | - | <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> | |
| 7 | - | <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> | |
| 8 | - | <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> | |
| 9 | - | </set> | |
| 10 | - | </option> | |
| 11 | - | </component> | |
| 12 | - | </project> | |
| 12 | > | ||
| 13 | 0 | > | \ No newline at end of file |
app/src/main/java/eu/lepiller/nani/dictionary/DictionaryFactory.java
| 256 | 256 | for(Dictionary d: dictionaries) { | |
| 257 | 257 | if (d instanceof ResultDictionary && d.isDownloaded()) { | |
| 258 | 258 | available++; | |
| 259 | - | ArrayList<Result> dr = ((ResultDictionary) d).search(text); | |
| 259 | + | List<Result> dr = ((ResultDictionary) d).search(text); | |
| 260 | 260 | if(dr != null) { | |
| 261 | 261 | for(Result r: dr) { | |
| 262 | 262 | try { |
app/src/main/java/eu/lepiller/nani/dictionary/FileDictionary.java
| 9 | 9 | import java.io.RandomAccessFile; | |
| 10 | 10 | import java.util.ArrayList; | |
| 11 | 11 | import java.util.HashMap; | |
| 12 | + | import java.util.List; | |
| 12 | 13 | import java.util.Map; | |
| 13 | 14 | ||
| 14 | 15 | public abstract class FileDictionary extends Dictionary { | |
… | |||
| 31 | 32 | } | |
| 32 | 33 | } | |
| 33 | 34 | ||
| 34 | - | interface TrieValsDecoder<T> { | |
| 35 | - | T decodeVals(RandomAccessFile file, long pos) throws IOException; | |
| 36 | - | void skipVals(RandomAccessFile file, long pos) throws IOException; | |
| 35 | + | static abstract class Parser<T> { | |
| 36 | + | abstract T parse(RandomAccessFile file) throws IOException; | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | static abstract class TrieParser<T> { | |
| 40 | + | protected Parser<T> valParser; | |
| 41 | + | TrieParser(Parser<T> parser) { | |
| 42 | + | valParser = parser; | |
| 43 | + | } | |
| 44 | + | ||
| 45 | + | final T decodeVals(RandomAccessFile file, long pos) throws IOException { | |
| 46 | + | seek(file, pos); | |
| 47 | + | Log.d(TAG, "if it's a list, it has " + file.readShort() + " elements."); | |
| 48 | + | seek(file, pos); | |
| 49 | + | return valParser.parse(file); | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | void seek(RandomAccessFile file, long pos) throws IOException { | |
| 53 | + | file.seek(pos); | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | abstract void skipVals(RandomAccessFile file, long pos) throws IOException; | |
| 37 | 57 | } | |
| 38 | 58 | ||
| 39 | 59 | private final String mUrl; | |
… | |||
| 142 | 162 | return 0; | |
| 143 | 163 | } | |
| 144 | 164 | ||
| 145 | - | static String getString(RandomAccessFile file) throws IOException { | |
| 146 | - | byte b; | |
| 147 | - | ArrayList<Byte> bs = new ArrayList<>(); | |
| 148 | - | while((b = file.readByte()) != 0) { | |
| 149 | - | bs.add(b); | |
| 150 | - | } | |
| 151 | - | byte[] str = new byte[bs.size()]; | |
| 152 | - | for(int j=0; j<bs.size(); j++) { | |
| 153 | - | str[j] = bs.get(j); | |
| 165 | + | static void logHuffman(Huffman h, ArrayList<Boolean> address) { | |
| 166 | + | if (h instanceof ResultDictionary.HuffmanValue) { | |
| 167 | + | Log.v(TAG, "HUFF: " + ((ResultDictionary.HuffmanValue) h).character + " -> " + address.toString()); | |
| 168 | + | } else if(h instanceof ResultDictionary.HuffmanTree) { | |
| 169 | + | ArrayList<Boolean> address_l = new ArrayList<>(address); | |
| 170 | + | address_l.add(false); | |
| 171 | + | ArrayList<Boolean> address_r = new ArrayList<>(address); | |
| 172 | + | address_r.add(true); | |
| 173 | + | logHuffman(((JMDict.HuffmanTree) h).left, address_l); | |
| 174 | + | logHuffman(((JMDict.HuffmanTree) h).right, address_r); | |
| 154 | 175 | } | |
| 155 | - | return new String(str, encoding); | |
| 156 | 176 | } | |
| 157 | 177 | ||
| 158 | - | static ArrayList<String> getStringList(RandomAccessFile file) throws IOException { | |
| 159 | - | ArrayList<String> results = new ArrayList<>(); | |
| 160 | - | int number = file.readShort(); | |
| 161 | - | for(int i=0; i<number; i++) { | |
| 162 | - | results.add(getString(file)); | |
| 178 | + | static class StringParser extends Parser<String> { | |
| 179 | + | @Override | |
| 180 | + | String parse(RandomAccessFile file) throws IOException { | |
| 181 | + | byte b; | |
| 182 | + | ArrayList<Byte> bs = new ArrayList<>(); | |
| 183 | + | while((b = file.readByte()) != 0) { | |
| 184 | + | bs.add(b); | |
| 185 | + | } | |
| 186 | + | byte[] str = new byte[bs.size()]; | |
| 187 | + | for(int j=0; j<bs.size(); j++) { | |
| 188 | + | str[j] = bs.get(j); | |
| 189 | + | } | |
| 190 | + | return new String(str, encoding); | |
| 163 | 191 | } | |
| 164 | - | return results; | |
| 165 | 192 | } | |
| 166 | 193 | ||
| 167 | - | static ArrayList<Integer> getIntList(RandomAccessFile file) throws IOException { | |
| 168 | - | ArrayList<Integer> results = new ArrayList<>(); | |
| 169 | - | int number = file.readShort(); | |
| 170 | - | for(int i=0; i<number; i++) { | |
| 171 | - | int tag = (int) file.readShort(); | |
| 172 | - | results.add(tag); | |
| 194 | + | static class ListParser<T> extends Parser<List<T>> { | |
| 195 | + | Parser<T> parser; | |
| 196 | + | int lenSize; | |
| 197 | + | ||
| 198 | + | ListParser(Parser<T> parser) { | |
| 199 | + | this(2, parser); | |
| 200 | + | } | |
| 201 | + | ListParser(int lenSize, Parser<T> parser) { | |
| 202 | + | this.parser = parser; | |
| 203 | + | this.lenSize = lenSize; | |
| 173 | 204 | } | |
| 174 | - | return results; | |
| 175 | - | } | |
| 176 | 205 | ||
| 177 | - | static Huffman loadHuffman(RandomAccessFile file) throws IOException { | |
| 178 | - | byte b = file.readByte(); | |
| 179 | - | if(b == 1) { | |
| 180 | - | Huffman left = loadHuffman(file); | |
| 181 | - | Huffman right = loadHuffman(file); | |
| 182 | - | ||
| 183 | - | return new HuffmanTree(left, right); | |
| 184 | - | } else if (b == 0) { | |
| 185 | - | Log.v(TAG, "Skipping byte " + file.readByte()); | |
| 186 | - | return new HuffmanValue(""); | |
| 187 | - | } else { | |
| 188 | - | ArrayList<Byte> bs = new ArrayList<>(); | |
| 189 | - | bs.add(b); | |
| 190 | - | while((b = file.readByte()) != 0) { | |
| 191 | - | bs.add(b); | |
| 206 | + | @Override | |
| 207 | + | List<T> parse(RandomAccessFile file) throws IOException { | |
| 208 | + | List<T> results = new ArrayList<>(); | |
| 209 | + | int number; | |
| 210 | + | switch(lenSize) { | |
| 211 | + | case 1: | |
| 212 | + | number = file.readByte(); | |
| 213 | + | break; | |
| 214 | + | case 2: | |
| 215 | + | number = file.readShort(); | |
| 216 | + | break; | |
| 217 | + | default: | |
| 218 | + | number = file.readInt(); | |
| 192 | 219 | } | |
| 193 | - | byte[] array = new byte[bs.size()]; | |
| 194 | - | for(int i=0; i<bs.size(); i++) { | |
| 195 | - | array[i] = bs.get(i); | |
| 220 | + | for(int i=0; i<number; i++) { | |
| 221 | + | Log.d("LISTPARSER", "at position " + file.getFilePointer()); | |
| 222 | + | results.add(parser.parse(file)); | |
| 196 | 223 | } | |
| 197 | - | return new HuffmanValue(new String(array, encoding)); | |
| 224 | + | return results; | |
| 198 | 225 | } | |
| 199 | 226 | } | |
| 200 | 227 | ||
| 201 | - | static String getHuffmanString(RandomAccessFile file, Huffman huffman) throws IOException { | |
| 202 | - | StringBuilder b = new StringBuilder(); | |
| 203 | - | ArrayList<Boolean> bits = new ArrayList<>(); | |
| 204 | - | String c = null; | |
| 205 | - | ResultDictionary.Huffman h = huffman; | |
| 206 | - | while(c == null || !c.isEmpty()) { | |
| 207 | - | if(h instanceof ResultDictionary.HuffmanValue) { | |
| 208 | - | c = ((ResultDictionary.HuffmanValue) h).character; | |
| 209 | - | //Log.v(TAG, "Huffman read: " + c); | |
| 210 | - | b.append(c); | |
| 211 | - | h = huffman; | |
| 212 | - | } else if(h instanceof ResultDictionary.HuffmanTree) { | |
| 213 | - | if(bits.isEmpty()) { | |
| 214 | - | byte by = file.readByte(); | |
| 215 | - | //Log.v(TAG, "Read byte for huffman: " + by); | |
| 216 | - | for(int i = 7; i>-1; i--) { | |
| 217 | - | bits.add((by&(1<<i))!=0); | |
| 218 | - | } | |
| 219 | - | //Log.v(TAG, "Read byte for huffman: " + bits); | |
| 220 | - | } | |
| 228 | + | static class HuffmanParser extends Parser<Huffman> { | |
| 229 | + | ||
| 230 | + | @Override | |
| 231 | + | Huffman parse(RandomAccessFile file) throws IOException { | |
| 232 | + | byte b = file.readByte(); | |
| 233 | + | if(b == 1) { | |
| 234 | + | Huffman left = new HuffmanParser().parse(file); | |
| 235 | + | Huffman right = new HuffmanParser().parse(file); | |
| 221 | 236 | ||
| 222 | - | Boolean bo = bits.get(0); | |
| 223 | - | bits.remove(0); | |
| 224 | - | h = bo? ((ResultDictionary.HuffmanTree) h).right: ((ResultDictionary.HuffmanTree) h).left; | |
| 237 | + | return new HuffmanTree(left, right); | |
| 238 | + | } else if (b == 0) { | |
| 239 | + | Log.v(TAG, "Skipping byte " + file.readByte()); | |
| 240 | + | return new HuffmanValue(""); | |
| 241 | + | } else { | |
| 242 | + | ArrayList<Byte> bs = new ArrayList<>(); | |
| 243 | + | bs.add(b); | |
| 244 | + | while((b = file.readByte()) != 0) { | |
| 245 | + | bs.add(b); | |
| 246 | + | } | |
| 247 | + | byte[] array = new byte[bs.size()]; | |
| 248 | + | for(int i=0; i<bs.size(); i++) { | |
| 249 | + | array[i] = bs.get(i); | |
| 250 | + | } | |
| 251 | + | return new HuffmanValue(new String(array, encoding)); | |
| 225 | 252 | } | |
| 226 | 253 | } | |
| 227 | - | ||
| 228 | - | return b.toString(); | |
| 229 | 254 | } | |
| 230 | 255 | ||
| 231 | - | static void logHuffman(Huffman h, ArrayList<Boolean> address) { | |
| 232 | - | if (h instanceof ResultDictionary.HuffmanValue) { | |
| 233 | - | Log.v(TAG, "HUFF: " + ((ResultDictionary.HuffmanValue) h).character + " -> " + address.toString()); | |
| 234 | - | } else if(h instanceof ResultDictionary.HuffmanTree) { | |
| 235 | - | ArrayList<Boolean> address_l = new ArrayList<>(address); | |
| 236 | - | address_l.add(false); | |
| 237 | - | ArrayList<Boolean> address_r = new ArrayList<>(address); | |
| 238 | - | address_r.add(true); | |
| 239 | - | logHuffman(((JMDict.HuffmanTree) h).left, address_l); | |
| 240 | - | logHuffman(((JMDict.HuffmanTree) h).right, address_r); | |
| 256 | + | static class HuffmanStringParser extends Parser<String> { | |
| 257 | + | Huffman huffman; | |
| 258 | + | HuffmanStringParser(Huffman huffman) { | |
| 259 | + | this.huffman = huffman; | |
| 241 | 260 | } | |
| 242 | - | } | |
| 243 | 261 | ||
| 244 | - | static ArrayList<String> getHuffmanStringList(RandomAccessFile file, Huffman huffman) throws IOException { | |
| 245 | - | ArrayList<String> results = new ArrayList<>(); | |
| 246 | - | int number = file.readShort(); | |
| 247 | - | Log.v(TAG, "huffmanStrings: " + number); | |
| 248 | - | for(int i=0; i<number; i++) { | |
| 249 | - | results.add(getHuffmanString(file, huffman)); | |
| 262 | + | @Override | |
| 263 | + | String parse(RandomAccessFile file) throws IOException { | |
| 264 | + | StringBuilder b = new StringBuilder(); | |
| 265 | + | ArrayList<Boolean> bits = new ArrayList<>(); | |
| 266 | + | String c = null; | |
| 267 | + | ResultDictionary.Huffman h = huffman; | |
| 268 | + | while(c == null || !c.isEmpty()) { | |
| 269 | + | if(h instanceof ResultDictionary.HuffmanValue) { | |
| 270 | + | c = ((ResultDictionary.HuffmanValue) h).character; | |
| 271 | + | //Log.v(TAG, "Huffman read: " + c); | |
| 272 | + | b.append(c); | |
| 273 | + | h = huffman; | |
| 274 | + | } else if(h instanceof ResultDictionary.HuffmanTree) { | |
| 275 | + | if(bits.isEmpty()) { | |
| 276 | + | byte by = file.readByte(); | |
| 277 | + | //Log.v(TAG, "Read byte for huffman: " + by); | |
| 278 | + | for(int i = 7; i>-1; i--) { | |
| 279 | + | bits.add((by&(1<<i))!=0); | |
| 280 | + | } | |
| 281 | + | //Log.v(TAG, "Read byte for huffman: " + bits); | |
| 282 | + | } | |
| 283 | + | ||
| 284 | + | Boolean bo = bits.get(0); | |
| 285 | + | bits.remove(0); | |
| 286 | + | h = bo? ((ResultDictionary.HuffmanTree) h).right: ((ResultDictionary.HuffmanTree) h).left; | |
| 287 | + | } | |
| 288 | + | } | |
| 289 | + | ||
| 290 | + | return b.toString(); | |
| 250 | 291 | } | |
| 251 | - | return results; | |
| 252 | 292 | } | |
| 253 | 293 | ||
| 254 | - | static<T> T searchTrie(RandomAccessFile file, long triePos, byte[] txt, TrieValsDecoder<T> decoder) throws IOException { | |
| 294 | + | static<T> T searchTrie(RandomAccessFile file, long triePos, byte[] txt, TrieParser<T> decoder) throws IOException { | |
| 255 | 295 | file.seek(triePos); | |
| 256 | 296 | if(txt.length == 0) { | |
| 257 | 297 | Log.v(TAG, "found trie value, reading values"); | |
app/src/main/java/eu/lepiller/nani/dictionary/KanjiDict.java
| 33 | 33 | return R.drawable.ic_nani_edrdg; | |
| 34 | 34 | } | |
| 35 | 35 | ||
| 36 | - | KanjiResult getValue(RandomAccessFile file, long pos, String kanji) throws IOException { | |
| 37 | - | Log.d(TAG, "getValue at " + pos); | |
| 38 | - | file.seek(pos); | |
| 39 | - | int stroke = file.readByte(); | |
| 40 | - | Log.d(TAG, "strokes: " + stroke); | |
| 41 | - | ||
| 42 | - | List<String> senses = getHuffmanStringList(file, meaningHuffman); | |
| 43 | - | List<KanjiResult.Sense> meanings = new ArrayList<>(); | |
| 44 | - | for(String s: senses) { | |
| 45 | - | meanings.add(new KanjiResult.Sense(this.getLang(), s)); | |
| 36 | + | class ResultParser extends Parser<KanjiResult> { | |
| 37 | + | String kanji; | |
| 38 | + | ResultParser(String kanji) { | |
| 39 | + | this.kanji = kanji; | |
| 46 | 40 | } | |
| 47 | - | List<String> kun = getHuffmanStringList(file, readingHuffman); | |
| 48 | - | List<String> on = getHuffmanStringList(file, readingHuffman); | |
| 49 | - | List<String> nanori = getHuffmanStringList(file, readingHuffman); | |
| 50 | 41 | ||
| 51 | - | return new KanjiResult(kanji, stroke, meanings, kun, on, nanori, null, null); | |
| 42 | + | @Override | |
| 43 | + | KanjiResult parse(RandomAccessFile file) throws IOException { | |
| 44 | + | int stroke = file.readByte(); | |
| 45 | + | Log.d(TAG, "strokes: " + stroke); | |
| 46 | + | ||
| 47 | + | List<String> senses = new ListParser<>(new HuffmanStringParser(meaningHuffman)).parse(file); | |
| 48 | + | List<KanjiResult.Sense> meanings = new ArrayList<>(); | |
| 49 | + | for(String s: senses) { | |
| 50 | + | meanings.add(new KanjiResult.Sense(KanjiDict.this.getLang(), s)); | |
| 51 | + | } | |
| 52 | + | List<String> kun = new ListParser<>(new HuffmanStringParser(readingHuffman)).parse(file); | |
| 53 | + | List<String> on = new ListParser<>(new HuffmanStringParser(readingHuffman)).parse(file); | |
| 54 | + | List<String> nanori = new ListParser<>(new HuffmanStringParser(readingHuffman)).parse(file); | |
| 55 | + | ||
| 56 | + | return new KanjiResult(kanji, stroke, meanings, kun, on, nanori, null, null); | |
| 57 | + | } | |
| 52 | 58 | } | |
| 53 | 59 | ||
| 54 | 60 | @Override | |
… | |||
| 82 | 88 | ||
| 83 | 89 | byte[] search = kanji.toLowerCase().getBytes(); | |
| 84 | 90 | file.skipBytes(4); // size | |
| 85 | - | meaningHuffman = loadHuffman(file); | |
| 86 | - | readingHuffman = loadHuffman(file); | |
| 91 | + | meaningHuffman = new HuffmanParser().parse(file); | |
| 92 | + | readingHuffman = new HuffmanParser().parse(file); | |
| 87 | 93 | long kanjiTriePos = file.getFilePointer(); | |
| 88 | 94 | ||
| 89 | 95 | Log.d(TAG, "trie pos: " + kanjiTriePos); | |
| 90 | 96 | ||
| 91 | - | return searchTrie(file, kanjiTriePos, search, new TrieValsDecoder<KanjiResult>() { | |
| 97 | + | return searchTrie(file, kanjiTriePos, search, new TrieParser<KanjiResult>(new ResultParser(kanji)) { | |
| 92 | 98 | @Override | |
| 93 | - | public KanjiResult decodeVals(RandomAccessFile file1, long pos) throws IOException { | |
| 94 | - | Log.d(TAG, "decoding val"); | |
| 99 | + | public void skipVals(RandomAccessFile file1, long pos) throws IOException { | |
| 95 | 100 | file1.seek(pos); | |
| 96 | - | return getValue(file1, file1.readInt(), kanji); | |
| 101 | + | file1.skipBytes(4); | |
| 97 | 102 | } | |
| 98 | 103 | ||
| 99 | 104 | @Override | |
| 100 | - | public void skipVals(RandomAccessFile file1, long pos) throws IOException { | |
| 101 | - | file1.seek(pos); | |
| 102 | - | file1.skipBytes(4); | |
| 105 | + | void seek(RandomAccessFile file, long pos) throws IOException { | |
| 106 | + | file.seek(pos); | |
| 107 | + | file.seek(file.readInt()); | |
| 103 | 108 | } | |
| 104 | 109 | }); | |
| 105 | 110 | } catch (FileNotFoundException e) { | |
app/src/main/java/eu/lepiller/nani/dictionary/KanjiVG.java
| 65 | 65 | ||
| 66 | 66 | byte[] search = kanji.toLowerCase().getBytes(); | |
| 67 | 67 | file.skipBytes(4); // size | |
| 68 | - | commandHuffman = loadHuffman(file); | |
| 68 | + | commandHuffman = new HuffmanParser().parse(file); | |
| 69 | 69 | long kanjiTriePos = file.getFilePointer(); | |
| 70 | 70 | ||
| 71 | 71 | Log.d(TAG, "trie pos: " + kanjiTriePos); | |
| 72 | 72 | ||
| 73 | - | return searchTrie(file, kanjiTriePos, search, new TrieValsDecoder<KanjiResult>() { | |
| 73 | + | return searchTrie(file, kanjiTriePos, search, new TrieParser<KanjiResult>(new ResultParser(kanji)) { | |
| 74 | 74 | @Override | |
| 75 | - | public KanjiResult decodeVals(RandomAccessFile file1, long pos) throws IOException { | |
| 76 | - | Log.d(TAG, "decoding val"); | |
| 75 | + | public void skipVals(RandomAccessFile file1, long pos) throws IOException { | |
| 77 | 76 | file1.seek(pos); | |
| 78 | - | return getValue(file1, file1.readInt(), kanji); | |
| 77 | + | file1.skipBytes(4); | |
| 79 | 78 | } | |
| 80 | 79 | ||
| 81 | 80 | @Override | |
| 82 | - | public void skipVals(RandomAccessFile file1, long pos) throws IOException { | |
| 83 | - | file1.seek(pos); | |
| 84 | - | file1.skipBytes(4); | |
| 81 | + | void seek(RandomAccessFile file, long pos) throws IOException { | |
| 82 | + | file.seek(pos); | |
| 83 | + | file.seek(file.readInt()); | |
| 85 | 84 | } | |
| 86 | 85 | }); | |
| 87 | 86 | } catch (FileNotFoundException e) { | |
… | |||
| 241 | 240 | } | |
| 242 | 241 | } | |
| 243 | 242 | ||
| 244 | - | KanjiResult.Stroke getStroke(RandomAccessFile file) throws IOException { | |
| 245 | - | String command = getHuffmanString(file, commandHuffman); | |
| 246 | - | String x = getHuffmanString(file, commandHuffman); | |
| 247 | - | String y = getHuffmanString(file, commandHuffman); | |
| 243 | + | class StrokeParser extends Parser<KanjiResult.Stroke> { | |
| 244 | + | @Override | |
| 245 | + | KanjiResult.Stroke parse(RandomAccessFile file) throws IOException { | |
| 246 | + | String command = new HuffmanStringParser(commandHuffman).parse(file); | |
| 247 | + | String x = new HuffmanStringParser(commandHuffman).parse(file); | |
| 248 | + | String y = new HuffmanStringParser(commandHuffman).parse(file); | |
| 248 | 249 | ||
| 249 | - | Path path = new Path(); | |
| 250 | + | Path path = new Path(); | |
| 250 | 251 | ||
| 251 | - | try { | |
| 252 | - | parsePath(path, command); | |
| 253 | - | } catch (ParseException e) { | |
| 254 | - | e.printStackTrace(); | |
| 255 | - | path.reset(); | |
| 256 | - | } | |
| 252 | + | try { | |
| 253 | + | parsePath(path, command); | |
| 254 | + | } catch (ParseException e) { | |
| 255 | + | e.printStackTrace(); | |
| 256 | + | path.reset(); | |
| 257 | + | } | |
| 257 | 258 | ||
| 258 | - | return new KanjiResult.Stroke(path, 109, Float.parseFloat(x), Float.parseFloat(y)); | |
| 259 | + | return new KanjiResult.Stroke(path, 109, Float.parseFloat(x), Float.parseFloat(y)); | |
| 260 | + | } | |
| 259 | 261 | } | |
| 260 | 262 | ||
| 261 | - | KanjiResult getValue(RandomAccessFile file, long pos, String kanji) throws IOException { | |
| 262 | - | Log.d(TAG, "getValue at " + pos); | |
| 263 | - | file.seek(pos); | |
| 264 | - | ||
| 265 | - | List<String> elements = getStringList(file); | |
| 266 | - | List<KanjiResult.Stroke> strokes = new ArrayList<>(); | |
| 267 | - | int number = file.readShort(); | |
| 268 | - | for(int i=0; i<number; i++) { | |
| 269 | - | strokes.add(getStroke(file)); | |
| 263 | + | class ResultParser extends Parser<KanjiResult> { | |
| 264 | + | String kanji; | |
| 265 | + | ResultParser(String kanji) { | |
| 266 | + | this.kanji = kanji; | |
| 270 | 267 | } | |
| 268 | + | @Override | |
| 269 | + | KanjiResult parse(RandomAccessFile file) throws IOException { | |
| 270 | + | List<String> elements = new ListParser<>(new StringParser()).parse(file); | |
| 271 | + | List<KanjiResult.Stroke> strokes = new ListParser<>(new StrokeParser()).parse(file); | |
| 271 | 272 | ||
| 272 | - | return new KanjiResult(kanji, -1, null, null, null, null, elements, strokes); | |
| 273 | + | return new KanjiResult(kanji, -1, null, null, null, null, elements, strokes); | |
| 274 | + | } | |
| 273 | 275 | } | |
| 274 | 276 | } | |
app/src/main/java/eu/lepiller/nani/dictionary/RadicalDict.java
| 38 | 38 | private void fillStrokeCount(RandomAccessFile file) throws IOException{ | |
| 39 | 39 | int size = file.readShort(); | |
| 40 | 40 | for(int i=0; i<size; i++) { | |
| 41 | - | String kanji = getString(file); | |
| 41 | + | String kanji = new StringParser().parse(file); | |
| 42 | 42 | int stroke = file.readByte(); | |
| 43 | 43 | strokeCount.put(kanji, stroke); | |
| 44 | 44 | } | |
… | |||
| 47 | 47 | private void fillRadicalStrokeCount(RandomAccessFile file) throws IOException { | |
| 48 | 48 | int size = file.readShort(); | |
| 49 | 49 | for(int i=0; i<size; i++) { | |
| 50 | - | String radical = getString(file); | |
| 50 | + | String radical = new StringParser().parse(file); | |
| 51 | 51 | int stroke = file.readByte(); | |
| 52 | 52 | ||
| 53 | 53 | radicalStrokeCount.put(radical, stroke); | |
… | |||
| 57 | 57 | private void fillRadicals(RandomAccessFile file) throws IOException { | |
| 58 | 58 | int size = file.readShort(); | |
| 59 | 59 | for(int i=0; i<size; i++) { | |
| 60 | - | String radical = getString(file); | |
| 61 | - | String kanji = getString(file); | |
| 60 | + | String radical = new StringParser().parse(file); | |
| 61 | + | String kanji = new StringParser().parse(file); | |
| 62 | 62 | List<String> lst = new ArrayList<>(); | |
| 63 | 63 | for(String s: kanji.split("")) { | |
| 64 | 64 | if(s.compareTo("") != 0) { | |
app/src/main/java/eu/lepiller/nani/dictionary/ResultDictionary.java
| 9 | 9 | import java.util.ArrayList; | |
| 10 | 10 | import java.util.Arrays; | |
| 11 | 11 | import java.util.Collections; | |
| 12 | + | import java.util.List; | |
| 12 | 13 | ||
| 13 | 14 | import eu.lepiller.nani.result.Result; | |
| 14 | 15 | ||
… | |||
| 29 | 30 | meaningHuffman = null; | |
| 30 | 31 | } | |
| 31 | 32 | ||
| 32 | - | private Result getValue(RandomAccessFile file, long pos) throws IOException { | |
| 33 | - | file.seek(pos); | |
| 34 | - | Log.v(TAG, "Getting value at " + pos); | |
| 35 | - | ArrayList<String> kanjis = getHuffmanStringList(file, kanjiHuffman); | |
| 36 | - | ||
| 37 | - | Log.v(TAG, "Getting readings"); | |
| 38 | - | ArrayList<Result.Reading> readings = new ArrayList<>(); | |
| 39 | - | int reading_number = file.readShort(); | |
| 40 | - | Log.v(TAG, reading_number + " readings."); | |
| 41 | - | for(int i=0; i<reading_number; i++) { | |
| 42 | - | ArrayList<String> reading_kanjis = getStringList(file); | |
| 33 | + | class ReadingParser extends Parser<Result.Reading> { | |
| 34 | + | @Override | |
| 35 | + | Result.Reading parse(RandomAccessFile file) throws IOException { | |
| 36 | + | List<String> reading_kanjis = new ListParser<>(new StringParser()).parse(file); | |
| 43 | 37 | Log.v(TAG, "kanjis: " + reading_kanjis); | |
| 44 | - | ArrayList<String> reading_infos = getStringList(file); | |
| 38 | + | List<String> reading_infos = new ListParser<>(new StringParser()).parse(file); | |
| 45 | 39 | Log.v(TAG, "infos: " + reading_kanjis); | |
| 46 | - | ArrayList<String> reading_readings = getHuffmanStringList(file, readingHuffman); | |
| 47 | - | Result.Reading r = new Result.Reading(reading_kanjis, reading_infos, reading_readings); | |
| 48 | - | readings.add(r); | |
| 40 | + | List<String> reading_readings = new ListParser<>(new HuffmanStringParser(readingHuffman)).parse(file); | |
| 41 | + | return new Result.Reading(reading_kanjis, reading_infos, reading_readings); | |
| 49 | 42 | } | |
| 43 | + | } | |
| 50 | 44 | ||
| 51 | - | ArrayList<Result.Sense> senses = new ArrayList<>(); | |
| 52 | - | int meaning_number = file.readShort(); | |
| 53 | - | Log.v(TAG, meaning_number + " meanings."); | |
| 54 | - | for(int i=0; i<meaning_number; i++) { | |
| 55 | - | ArrayList<String> sense_references = getStringList(file); | |
| 56 | - | ArrayList<String> sense_limits = getStringList(file); | |
| 57 | - | ArrayList<Result.Source> sense_sources = new ArrayList<>(); | |
| 58 | - | int source_number = file.readShort(); | |
| 59 | - | for(int j=0; j<source_number; j++) { | |
| 60 | - | ArrayList<String> source_content = getStringList(file); | |
| 61 | - | boolean source_wasei = file.read() != 0; | |
| 62 | - | String source_language = getString(file); | |
| 63 | - | sense_sources.add(new Result.Source(source_content, source_wasei, source_language)); | |
| 64 | - | } | |
| 65 | - | ArrayList<String> sense_infos = getHuffmanStringList(file, meaningHuffman); | |
| 66 | - | ArrayList<String> sense_glosses = getHuffmanStringList(file, meaningHuffman); | |
| 67 | - | String sense_language = getString(file); | |
| 68 | - | senses.add(new Result.Sense(sense_references, sense_limits, sense_infos, sense_sources, | |
| 69 | - | sense_glosses, sense_language)); | |
| 45 | + | static class SourceParser extends Parser<Result.Source> { | |
| 46 | + | @Override | |
| 47 | + | Result.Source parse(RandomAccessFile file) throws IOException { | |
| 48 | + | List<String> source_content = new ListParser<>(new StringParser()).parse(file); | |
| 49 | + | boolean source_wasei = file.read() != 0; | |
| 50 | + | String source_language = new StringParser().parse(file); | |
| 51 | + | return new Result.Source(source_content, source_wasei, source_language); | |
| 70 | 52 | } | |
| 53 | + | } | |
| 71 | 54 | ||
| 72 | - | int score = file.readChar(); | |
| 73 | - | return new Result(kanjis, readings, senses, score); | |
| 55 | + | class SenseParser extends Parser<Result.Sense> { | |
| 56 | + | @Override | |
| 57 | + | Result.Sense parse(RandomAccessFile file) throws IOException { | |
| 58 | + | List<String> sense_references = new ListParser<>(new StringParser()).parse(file); | |
| 59 | + | List<String> sense_limits = new ListParser<>(new StringParser()).parse(file); | |
| 60 | + | List<Result.Source> sense_sources = new ListParser<>(new SourceParser()).parse(file); | |
| 61 | + | List<String> sense_infos = new ListParser<>(new HuffmanStringParser(meaningHuffman)).parse(file); | |
| 62 | + | List<String> sense_glosses = new ListParser<>(new HuffmanStringParser(meaningHuffman)).parse(file); | |
| 63 | + | String sense_language = new StringParser().parse(file); | |
| 64 | + | return new Result.Sense(sense_references, sense_limits, sense_infos, sense_sources, | |
| 65 | + | sense_glosses, sense_language); | |
| 66 | + | } | |
| 74 | 67 | } | |
| 75 | 68 | ||
| 76 | - | private ArrayList<Integer> getValues(RandomAccessFile file, long triePos) throws IOException { | |
| 77 | - | file.seek(triePos); | |
| 78 | - | Log.v(TAG, "Getting values"); | |
| 79 | - | int valuesLength = file.readShort(); | |
| 80 | - | ArrayList<Integer> results = new ArrayList<>(); | |
| 81 | - | ArrayList<Integer> exactResults = new ArrayList<>(); | |
| 69 | + | class ResultParser extends Parser<Result> { | |
| 70 | + | @Override | |
| 71 | + | Result parse(RandomAccessFile file) throws IOException { | |
| 72 | + | List<String> kanjis = new ListParser<>(new HuffmanStringParser(kanjiHuffman)).parse(file); | |
| 82 | 73 | ||
| 83 | - | Log.v(TAG, "Number of values: " + valuesLength); | |
| 84 | - | for(int i=0; i<valuesLength; i++) { | |
| 85 | - | exactResults.add(file.readInt()); | |
| 86 | - | } | |
| 74 | + | Log.v(TAG, "Getting readings"); | |
| 75 | + | List<Result.Reading> readings = new ListParser<>(new ReadingParser()).parse(file); | |
| 87 | 76 | ||
| 88 | - | int transitionLength = file.readByte(); | |
| 89 | - | Log.v(TAG, "Number of transitions: " + transitionLength); | |
| 90 | - | int[] others = new int[transitionLength]; | |
| 91 | - | for(int i=0; i<transitionLength; i++) { | |
| 92 | - | file.skipBytes(1); | |
| 93 | - | others[i] = file.readInt(); | |
| 94 | - | } | |
| 77 | + | List<Result.Sense> senses = new ListParser<>(new SenseParser()).parse(file); | |
| 95 | 78 | ||
| 96 | - | for(int i=0; i<transitionLength; i++) { | |
| 97 | - | results.addAll(getValues(file, others[i])); | |
| 79 | + | int score = file.readChar(); | |
| 80 | + | return new Result(kanjis, readings, senses, score); | |
| 98 | 81 | } | |
| 82 | + | } | |
| 99 | 83 | ||
| 100 | - | Collections.sort(results); | |
| 101 | - | Collections.sort(exactResults); | |
| 84 | + | static class ValuesParser extends Parser<List<Integer>> { | |
| 85 | + | @Override | |
| 86 | + | List<Integer> parse(RandomAccessFile file) throws IOException { | |
| 87 | + | ArrayList<Integer> results = new ArrayList<>(); | |
| 102 | 88 | ||
| 103 | - | Log.v(TAG, "exact result size: " + exactResults.size() + ", result size: " + results.size()); | |
| 104 | - | Log.v(TAG, "exact: " + Arrays.toString(exactResults.toArray()) + ", others: " + Arrays.toString(results.toArray())); | |
| 105 | - | exactResults.addAll(results); | |
| 106 | - | return exactResults; | |
| 107 | - | } | |
| 89 | + | Log.v(TAG, "Getting values"); | |
| 90 | + | List<Integer> exactResults = new ListParser<>(new Parser<Integer>() { | |
| 91 | + | @Override | |
| 92 | + | Integer parse(RandomAccessFile file) throws IOException { | |
| 93 | + | return file.readInt(); | |
| 94 | + | } | |
| 95 | + | }).parse(file); | |
| 108 | 96 | ||
| 109 | - | private ArrayList<Integer> searchTrie(RandomAccessFile file, long triePos, byte[] txt) throws IOException { | |
| 110 | - | return searchTrie(file, triePos, txt, new TrieValsDecoder<ArrayList<Integer>>() { | |
| 111 | - | @Override | |
| 112 | - | public ArrayList<Integer> decodeVals(RandomAccessFile file, long pos) throws IOException { | |
| 113 | - | return getValues(file, pos); | |
| 97 | + | List<Integer> others = new ListParser<>(1, new Parser<Integer>() { | |
| 98 | + | @Override | |
| 99 | + | Integer parse(RandomAccessFile file) throws IOException { | |
| 100 | + | file.skipBytes(1); | |
| 101 | + | return file.readInt(); | |
| 102 | + | } | |
| 103 | + | }).parse(file); | |
| 104 | + | ||
| 105 | + | for(Integer pos: others) { | |
| 106 | + | file.seek(pos); | |
| 107 | + | results.addAll(new ValuesParser().parse(file)); | |
| 114 | 108 | } | |
| 115 | 109 | ||
| 110 | + | Collections.sort(results); | |
| 111 | + | Collections.sort(exactResults); | |
| 112 | + | ||
| 113 | + | Log.v(TAG, "exact result size: " + exactResults.size() + ", result size: " + results.size()); | |
| 114 | + | Log.v(TAG, "exact: " + Arrays.toString(exactResults.toArray()) + ", others: " + Arrays.toString(results.toArray())); | |
| 115 | + | exactResults.addAll(results); | |
| 116 | + | return exactResults; | |
| 117 | + | } | |
| 118 | + | } | |
| 119 | + | ||
| 120 | + | private List<Integer> searchTrie(RandomAccessFile file, long triePos, byte[] txt) throws IOException { | |
| 121 | + | return searchTrie(file, triePos, txt, new TrieParser<List<Integer>>(new ValuesParser()) { | |
| 116 | 122 | @Override | |
| 117 | 123 | public void skipVals(RandomAccessFile file, long pos) throws IOException { | |
| 118 | 124 | file.seek(pos); | |
… | |||
| 123 | 129 | }); | |
| 124 | 130 | } | |
| 125 | 131 | ||
| 126 | - | ArrayList<Result> search(String text) throws IncompatibleFormatException { | |
| 132 | + | List<Result> search(String text) throws IncompatibleFormatException { | |
| 127 | 133 | if (isDownloaded()) { | |
| 128 | 134 | try { | |
| 129 | 135 | RandomAccessFile file = new RandomAccessFile(getFile(), "r"); | |
… | |||
| 160 | 166 | Log.v(TAG, "reading: " + readingTriePos); | |
| 161 | 167 | Log.v(TAG, "meaning: " + meaningTriePos); | |
| 162 | 168 | ||
| 163 | - | kanjiHuffman = loadHuffman(file); | |
| 164 | - | readingHuffman = loadHuffman(file); | |
| 165 | - | meaningHuffman = loadHuffman(file); | |
| 169 | + | kanjiHuffman = new HuffmanParser().parse(file); | |
| 170 | + | readingHuffman = new HuffmanParser().parse(file); | |
| 171 | + | meaningHuffman = new HuffmanParser().parse(file); | |
| 166 | 172 | ||
| 167 | 173 | logHuffman(readingHuffman, new ArrayList<>()); | |
| 168 | 174 | ||
| 169 | 175 | // Search in Japanese, by kanji and reading | |
| 170 | 176 | Log.d(TAG, "search: by kanji and reading"); | |
| 171 | - | ArrayList<Integer> results = searchTrie(file, kanjiTriePos, search); | |
| 172 | - | ArrayList<Integer> readingResults = searchTrie(file, readingTriePos, search); | |
| 177 | + | List<Integer> results = searchTrie(file, kanjiTriePos, search); | |
| 178 | + | List<Integer> readingResults = searchTrie(file, readingTriePos, search); | |
| 173 | 179 | if(results != null && readingResults != null) | |
| 174 | 180 | results.addAll(readingResults); | |
| 175 | 181 | else if (results == null) | |
… | |||
| 185 | 191 | ||
| 186 | 192 | Log.d(TAG, results.size() + " result(s)"); | |
| 187 | 193 | ||
| 188 | - | ArrayList<Result> r = new ArrayList<>(); | |
| 189 | - | ArrayList<Integer> uniqResults = new ArrayList<>(); | |
| 194 | + | List<Result> r = new ArrayList<>(); | |
| 195 | + | List<Integer> uniqResults = new ArrayList<>(); | |
| 190 | 196 | for(Integer i: results) { | |
| 191 | 197 | if(!uniqResults.contains(i)) | |
| 192 | 198 | uniqResults.add(i); | |
… | |||
| 195 | 201 | Log.v(TAG, Arrays.toString(uniqResults.toArray())); | |
| 196 | 202 | ||
| 197 | 203 | int num = 0; | |
| 198 | - | for(int i: uniqResults) { | |
| 204 | + | for(int pos: uniqResults) { | |
| 199 | 205 | if(num > 10) | |
| 200 | 206 | break; | |
| 201 | 207 | num++; | |
| 202 | - | r.add(getValue(file, i)); | |
| 208 | + | file.seek(pos); | |
| 209 | + | r.add(new ResultParser().parse(file)); | |
| 203 | 210 | } | |
| 204 | 211 | return r; | |
| 205 | 212 | } catch (FileNotFoundException e) { | |
app/src/main/java/eu/lepiller/nani/dictionary/WadokuPitchDictionary.java
| 29 | 29 | ||
| 30 | 30 | private String findPitch(String kanji, String reading, RandomAccessFile file) throws IOException { | |
| 31 | 31 | String concat = kanji + reading; | |
| 32 | - | return searchTrie(file, triePos, concat.getBytes(), new TrieValsDecoder<String>() { | |
| 33 | - | @Override | |
| 34 | - | public String decodeVals(RandomAccessFile file, long pos) throws IOException { | |
| 35 | - | file.seek(pos); | |
| 36 | - | Log.d(TAG, "decoding at " + pos); | |
| 37 | - | return getHuffmanString(file, huffman); | |
| 38 | - | } | |
| 39 | - | ||
| 32 | + | return searchTrie(file, triePos, concat.getBytes(), new TrieParser<String>(new HuffmanStringParser(huffman)) { | |
| 40 | 33 | @Override | |
| 41 | 34 | public void skipVals(RandomAccessFile file, long pos) throws IOException { | |
| 42 | 35 | file.seek(pos); | |
| 43 | - | getHuffmanString(file, huffman); | |
| 36 | + | new HuffmanStringParser(huffman).parse(file); | |
| 44 | 37 | } | |
| 45 | 38 | }); | |
| 46 | 39 | } | |
… | |||
| 62 | 55 | // number of entries | |
| 63 | 56 | file.readInt(); | |
| 64 | 57 | ||
| 65 | - | huffman = loadHuffman(file); | |
| 58 | + | huffman = new HuffmanParser().parse(file); | |
| 66 | 59 | logHuffman(huffman, new ArrayList<>()); | |
| 67 | 60 | ||
| 68 | 61 | triePos = file.getFilePointer(); | |
app/src/main/java/eu/lepiller/nani/result/Result.java
| 14 | 14 | ||
| 15 | 15 | public class Result { | |
| 16 | 16 | public static class Source { | |
| 17 | - | private final ArrayList<String> content; | |
| 17 | + | private final List<String> content; | |
| 18 | 18 | private final boolean wasei; | |
| 19 | 19 | private final String language; | |
| 20 | 20 | ||
| 21 | - | public Source(ArrayList<String> content, boolean wasei, String language) { | |
| 21 | + | public Source(List<String> content, boolean wasei, String language) { | |
| 22 | 22 | this.content = content; | |
| 23 | 23 | this.wasei = wasei; | |
| 24 | 24 | this.language = language; | |
… | |||
| 26 | 26 | } | |
| 27 | 27 | ||
| 28 | 28 | public static class Sense { | |
| 29 | - | private final ArrayList<String> references, limits, infos, glosses; | |
| 29 | + | private final List<String> references, limits, infos, glosses; | |
| 30 | 30 | private final String language; | |
| 31 | - | private final ArrayList<Source> sources; | |
| 31 | + | private final List<Source> sources; | |
| 32 | 32 | ||
| 33 | - | public Sense(ArrayList<String> references, ArrayList<String> limits, ArrayList<String> infos, | |
| 34 | - | ArrayList<Source> sources, ArrayList<String> glosses, | |
| 33 | + | public Sense(List<String> references, List<String> limits, List<String> infos, | |
| 34 | + | List<Source> sources, List<String> glosses, | |
| 35 | 35 | String language) { | |
| 36 | 36 | this.references = references; | |
| 37 | 37 | this.limits = limits; | |
… | |||
| 41 | 41 | this.language = language; | |
| 42 | 42 | } | |
| 43 | 43 | ||
| 44 | - | public ArrayList<String> getGlosses() { | |
| 44 | + | public List<String> getGlosses() { | |
| 45 | 45 | return glosses; | |
| 46 | 46 | } | |
| 47 | 47 | ||
… | |||
| 55 | 55 | } | |
| 56 | 56 | ||
| 57 | 57 | public static class Reading { | |
| 58 | - | private final ArrayList<String> kanjis, infos, readings, pitches; | |
| 58 | + | private final List<String> kanjis, infos, readings, pitches; | |
| 59 | 59 | ||
| 60 | - | public Reading(ArrayList<String> kanjis, ArrayList<String> infos, ArrayList<String> readings) { | |
| 60 | + | public Reading(List<String> kanjis, List<String> infos, List<String> readings) { | |
| 61 | 61 | this.kanjis = kanjis; | |
| 62 | 62 | this.infos = infos; | |
| 63 | 63 | this.readings = readings; | |
… | |||
| 77 | 77 | } | |
| 78 | 78 | } | |
| 79 | 79 | ||
| 80 | - | private final ArrayList<String> kanjis; | |
| 81 | - | private final ArrayList<Reading> readings; | |
| 82 | - | private final ArrayList<Sense> senses; | |
| 80 | + | private final List<String> kanjis; | |
| 81 | + | private final List<Reading> readings; | |
| 82 | + | private final List<Sense> senses; | |
| 83 | 83 | private final int score; | |
| 84 | 84 | ||
| 85 | - | public Result(ArrayList<String> kanjis, ArrayList<Reading> readings, ArrayList<Sense> senses, int score) { | |
| 85 | + | public Result(List<String> kanjis, List<Reading> readings, List<Sense> senses, int score) { | |
| 86 | 86 | this.kanjis = kanjis; | |
| 87 | 87 | this.readings = readings; | |
| 88 | 88 | this.senses = senses; | |
… | |||
| 96 | 96 | return k; | |
| 97 | 97 | } | |
| 98 | 98 | ||
| 99 | - | public ArrayList<String> getAlternatives() { | |
| 99 | + | public List<String> getAlternatives() { | |
| 100 | 100 | return kanjis; | |
| 101 | 101 | } | |
| 102 | 102 | ||
| 103 | - | public ArrayList<Sense> getSenses() { | |
| 103 | + | public List<Sense> getSenses() { | |
| 104 | 104 | return senses; | |
| 105 | 105 | } | |
| 106 | 106 | ||
| 107 | - | public ArrayList<Reading> getReadings() { | |
| 107 | + | public List<Reading> getReadings() { | |
| 108 | 108 | return readings; | |
| 109 | 109 | } | |
| 110 | 110 | ||
| 111 | 111 | public String getReading() { | |
| 112 | 112 | String reading = ""; | |
| 113 | 113 | if(readings.size() > 0) { | |
| 114 | - | ArrayList<String> rs = readings.get(0).readings; | |
| 114 | + | List<String> rs = readings.get(0).readings; | |
| 115 | 115 | if(rs.size() > 0) | |
| 116 | 116 | reading = rs.get(0); | |
| 117 | 117 | } | |
… | |||
| 126 | 126 | ||
| 127 | 127 | public String getPitch() { | |
| 128 | 128 | if(readings.size() > 0) { | |
| 129 | - | ArrayList<String> pitches = readings.get(0).pitches; | |
| 129 | + | List<String> pitches = readings.get(0).pitches; | |
| 130 | 130 | if(pitches.size() > 0) | |
| 131 | 131 | return pitches.get(0); | |
| 132 | 132 | } | |
app/src/main/java/eu/lepiller/nani/views/KanjiStrokeView.java
| 94 | 94 | int color; | |
| 95 | 95 | int i = 0; | |
| 96 | 96 | int m = strokes.size(); | |
| 97 | - | paint.setTextSize((float)size/24); | |
| 98 | - | paint.setStyle(Paint.Style.STROKE); | |
| 97 | + | paint.setTextSize((float)size/12); | |
| 99 | 98 | for(KanjiResult.Stroke s: strokes) { | |
| 100 | 99 | color = getColor(i, m, scheme, defaultColor); | |
| 101 | 100 | paint.setColor(color); | |
| 102 | 101 | ||
| 103 | 102 | // Draw number | |
| 104 | 103 | paint.setStrokeWidth(2); | |
| 105 | - | canvas.drawText(String.valueOf(i),s.getNumX() / 109 * size, s.getNumY() / 109 * size, paint); | |
| 104 | + | paint.setStyle(Paint.Style.FILL_AND_STROKE); | |
| 105 | + | canvas.drawText(String.valueOf(i+1),s.getNumX() / 109 * size, s.getNumY() / 109 * size, paint); | |
| 106 | 106 | ||
| 107 | 107 | // Draw stroke | |
| 108 | 108 | path.set(s.getPath()); | |
… | |||
| 111 | 111 | path.transform(matrix); | |
| 112 | 112 | ||
| 113 | 113 | paint.setStrokeWidth((float)size/32); | |
| 114 | + | paint.setStyle(Paint.Style.STROKE); | |
| 114 | 115 | canvas.drawPath(path, paint); | |
| 115 | 116 | ||
| 116 | 117 | i++; | |
app/src/main/res/values/dimens.xml
| 1 | 1 | <resources> | |
| 2 | 2 | <dimen name="fab_margin">16dp</dimen> | |
| 3 | 3 | <dimen name="title_size">32sp</dimen> | |
| 4 | - | <dimen name="huge_kanji_size">64sp</dimen> | |
| 4 | + | <dimen name="huge_kanji_size">128sp</dimen> | |
| 5 | 5 | <dimen name="subtitle_size">24sp</dimen> | |
| 6 | 6 | <dimen name="normal_size">18sp</dimen> | |
| 7 | 7 | <dimen name="text_margin">16dp</dimen> |