]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/engine/PairEntry.java
Remove last Java-deserialization based code.
[Dictionary.git] / src / com / hughes / android / dictionary / engine / PairEntry.java
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package com.hughes.android.dictionary.engine;
16
17 import java.io.DataInput;
18 import java.io.DataOutput;
19 import java.io.IOException;
20 import java.io.PrintStream;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.regex.Pattern;
25
26 import com.hughes.util.StringUtil;
27 import com.hughes.util.raf.RAFListSerializerSkippable;
28 import com.ibm.icu.text.Transliterator;
29
30 public class PairEntry extends AbstractEntry implements Comparable<PairEntry> {
31
32     public final List<Pair> pairs;
33
34     public PairEntry(final EntrySource entrySource) {
35         super(entrySource);
36         pairs = new ArrayList<>(1);
37     }
38
39     public PairEntry(final EntrySource entrySource, final String lang1, final String lang2) {
40         this(entrySource);
41         this.pairs.add(new Pair(lang1, lang2));
42     }
43
44     public PairEntry(final Dictionary dictionary, final DataInput raf, final int index)
45     throws IOException {
46         super(dictionary, raf, index);
47         final int size = dictionary.dictFileVersion >= 7 ? StringUtil.readVarInt(raf) : raf.readInt();
48         // Use singletonList for better performance in common case
49         if (size == 1) pairs = Collections.singletonList(new Pair(raf.readUTF(), raf.readUTF()));
50         else
51         {
52             pairs = new ArrayList<>(size);
53             for (int i = 0; i < size; ++i) {
54                 pairs.add(new Pair(raf.readUTF(), raf.readUTF()));
55             }
56         }
57     }
58
59     @Override
60     public void write(DataOutput raf) throws IOException {
61         super.write(raf);
62         StringUtil.writeVarInt(raf, pairs.size());
63         for (Pair p : pairs) {
64             assert p.lang1.length() > 0;
65             raf.writeUTF(p.lang1);
66             raf.writeUTF(p.lang2);
67         }
68     }
69
70     static final class Serializer implements RAFListSerializerSkippable<PairEntry> {
71
72         final Dictionary dictionary;
73
74         Serializer(Dictionary dictionary) {
75             this.dictionary = dictionary;
76         }
77
78         @Override
79         public PairEntry read(DataInput raf, int index) throws IOException {
80             return new PairEntry(dictionary, raf, index);
81         }
82
83         @Override
84         public void skip(DataInput raf, int index) throws IOException {
85             final int size;
86             if (dictionary.dictFileVersion >= 7)
87             {
88                 StringUtil.readVarInt(raf);
89                 size = StringUtil.readVarInt(raf);
90             }
91             else
92             {
93                 raf.skipBytes(2);
94                 size = raf.readInt();
95             }
96             for (int i = 0; i < 2*size; ++i) {
97                 int l = raf.readUnsignedShort();
98                 raf.skipBytes(l);
99             }
100         }
101
102         @Override
103         public void write(DataOutput raf, PairEntry t) throws IOException {
104             t.write(raf);
105         }
106     }
107
108     @Override
109     public void addToDictionary(final Dictionary dictionary) {
110         assert index == -1;
111         dictionary.pairEntries.add(this);
112         index = dictionary.pairEntries.size() - 1;
113     }
114
115     @Override
116     public RowBase CreateRow(int rowIndex, Index dictionaryIndex) {
117         return new Row(this.index, rowIndex, dictionaryIndex);
118     }
119
120     // --------------------------------------------------------------------
121
122     public static class Row extends RowBase {
123
124         Row(final DataInput raf, final int thisRowIndex,
125             final Index index, int extra) throws IOException {
126             super(raf, thisRowIndex, index, extra);
127         }
128
129         Row(final int referenceIndex, final int thisRowIndex,
130             final Index index) {
131             super(referenceIndex, thisRowIndex, index);
132         }
133
134         @Override
135         public String toString() {
136             return getRawText(false);
137         }
138
139         public PairEntry getEntry() {
140             return index.dict.pairEntries.get(referenceIndex);
141         }
142
143         @Override
144         public void print(PrintStream out) {
145             final PairEntry pairEntry = getEntry();
146             for (int i = 0; i < pairEntry.pairs.size(); ++i) {
147                 out.print((i == 0 ? "  " : "    ") + pairEntry.pairs.get(i));
148                 out.println();
149             }
150         }
151
152         @Override
153         public String getRawText(boolean compact) {
154             final PairEntry pairEntry = getEntry();
155             return pairEntry.getRawText(compact);
156         }
157
158         @Override
159         public RowMatchType matches(final List<String> searchTokens,
160                                     final Pattern orderedMatchPattern, final Transliterator normalizer,
161                                     final boolean swapPairEntries) {
162             final int side = swapPairEntries ? 1 : 0;
163             final List<Pair> pairs = getEntry().pairs;
164             final String[] pairSides = new String[pairs.size()];
165             for (int i = 0; i < pairs.size(); ++i) {
166                 pairSides[i] = normalizer.transform(pairs.get(i).get(side));
167             }
168             for (int i = searchTokens.size() - 1; i >= 0; --i) {
169                 final String searchToken = searchTokens.get(i);
170                 boolean found = false;
171                 for (final String pairSide : pairSides) {
172                     found |= pairSide.contains(searchToken);
173                 }
174                 if (!found) {
175                     return RowMatchType.NO_MATCH;
176                 }
177             }
178             for (final String pairSide : pairSides) {
179                 if (orderedMatchPattern.matcher(pairSide).find()) {
180                     return RowMatchType.ORDERED_MATCH;
181                 }
182             }
183             return RowMatchType.BAG_OF_WORDS_MATCH;
184         }
185
186         @Override
187         public int getSideLength(boolean swapPairEntries) {
188             int result = 0;
189             final int side = swapPairEntries ? 1 : 0;
190             for (final Pair pair : getEntry().pairs) {
191                 result += pair.get(side).length();
192             }
193             return result;
194         }
195
196     }
197
198     private String getRawText(final boolean compact) {
199         if (compact) {
200             return this.pairs.get(0).toStringTab();
201         }
202         final StringBuilder builder = new StringBuilder();
203         for (int i = 0; i < this.pairs.size(); ++i) {
204             if (i > 0) {
205                 builder.append(" | ");
206             }
207             builder.append(this.pairs.get(i).lang1);
208         }
209         builder.append("\t");
210         for (int i = 0; i < this.pairs.size(); ++i) {
211             if (i > 0) {
212                 builder.append(" | ");
213             }
214             builder.append(this.pairs.get(i).lang2);
215         }
216         return builder.toString();
217     }
218
219     @Override
220     public int compareTo(/*@NonNull*/ final PairEntry that) {
221         return this.getRawText(false).compareTo(that.getRawText(false));
222     }
223
224     @Override
225     public String toString() {
226         return getRawText(false);
227     }
228
229     // -----------------------------------------------------------------------
230
231     public static final class Pair {
232
233         public final String lang1;
234         public final String lang2;
235
236         @SuppressWarnings("WeakerAccess")
237         public Pair(final String lang1, final String lang2) {
238             this.lang1 = lang1;
239             this.lang2 = lang2;
240             assert lang1.trim().length() > 0 && lang2.trim().length() > 0 : "Empty pair!!!";
241         }
242
243         public Pair(final String lang1, final String lang2, final boolean swap) {
244             this(swap ? lang2 : lang1, swap ? lang1 : lang2);
245         }
246
247         public String toString() {
248             return lang1 + " :: " + lang2;
249         }
250
251         String toStringTab() {
252             return lang1 + "\t" + lang2;
253         }
254
255         public String get(int i) {
256             if (i == 0) {
257                 return lang1;
258             } else if (i == 1) {
259                 return lang2;
260             }
261             throw new IllegalArgumentException();
262         }
263
264         @Override
265         public boolean equals(Object o)
266         {
267             if (o == this) return true;
268             if (!(o instanceof Pair)) return false;
269             Pair p = (Pair)o;
270             return p.lang1.equals(lang1) && p.lang2.equals(lang2);
271         }
272
273         @Override
274         public int hashCode()
275         {
276             return (lang1 + "|" + lang2).hashCode();
277         }
278     }
279 }