* @throws TikaException
*/
public byte[][] extractChmEntry(DirectoryListingEntry directoryListingEntry) throws TikaException {
byte[][] tmp = null;
byte[] dataSegment = null;
ChmLzxBlock lzxBlock = null;
try {
/* UNCOMPRESSED type is easiest one */
if (directoryListingEntry.getEntryType() == EntryType.UNCOMPRESSED
&& directoryListingEntry.getLength() > 0
&& !ChmCommons.hasSkip(directoryListingEntry)) {
int dataOffset = (int) (getChmItsfHeader().getDataOffset() + directoryListingEntry
.getOffset());
// dataSegment = Arrays.copyOfRange(getData(), dataOffset,
// dataOffset + directoryListingEntry.getLength());
dataSegment = ChmCommons.copyOfRange(getData(), dataOffset,
dataOffset + directoryListingEntry.getLength());
} else if (directoryListingEntry.getEntryType() == EntryType.COMPRESSED
&& !ChmCommons.hasSkip(directoryListingEntry)) {
/* Gets a chm block info */
ChmBlockInfo bb = ChmBlockInfo.getChmBlockInfoInstance(
directoryListingEntry, (int) getChmLzxcResetTable()
.getBlockLen(), getChmLzxcControlData());
tmp = new byte[bb.getEndBlock() - bb.getStartBlock() + 1][];
int i = 0, start = 0, block = 0;
if ((getLzxBlockLength() < Integer.MAX_VALUE)
&& (getLzxBlockOffset() < Integer.MAX_VALUE)) {
// TODO: Improve the caching
// caching ... = O(n^2) - depends on startBlock and endBlock
if (getLzxBlocksCache().size() != 0) {
for (i = 0; i < getLzxBlocksCache().size(); i++) {
lzxBlock = getLzxBlocksCache().get(i);
for (int j = bb.getIniBlock(); j <= bb
.getStartBlock(); j++) {
if (lzxBlock.getBlockNumber() == j)
if (j > start) {
start = j;
block = i;
}
if (start == bb.getStartBlock())
break;
}
}
}
if (i == getLzxBlocksCache().size() && i == 0) {
start = bb.getIniBlock();
dataSegment = ChmCommons.getChmBlockSegment(getData(),
getChmLzxcResetTable(), start,
(int) getLzxBlockOffset(),
(int) getLzxBlockLength());
lzxBlock = new ChmLzxBlock(start, dataSegment,
getChmLzxcResetTable().getBlockLen(), null);
getLzxBlocksCache().add(lzxBlock);
} else {
lzxBlock = getLzxBlocksCache().get(block);
}
for (i = start; i <= bb.getEndBlock();) {
if (i == bb.getStartBlock() && i == bb.getEndBlock()) {
dataSegment = lzxBlock.getContent(
bb.getStartOffset(), bb.getEndOffset());
tmp[0] = dataSegment;
break;
}
if (i == bb.getStartBlock()) {
dataSegment = lzxBlock.getContent(bb
.getStartOffset());
tmp[0] = dataSegment;
}
if (i > bb.getStartBlock() && i < bb.getEndBlock()) {
dataSegment = lzxBlock.getContent();
tmp[i - bb.getStartBlock()] = dataSegment;
}
if (i == bb.getEndBlock()) {
dataSegment = lzxBlock.getContent(0,
bb.getEndOffset());
tmp[i - bb.getStartBlock()] = dataSegment;
break;
}
i++;
if (i % getChmLzxcControlData().getResetInterval() == 0) {
lzxBlock = new ChmLzxBlock(i,
ChmCommons.getChmBlockSegment(getData(),
getChmLzxcResetTable(), i,
(int) getLzxBlockOffset(),
(int) getLzxBlockLength()),
getChmLzxcResetTable().getBlockLen(), null);
} else {
lzxBlock = new ChmLzxBlock(i,
ChmCommons.getChmBlockSegment(getData(),
getChmLzxcResetTable(), i,
(int) getLzxBlockOffset(),
(int) getLzxBlockLength()),
getChmLzxcResetTable().getBlockLen(),