1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.archive.util.ms;
24
25
26 import java.io.IOException;
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 import java.util.Random;
30
31 import org.archive.io.ArraySeekInputStream;
32 import org.archive.io.SafeSeekInputStream;
33 import org.archive.io.SeekInputStream;
34
35 import junit.framework.TestCase;
36
37
38 /***
39 * Unit test for PieceReader. Takes a quatrain of a sonnet and stores the
40 * lines out-of-order, then constructs a PieceTable that will re-order the
41 * lines correctly. Finally constructs a PieceReader with that raw data
42 * and piece table and sees if the correct quatrain is produced by the
43 * stream. Also performs some tests of random seeking within the stream.
44 *
45 * @author pjack
46 */
47 public class PieceReaderTest extends TestCase {
48
49
50 final private static String[] QUATRAIN = new String[] {
51 "If the dull substance of my flesh were thought\n",
52 "Injurious distance could not stop my way\n",
53 "For then, despite of space, I would be brought\n",
54 "From limits far remote where thou dost stay.\n"
55 };
56
57
58 final private static String QUATRAIN_STRING =
59 QUATRAIN[0] + QUATRAIN[1] + QUATRAIN[2] + QUATRAIN[3];
60
61 final private static byte[] QUATRAIN_BYTES;
62 final private static byte[] PIECE_TABLE;
63
64
65
66 public void testPosition() throws Exception {
67 PieceTable table = makePieceTable();
68 SeekInputStream asis = new ArraySeekInputStream(QUATRAIN_BYTES);
69 asis = new SafeSeekInputStream(asis);
70 PieceReader reader = new PieceReader(table, asis);
71 StringBuilder sb = new StringBuilder();
72 for (int ch = reader.read(); ch > 0; ch = reader.read()) {
73 sb.append((char)ch);
74 }
75 assertEquals(QUATRAIN_STRING, sb.toString());
76
77 reader.position(0);
78 sb = new StringBuilder();
79 for (int ch = reader.read(); ch > 0; ch = reader.read()) {
80 sb.append((char)ch);
81 }
82 assertEquals(QUATRAIN_STRING, sb.toString());
83
84 Random random = new Random();
85 for (int i = 0; i < 1000; i++) {
86 int index = random.nextInt(QUATRAIN_BYTES.length);
87 reader.position(index);
88 char ch = (char)reader.read();
89 assertEquals(QUATRAIN_STRING.charAt(index), ch);
90 }
91 }
92
93
94 private static PieceTable makePieceTable() throws IOException {
95 ArraySeekInputStream stream = new ArraySeekInputStream(PIECE_TABLE);
96 int maxSize = QUATRAIN_BYTES.length;
97 return new PieceTable(stream, 0, maxSize, 4);
98 }
99
100
101 static {
102 QUATRAIN_BYTES = new byte[QUATRAIN_STRING.length()];
103 PIECE_TABLE = new byte[4 * 12 + 5 + 4];
104 int ofs = 0;
105 int line3 = 0;
106 ofs += addLine(ofs, QUATRAIN[2]);
107 int line1 = ofs;
108 ofs += addLine(ofs, QUATRAIN[0]);
109 int line4 = ofs;
110 ofs += addLine(ofs, QUATRAIN[3]);
111 int line2 = ofs;
112 ofs += addLine(ofs, QUATRAIN[1]);
113
114 int start = 0;
115 int end = QUATRAIN[0].length();
116 addPiece(0, start, end, line1);
117
118 start += QUATRAIN[0].length();
119 end += QUATRAIN[1].length();
120 addPiece(1, start, end, line2);
121
122 start += QUATRAIN[1].length();
123 end += QUATRAIN[2].length();
124 addPiece(2, start, end, line3);
125
126 start += QUATRAIN[2].length();
127 end += QUATRAIN[3].length();
128 addPiece(3, start, end, line4);
129
130 ByteBuffer buf = ByteBuffer.wrap(PIECE_TABLE);
131 buf.order(ByteOrder.LITTLE_ENDIAN);
132 buf.put(0, (byte)2);
133 buf.putInt(1, 52);
134 }
135
136
137 private static int addLine(int ofs, String line) {
138 for (int i = 0; i < line.length(); i++) {
139 QUATRAIN_BYTES[ofs + i] = (byte)line.charAt(i);
140 }
141 return line.length();
142 }
143
144
145 private static void addPiece(int index, int start, int end, int fp) {
146 ByteBuffer buf = ByteBuffer.wrap(PIECE_TABLE);
147 buf.order(ByteOrder.LITTLE_ENDIAN);
148 int orig = fp;
149 fp = (fp * 2) | PieceTable.CP1252_INDICATOR;
150 if ((fp & PieceTable.CP1252_MASK) / 2 != orig) {
151 throw new RuntimeException("No.");
152 }
153 buf.putInt(index * 4 + 5, start);
154 buf.putInt(5 + 20 + index * 8 + 2, fp);
155 }
156 }