001: /* PieceReaderTest
002: *
003: * Created on September 18, 2006
004: *
005: * Copyright (C) 2006 Internet Archive.
006: *
007: * This file is part of the Heritrix web crawler (crawler.archive.org).
008: *
009: * Heritrix is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU Lesser Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * any later version.
013: *
014: * Heritrix is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
017: * GNU Lesser Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser Public License
020: * along with Heritrix; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: */
023: package org.archive.util.ms;
024:
025: import java.io.IOException;
026: import java.nio.ByteBuffer;
027: import java.nio.ByteOrder;
028: import java.util.Random;
029:
030: import org.archive.io.ArraySeekInputStream;
031: import org.archive.io.SafeSeekInputStream;
032: import org.archive.io.SeekInputStream;
033:
034: import junit.framework.TestCase;
035:
036: /**
037: * Unit test for PieceReader. Takes a quatrain of a sonnet and stores the
038: * lines out-of-order, then constructs a PieceTable that will re-order the
039: * lines correctly. Finally constructs a PieceReader with that raw data
040: * and piece table and sees if the correct quatrain is produced by the
041: * stream. Also performs some tests of random seeking within the stream.
042: *
043: * @author pjack
044: */
045: public class PieceReaderTest extends TestCase {
046:
047: final private static String[] QUATRAIN = new String[] {
048: "If the dull substance of my flesh were thought\n",
049: "Injurious distance could not stop my way\n",
050: "For then, despite of space, I would be brought\n",
051: "From limits far remote where thou dost stay.\n" };
052:
053: final private static String QUATRAIN_STRING = QUATRAIN[0]
054: + QUATRAIN[1] + QUATRAIN[2] + QUATRAIN[3];
055:
056: final private static byte[] QUATRAIN_BYTES;
057: final private static byte[] PIECE_TABLE;
058:
059: public void testPosition() throws Exception {
060: PieceTable table = makePieceTable();
061: SeekInputStream asis = new ArraySeekInputStream(QUATRAIN_BYTES);
062: asis = new SafeSeekInputStream(asis);
063: PieceReader reader = new PieceReader(table, asis);
064: StringBuilder sb = new StringBuilder();
065: for (int ch = reader.read(); ch > 0; ch = reader.read()) {
066: sb.append((char) ch);
067: }
068: assertEquals(QUATRAIN_STRING, sb.toString());
069:
070: reader.position(0);
071: sb = new StringBuilder();
072: for (int ch = reader.read(); ch > 0; ch = reader.read()) {
073: sb.append((char) ch);
074: }
075: assertEquals(QUATRAIN_STRING, sb.toString());
076:
077: Random random = new Random();
078: for (int i = 0; i < 1000; i++) {
079: int index = random.nextInt(QUATRAIN_BYTES.length);
080: reader.position(index);
081: char ch = (char) reader.read();
082: assertEquals(QUATRAIN_STRING.charAt(index), ch);
083: }
084: }
085:
086: private static PieceTable makePieceTable() throws IOException {
087: ArraySeekInputStream stream = new ArraySeekInputStream(
088: PIECE_TABLE);
089: int maxSize = QUATRAIN_BYTES.length;
090: return new PieceTable(stream, 0, maxSize, 4);
091: }
092:
093: static {
094: QUATRAIN_BYTES = new byte[QUATRAIN_STRING.length()];
095: PIECE_TABLE = new byte[4 * 12 + 5 + 4];
096: int ofs = 0;
097: int line3 = 0;
098: ofs += addLine(ofs, QUATRAIN[2]);
099: int line1 = ofs;
100: ofs += addLine(ofs, QUATRAIN[0]);
101: int line4 = ofs;
102: ofs += addLine(ofs, QUATRAIN[3]);
103: int line2 = ofs;
104: ofs += addLine(ofs, QUATRAIN[1]);
105:
106: int start = 0;
107: int end = QUATRAIN[0].length();
108: addPiece(0, start, end, line1);
109:
110: start += QUATRAIN[0].length();
111: end += QUATRAIN[1].length();
112: addPiece(1, start, end, line2);
113:
114: start += QUATRAIN[1].length();
115: end += QUATRAIN[2].length();
116: addPiece(2, start, end, line3);
117:
118: start += QUATRAIN[2].length();
119: end += QUATRAIN[3].length();
120: addPiece(3, start, end, line4);
121:
122: ByteBuffer buf = ByteBuffer.wrap(PIECE_TABLE);
123: buf.order(ByteOrder.LITTLE_ENDIAN);
124: buf.put(0, (byte) 2);
125: buf.putInt(1, 52);
126: }
127:
128: private static int addLine(int ofs, String line) {
129: for (int i = 0; i < line.length(); i++) {
130: QUATRAIN_BYTES[ofs + i] = (byte) line.charAt(i);
131: }
132: return line.length();
133: }
134:
135: private static void addPiece(int index, int start, int end, int fp) {
136: ByteBuffer buf = ByteBuffer.wrap(PIECE_TABLE);
137: buf.order(ByteOrder.LITTLE_ENDIAN);
138: int orig = fp;
139: fp = (fp * 2) | PieceTable.CP1252_INDICATOR;
140: if ((fp & PieceTable.CP1252_MASK) / 2 != orig) {
141: throw new RuntimeException("No.");
142: }
143: buf.putInt(index * 4 + 5, start);
144: buf.putInt(5 + 20 + index * 8 + 2, fp);
145: }
146: }
|