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 }