/* * Copyright 2014 Takao Nakaguchi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.trie4j.io; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import org.trie4j.Trie; import org.trie4j.bv.BitVector01Divider; import org.trie4j.bv.BytesRank0OnlySuccinctBitVector; import org.trie4j.bv.BytesRank1OnlySuccinctBitVector; import org.trie4j.bv.BytesSuccinctBitVector; import org.trie4j.bv.LongsSuccinctBitVector; import org.trie4j.bv.SuccinctBitVector; import org.trie4j.louds.TailLOUDSTrie; import org.trie4j.louds.bvtree.BvTree; import org.trie4j.louds.bvtree.LOUDSBvTree; import org.trie4j.louds.bvtree.LOUDSPPBvTree; import org.trie4j.tail.DefaultTailArray; import org.trie4j.tail.TailArray; import org.trie4j.tail.index.ArrayTailIndex; import org.trie4j.tail.index.DenseArrayTailIndex; import org.trie4j.tail.index.SBVTailIndex; import org.trie4j.tail.index.TailIndex; import org.trie4j.util.IntArray; public class TrieReader implements Constants{ public TrieReader(InputStream is){ dis = new DataInputStream(is); } public Trie read() throws IOException{ short type = dis.readShort(); switch(type){ case TYPE_TRIE_LOUDS_TAIL: return readTailLOUDSTrie(); default: throw new IOException(String.format( "unknown trie type: 0x%04x", type )); } } public TailLOUDSTrie readTailLOUDSTrie() throws IOException{ return new TailLOUDSTrie( dis.readInt(), dis.readInt(), readBvTree(), readChars(), readTailArray(), readSuccinctBitVector()) {}; } public BvTree readBvTree() throws IOException{ short type = dis.readShort(); switch(type){ case TYPE_BVTREE_LOUDS: return readLOUDSBvTree(); case TYPE_BVTREE_LOUDSPP: return readLOUDSPPBvTree(); default: throw new IOException(String.format( "unknown bvTree type: 0x%04x", type )); } } public LOUDSBvTree readLOUDSBvTree() throws IOException{ return new LOUDSBvTree(readBytesSuccinctBitVector()); } public LOUDSPPBvTree readLOUDSPPBvTree() throws IOException{ return new LOUDSPPBvTree( readBitVector01Divider(), readSuccinctBitVector(), readSuccinctBitVector()); } public TailArray readTailArray() throws IOException{ short type = dis.readShort(); switch(type){ case TYPE_TAILARRAY_DEFAULT: return readDefaultTailArray(); default: throw new IOException(String.format( "unknown tailArray type: 0x%04x", type )); } } public DefaultTailArray readDefaultTailArray() throws IOException{ return new DefaultTailArray( new String(readChars()), readTailIndex() ); } public TailIndex readTailIndex() throws IOException{ short type = dis.readShort(); switch(type){ case TYPE_TAILINDEX_ARRAY: return readArrayTailIndex(); case TYPE_TAILINDEX_DENSEARRAY: return readDenseArrayTailIndex(); case TYPE_TAILINDEX_SBV: return readSBVTailIndex(); default: throw new IOException(String.format( "unknown tailIndex type: 0x%04x", type )); } } public ArrayTailIndex readArrayTailIndex() throws IOException{ return new ArrayTailIndex(readInts()); } public DenseArrayTailIndex readDenseArrayTailIndex() throws IOException{ return new DenseArrayTailIndex( readSuccinctBitVector(), readInts()); } public SBVTailIndex readSBVTailIndex() throws IOException{ return new SBVTailIndex( readSuccinctBitVector(), dis.readInt()); } public BitVector01Divider readBitVector01Divider() throws IOException{ return new BitVector01Divider( dis.readBoolean(), dis.readBoolean()); } public SuccinctBitVector readSuccinctBitVector() throws IOException{ short type = dis.readShort(); switch(type){ case TYPE_SBV_BYTES: return readBytesSuccinctBitVector(); case TYPE_SBV_RANK0ONLY: return readRank0OnlySuccinctBitVector(); case TYPE_SBV_RANK1ONLY: return readRank1OnlySuccinctBitVector(); case TYPE_SBV_LONGS: return readLongsSuccinctBitVector(); } return null; } public BytesSuccinctBitVector readBytesSuccinctBitVector() throws IOException{ return new BytesSuccinctBitVector( readBytes(), dis.readInt(), dis.readInt(), dis.readInt(), dis.readInt(), dis.readInt(), readInts(), readIntArray() ); } public LongsSuccinctBitVector readLongsSuccinctBitVector() throws IOException{ return new LongsSuccinctBitVector( readLongs(), dis.readInt(), dis.readInt(), dis.readInt(), dis.readInt(), dis.readInt(), readInts(), readIntArray() ); } public BytesRank0OnlySuccinctBitVector readRank0OnlySuccinctBitVector() throws IOException{ return new BytesRank0OnlySuccinctBitVector( readBytes(), dis.readInt(), readInts() ); } public BytesRank1OnlySuccinctBitVector readRank1OnlySuccinctBitVector() throws IOException{ return new BytesRank1OnlySuccinctBitVector( readBytes(), dis.readInt(), readInts() ); } public byte[] readBytes() throws IOException{ int n = dis.readInt(); byte[] ret = new byte[n]; int offset = 0; while(n > 0){ int s = dis.read(ret, offset, n); if(s == -1){ throw new EOFException("failed to read expected bytes. exp:" + (offset + n) + " act:" + offset); } offset += s; n -= s; } return ret; } public char[] readChars() throws IOException{ int n = dis.readInt(); char[] ret = new char[n]; for(int i = 0; i < n; i++){ ret[i] = dis.readChar(); } return ret; } public int[] readInts() throws IOException{ int n = dis.readInt(); int[] ret = new int[n]; for(int i = 0; i < n; i++){ ret[i] = dis.readInt(); } return ret; } public long[] readLongs() throws IOException{ int n = dis.readInt(); long[] ret = new long[n]; for(int i = 0; i < n; i++){ ret[i] = dis.readLong(); } return ret; } public IntArray readIntArray() throws IOException{ int[] i = readInts(); return new IntArray(i, i.length); } private DataInputStream dis; }