View Javadoc

1   /* PieceReaderTest
2   *
3   * Created on September 18, 2006
4   *
5   * Copyright (C) 2006 Internet Archive.
6   *
7   * This file is part of the Heritrix web crawler (crawler.archive.org).
8   *
9   * Heritrix is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * any later version.
13  *
14  * Heritrix is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser Public License
20  * along with Heritrix; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 }