ChmExtractor { public byte[] extractChmEntry(DirectoryListingEntry directoryListingEntry) throws TikaException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ChmLzxBlock lzxBlock = null; try { if (directoryListingEntry.getEntryType() == EntryType.UNCOMPRESSED && directoryListingEntry.getLength() > 0 && !ChmCommons.hasSkip(directoryListingEntry)) { int dataOffset = (int) (getChmItsfHeader().getDataOffset() + directoryListingEntry .getOffset()); buffer.write(ChmCommons.copyOfRange( getData(), dataOffset, dataOffset + directoryListingEntry.getLength())); } else if (directoryListingEntry.getEntryType() == EntryType.COMPRESSED && !ChmCommons.hasSkip(directoryListingEntry)) { chmBlockInfo = ChmBlockInfo.getChmBlockInfoInstance( directoryListingEntry, (int) getChmLzxcResetTable() .getBlockLen(), getChmLzxcControlData(), chmBlockInfo); int i = 0, start = 0, hit_cache = 0; if ((getLzxBlockLength() < Integer.MAX_VALUE) && (getLzxBlockOffset() < Integer.MAX_VALUE)) { start = -1; if (!getLzxBlocksCache().isEmpty()) { for (i = 0; i < getLzxBlocksCache().size(); i++) { int bn = getLzxBlocksCache().get(i).getBlockNumber(); for (int j = chmBlockInfo.getIniBlock(); j <= chmBlockInfo.getStartBlock(); j++) { if (bn == j) { if (j > start) { start = j; hit_cache = i; } } } if (start == chmBlockInfo.getStartBlock()) break; } } if (start<0) { start = chmBlockInfo.getIniBlock(); byte[] 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(hit_cache); } for (i = start; i <= chmBlockInfo.getEndBlock();) { if (i == chmBlockInfo.getStartBlock() && i == chmBlockInfo.getEndBlock()) { buffer.write(lzxBlock.getContent( chmBlockInfo.getStartOffset(), chmBlockInfo.getEndOffset())); break; } if (i == chmBlockInfo.getStartBlock()) { buffer.write(lzxBlock.getContent( chmBlockInfo.getStartOffset())); } if (i > chmBlockInfo.getStartBlock() && i < chmBlockInfo.getEndBlock()) { buffer.write(lzxBlock.getContent()); } if (i == chmBlockInfo.getEndBlock()) { buffer.write(lzxBlock.getContent( 0, chmBlockInfo.getEndOffset())); 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(), lzxBlock); } getLzxBlocksCache().add(lzxBlock); } if (getLzxBlocksCache().size() > getChmLzxcResetTable() .getBlockCount()) { getLzxBlocksCache().clear(); } } if (buffer.size() != directoryListingEntry.getLength()) { throw new TikaException("CHM file extract error: extracted Length is wrong."); } } } catch (Exception e) { throw new TikaException(e.getMessage()); } return buffer.toByteArray(); } ChmExtractor(InputStream is); List<String> enumerateChm(); byte[] extractChmEntry(DirectoryListingEntry directoryListingEntry); ChmDirectoryListingSet getChmDirList();  }
@Test public void testExtractChmEntry() throws TikaException{ ChmDirectoryListingSet entries = chmExtractor.getChmDirList(); int count = 0; for (DirectoryListingEntry directoryListingEntry : entries.getDirectoryListingEntryList()) { chmExtractor.extractChmEntry(directoryListingEntry); ++count; } assertEquals(TestParameters.VP_CHM_ENTITIES_NUMBER, count); }