| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.tika.parser.microsoft.chm; |
| |
| import java.util.concurrent.CancellationException; |
| |
| import org.apache.tika.exception.TikaException; |
| import org.apache.tika.parser.microsoft.chm.ChmCommons.IntelState; |
| import org.apache.tika.parser.microsoft.chm.ChmCommons.LzxState; |
| |
| public class ChmLzxState implements Cloneable { |
| // Trees - PRETREE, MAINTREE, LENGTH, ALIGNED |
| protected short[] mainTreeLengtsTable; |
| protected short[] mainTreeTable; |
| protected short[] lengthTreeTable; |
| protected short[] lengthTreeLengtsTable; |
| protected short[] alignedLenTable; |
| protected short[] alignedTreeTable; |
| /* Class' members */ |
| private int window; /* the actual decoding window */ |
| private long window_size; /* window size (32Kb through 2Mb) */ |
| private int window_position; /* current offset within the window */ |
| private int main_tree_elements; /* number of main tree elements */ |
| private LzxState hadStarted; /* have we started decoding at all yet? */ |
| private int block_type; /* type of this block */ |
| private int block_length; /* uncompressed length of this block */ |
| private int block_remaining; /* uncompressed bytes still left to decode */ |
| private int frames_read; /* the number of CFDATA blocks processed */ |
| private int intel_file_size; /* magic header value used for transform */ |
| private long intel_current_possition; /* current offset in transform space */ |
| private IntelState intel_state; /* have we seen any translatable data yet? */ |
| private long R0; /* for the LRU offset system */ |
| private long R1; /* for the LRU offset system */ |
| private long R2; /* for the LRU offset system */ |
| |
| public ChmLzxState(int window) throws TikaException { |
| if (window >= 0) { |
| int position_slots; |
| int win = ChmCommons.getWindowSize(window); |
| setWindowSize(1 << win); |
| /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */ |
| if (win < 15 || win > 21) { |
| throw new ChmParsingException("window less than 15 or window greater than 21"); |
| } |
| |
| /* Calculates required position slots */ |
| if (win == 20) { |
| position_slots = 42; |
| } else if (win == 21) { |
| position_slots = 50; |
| } else { |
| position_slots = win << 1; |
| } |
| //TODO: position_slots is not used ? |
| setR0(1); |
| setR1(1); |
| setR2(1); |
| setMainTreeElements(512); |
| setHadStarted(LzxState.NOT_STARTED_DECODING); |
| setFramesRead(0); |
| setBlockRemaining(0); |
| setBlockType(ChmConstants.LZX_BLOCKTYPE_INVALID); |
| setIntelCurrentPossition(0); |
| setIntelState(IntelState.NOT_STARTED); |
| setWindowPosition(0); |
| setMainTreeLengtsTable(new short[getMainTreeElements()]); |
| setLengthTreeLengtsTable(new short[ChmConstants.LZX_NUM_SECONDARY_LENGTHS]); |
| } else { |
| throw new CancellationException("window size should be more than zero"); |
| } |
| } |
| |
| private static short[] arrayClone(short[] a) { |
| return a == null ? null : (short[]) a.clone(); |
| } |
| |
| @Override |
| public ChmLzxState clone() { |
| try { |
| ChmLzxState clone = (ChmLzxState) super.clone(); |
| clone.mainTreeLengtsTable = arrayClone(mainTreeLengtsTable); |
| clone.mainTreeTable = arrayClone(mainTreeTable); |
| clone.lengthTreeTable = arrayClone(lengthTreeTable); |
| clone.lengthTreeLengtsTable = arrayClone(lengthTreeLengtsTable); |
| clone.alignedLenTable = arrayClone(alignedLenTable); |
| clone.alignedTreeTable = arrayClone(alignedTreeTable); |
| return clone; |
| } catch (CloneNotSupportedException ex) { |
| return null; |
| } |
| } |
| |
| protected short[] getMainTreeTable() { |
| return mainTreeTable; |
| } |
| |
| protected void setMainTreeTable(short[] mainTreeTable) { |
| this.mainTreeTable = mainTreeTable; |
| } |
| |
| protected short[] getAlignedTreeTable() { |
| return alignedTreeTable; |
| } |
| |
| protected void setAlignedTreeTable(short[] alignedTreeTable) { |
| this.alignedTreeTable = alignedTreeTable; |
| } |
| |
| protected short[] getLengthTreeTable() throws TikaException { |
| if (lengthTreeTable != null) { |
| return this.lengthTreeTable; |
| } else { |
| throw new ChmParsingException("lengthTreeTable is null"); |
| } |
| } |
| |
| protected void setLengthTreeTable(short[] lengthTreeTable) { |
| this.lengthTreeTable = lengthTreeTable; |
| } |
| |
| protected short[] getAlignedLenTable() { |
| return this.alignedLenTable; |
| } |
| |
| protected void setAlignedLenTable(short[] alignedLenTable) { |
| this.alignedLenTable = alignedLenTable; |
| } |
| |
| /** |
| * It suits for informative outlook |
| */ |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append("actual decoding window:=") |
| .append(getWindow()) |
| .append(System.getProperty("line.separator")); |
| sb.append("window size (32Kb through 2Mb):=") |
| .append(getWindowSize()) |
| .append(System.getProperty("line.separator")); |
| sb.append("current offset within the window:=") |
| .append(getWindowPosition()) |
| .append(System.getProperty("line.separator")); |
| sb.append("number of main tree elements:=") |
| .append(getMainTreeElements()) |
| .append(System.getProperty("line.separator")); |
| sb.append("have we started decoding at all yet?:=") |
| .append(getHadStarted()) |
| .append(System.getProperty("line.separator")); |
| sb.append("type of this block:=") |
| .append(getBlockType()) |
| .append(System.getProperty("line.separator")); |
| sb.append("uncompressed length of this block:=") |
| .append(getBlockLength()) |
| .append(System.getProperty("line.separator")); |
| sb.append("uncompressed bytes still left to decode:=") |
| .append(getBlockRemaining()) |
| .append(System.getProperty("line.separator")); |
| sb.append("the number of CFDATA blocks processed:=") |
| .append(getFramesRead()) |
| .append(System.getProperty("line.separator")); |
| sb.append("magic header value used for transform:=") |
| .append(getIntelFileSize()) |
| .append(System.getProperty("line.separator")); |
| sb.append("current offset in transform space:=") |
| .append(getIntelCurrentPossition()) |
| .append(System.getProperty("line.separator")); |
| sb.append("have we seen any translatable data yet?:=") |
| .append(getIntelState()) |
| .append(System.getProperty("line.separator")); |
| sb.append("R0 for the LRU offset system:=") |
| .append(getR0()) |
| .append(System.getProperty("line.separator")); |
| sb.append("R1 for the LRU offset system:=") |
| .append(getR1()) |
| .append(System.getProperty("line.separator")); |
| sb.append("R2 for the LRU offset system:=") |
| .append(getR2()) |
| .append(System.getProperty("line.separator")); |
| sb.append("main tree length:=") |
| .append(getMainTreeLengtsTable().length) |
| .append(System.getProperty("line.separator")); |
| sb.append("secondary tree length:=") |
| .append(getLengthTreeLengtsTable().length) |
| .append(System.getProperty("line.separator")); |
| return sb.toString(); |
| } |
| |
| protected int getWindow() { |
| return window; |
| } |
| |
| protected void setWindow(int window) { |
| this.window = window; |
| } |
| |
| protected long getWindowSize() { |
| return window_size; |
| } |
| |
| protected void setWindowSize(long window_size) { |
| this.window_size = window_size; |
| } |
| |
| protected int getWindowPosition() { |
| return window_position; |
| } |
| |
| protected void setWindowPosition(int window_position) { |
| this.window_position = window_position; |
| } |
| |
| protected int getMainTreeElements() { |
| return main_tree_elements; |
| } |
| |
| protected void setMainTreeElements(int main_tree_elements) { |
| this.main_tree_elements = main_tree_elements; |
| } |
| |
| protected LzxState getHadStarted() { |
| return hadStarted; |
| } |
| |
| protected void setHadStarted(LzxState hadStarted) { |
| this.hadStarted = hadStarted; |
| } |
| |
| public int getBlockType() { |
| return block_type; |
| } |
| |
| protected void setBlockType(int block_type) { |
| this.block_type = block_type; |
| } |
| |
| protected int getBlockLength() { |
| return block_length; |
| } |
| |
| protected void setBlockLength(int block_length) { |
| this.block_length = block_length; |
| } |
| |
| protected int getBlockRemaining() { |
| return block_remaining; |
| } |
| |
| protected void setBlockRemaining(int block_remaining) { |
| this.block_remaining = block_remaining; |
| } |
| |
| protected void increaseFramesRead() { |
| this.frames_read = getFramesRead() + 1; |
| } |
| |
| protected int getFramesRead() { |
| return frames_read; |
| } |
| |
| protected void setFramesRead(int frames_read) { |
| this.frames_read = frames_read; |
| } |
| |
| protected int getIntelFileSize() { |
| return intel_file_size; |
| } |
| |
| protected void setIntelFileSize(int intel_file_size) { |
| this.intel_file_size = intel_file_size; |
| } |
| |
| protected long getIntelCurrentPossition() { |
| return intel_current_possition; |
| } |
| |
| protected void setIntelCurrentPossition(long intel_current_possition) { |
| this.intel_current_possition = intel_current_possition; |
| } |
| |
| protected IntelState getIntelState() { |
| return intel_state; |
| } |
| |
| protected void setIntelState(IntelState intel_state) { |
| this.intel_state = intel_state; |
| } |
| |
| protected long getR0() { |
| return R0; |
| } |
| |
| protected void setR0(long r0) { |
| R0 = r0; |
| } |
| |
| protected long getR1() { |
| return R1; |
| } |
| |
| protected void setR1(long r1) { |
| R1 = r1; |
| } |
| |
| protected long getR2() { |
| return R2; |
| } |
| |
| protected void setR2(long r2) { |
| R2 = r2; |
| } |
| |
| public short[] getMainTreeLengtsTable() { |
| return mainTreeLengtsTable; |
| } |
| |
| public void setMainTreeLengtsTable(short[] mainTreeLengtsTable) { |
| this.mainTreeLengtsTable = mainTreeLengtsTable; |
| } |
| |
| public short[] getLengthTreeLengtsTable() { |
| return lengthTreeLengtsTable; |
| } |
| |
| public void setLengthTreeLengtsTable(short[] lengthTreeLengtsTable) { |
| this.lengthTreeLengtsTable = lengthTreeLengtsTable; |
| } |
| } |