]> gitweb.fperrin.net Git - Dictionary.git/blob - src/com/hughes/android/dictionary/engine/RowBase.java
go
[Dictionary.git] / src / com / hughes / android / dictionary / engine / RowBase.java
1 package com.hughes.android.dictionary.engine;
2
3 import java.io.IOException;
4 import java.io.PrintStream;
5 import java.io.RandomAccessFile;
6
7 import com.hughes.util.IndexedObject;
8 import com.hughes.util.raf.RAFListSerializer;
9
10 public abstract class RowBase extends IndexedObject {
11   /**
12    * the Index owning this RowBase.
13    */
14   public final Index index;
15   
16   /**
17    * Where this RowBase points to.
18    */
19   public final int referenceIndex;
20
21   /**
22    * the TokenRow above this RowBase, populated on demand.
23    */
24   private TokenRow tokenRow = null;
25   
26   RowBase(final RandomAccessFile raf, final int thisRowIndex, final Index index) throws IOException {
27     super(thisRowIndex);
28     this.index = index;
29     this.referenceIndex = raf.readInt();  // what this points to.
30   }
31
32   public RowBase(final int referenceIndex, final int thisRowIndex, final Index index) {
33     super(thisRowIndex);
34     this.index = index;
35     this.referenceIndex = referenceIndex;
36   }
37
38   /**
39    * @return the TokenRow that this row is "filed under".
40    */
41   public TokenRow getTokenRow(final boolean search) {
42     if (tokenRow == null && search) {
43       int r = index() - 1;
44       int rUp = index() + 1;
45       while (r >= 0) {
46         final RowBase row = index.rows.get(r);
47         final TokenRow candidate = row.getTokenRow(false);
48         if (candidate != null) {
49           for (++r; r <= index(); ++r) {
50             index.rows.get(r).setTokenRow(candidate);
51           }
52           break;
53         }
54         if (rUp < index.rows.size()) {
55           final RowBase rowUp = index.rows.get(rUp);
56           TokenRow candidateUp = rowUp.getTokenRow(false);
57           if (candidateUp != null) {
58             // Did we hit the next set of TokenRows?
59             if (candidateUp.index() > this.index()) {  
60               final int tokenIndex = index.sortedIndexEntries.get(candidateUp.referenceIndex - 1).startRow;
61               candidateUp = (TokenRow) index.rows.get(tokenIndex);
62             }
63             for (--rUp; rUp >= index(); --rUp) {
64               index.rows.get(rUp).setTokenRow(candidateUp);
65             }
66             break;
67           }
68           rUp++;
69         }
70         --r;
71       }
72       assert tokenRow != null;
73     }
74     return tokenRow;
75   }
76   
77   public void setTokenRow(TokenRow tokenRow) {
78     assert this.tokenRow == null;
79     assert tokenRow != null;
80     this.tokenRow = tokenRow;
81   }
82
83   public abstract void print(PrintStream out);
84
85   public abstract String getRawText(final boolean compact);
86
87   // RowBase must manage "disk-based" polymorphism.  All other polymorphism is
88   // dealt with in the normal manner.
89   static class Serializer implements RAFListSerializer<RowBase> {
90     
91     final Index index;
92     
93     Serializer(final Index index) {
94       this.index = index;
95     }
96
97     @Override
98     public RowBase read(RandomAccessFile raf, final int listIndex) throws IOException {
99       final byte rowType = raf.readByte();
100       if (rowType == 0) {
101         return new PairEntry.Row(raf, listIndex, index);
102       } else if (rowType == 1) {
103         return new TokenRow(raf, listIndex, index);
104       } else if (rowType == 2) {
105         return new TextEntry.Row(raf, listIndex, index);
106       }
107       throw new RuntimeException("Invalid rowType:" + rowType);
108     }
109
110     @Override
111     public void write(RandomAccessFile raf, RowBase t) throws IOException {
112       if (t instanceof PairEntry.Row) {
113         raf.writeByte(0);
114       } else if (t instanceof TokenRow) {
115         raf.writeByte(1);
116       } else if (t instanceof TextEntry.Row) {
117         raf.writeByte(2);
118       }
119       raf.writeInt(t.referenceIndex);
120     }
121   }
122
123 }