1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 10:49:24 +02:00

zip/epub optimizations

git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@897 6a642e6f-84f6-412e-ac94-c4a38d5a04b0
This commit is contained in:
Nikolay Pultsin 2009-03-25 08:36:06 +00:00
parent e372718dc1
commit eebd831047
11 changed files with 289 additions and 287 deletions

View file

@ -4,14 +4,15 @@ final class CircularBuffer {
static final int DICTIONARY_LENGTH = (1 << 15);
private static final int DICTIONARY_MASK = DICTIONARY_LENGTH - 1;
private final byte[] myBuffer;
private final byte[] myBuffer = new byte[DICTIONARY_LENGTH];
private int myBytesReady; // number of bytes can be read
private int myCurrentPosition; // the next byte to read is
// myDictionary[myCurrentPosition]
public CircularBuffer() {
myBuffer = new byte[DICTIONARY_LENGTH];
}
void reset() {
myBytesReady = 0;
myCurrentPosition = 0;
}
public int available() {
return myBytesReady;

View file

@ -3,122 +3,101 @@ package org.amse.ys.zip;
public class CodeBuilder {
public static final int MAX_HUFFMAN_CODE_LENGTH = 15;
final private int[] myCodeArray;
final private int[] myLengthArray;
private int myNumberOfCodes;
private boolean myCodesAreBuild;
public CodeBuilder(int maxNumberOfCodes) {
myCodeArray = new int[maxNumberOfCodes];
myLengthArray = new int[maxNumberOfCodes];
myNumberOfCodes = maxNumberOfCodes;
myLengthArray = new int[maxNumberOfCodes];
}
public void addCodeLength(int codeNumber, int codeLen) {
if (!myCodesAreBuild) {
myLengthArray[codeNumber] = codeLen;
} else {
throw new RuntimeException(
"Trying to addCodeLength after biulding huffman codes");
}
myLengthArray[codeNumber] = codeLen;
}
private void buildCodes() {
// counting number of codes for definite length
int[] b1_count = new int[MAX_HUFFMAN_CODE_LENGTH + 1];
for (int i = 0; i < myNumberOfCodes; i++) {
b1_count[myLengthArray[i]]++;
}
b1_count[0] = 0;
public void buildTable(int[] table) {
final int arrayLength = myLengthArray.length;
// step 2
int[] next_code = new int[MAX_HUFFMAN_CODE_LENGTH + 1];
int code = 0;
for (int bits = 1; bits <= MAX_HUFFMAN_CODE_LENGTH; bits++) {
code = ((code + b1_count[bits - 1]) << 1);
next_code[bits] = code;
}
// counting number of codes for definite length
int[] b1_count = new int[MAX_HUFFMAN_CODE_LENGTH + 1];
for (int i = 0; i < arrayLength; i++) {
b1_count[myLengthArray[i]]++;
}
b1_count[0] = 0;
// step 3
for (int i = 0; i < myNumberOfCodes; i++) {
int len = myLengthArray[i];
if (len != 0) {
myCodeArray[i] = next_code[len];
next_code[len]++;
}
}
myCodesAreBuild = true;
// step 2
int[] next_code = new int[MAX_HUFFMAN_CODE_LENGTH + 1];
int code = 0;
for (int bits = 1; bits <= MAX_HUFFMAN_CODE_LENGTH; bits++) {
code = ((code + b1_count[bits - 1]) << 1);
next_code[bits] = code;
}
// step 3
for (int i = 0; i < arrayLength; ++i) {
final int codeLength = myLengthArray[i];
if (codeLength > 0) {
int revertedCode = next_code[codeLength]++;
int c = 0;
for (int j = 0; j < codeLength; ++j) {
c = (c << 1) + (revertedCode & 1);
revertedCode >>= 1;
}
final int value = (codeLength << 16) + i;
for (int j = 0; j < (1 << (15 - codeLength)); ++j) {
table[(j << codeLength) + c] = value;
}
}
}
}
public int[] returnArrayOfCodes() {
if (!myCodesAreBuild) {
buildCodes();
}
return myCodeArray;
}
public int[] returnArrayOfLengths() {
return myLengthArray;
}
public int[] buildTable() {
final int[] table = new int[1 << 15];
if (!myCodesAreBuild) {
buildCodes();
}
final int length = myCodeArray.length;
public void buildTable(int[] codeArray, int[] table) {
final int length = codeArray.length;
for (int i = 0; i < length; i++) {
final int codeLength = myLengthArray[i];
if (codeLength > 0) {
int revertedCode = myCodeArray[i];
int code = 0;
for (int j = 0; j < codeLength; ++j) {
code = (code << 1) + (revertedCode & 1);
revertedCode >>= 1;
}
final int value = (codeLength << 16) + i;
for (int j = 0; j < (1 << (15 - codeLength)); ++j) {
table[(j << codeLength) + code] = value;
}
}
final int codeLength = myLengthArray[i];
if (codeLength > 0) {
int revertedCode = codeArray[i];
int code = 0;
for (int j = 0; j < codeLength; ++j) {
code = (code << 1) + (revertedCode & 1);
revertedCode >>= 1;
}
final int value = (codeLength << 16) + i;
for (int j = 0; j < (1 << (15 - codeLength)); ++j) {
table[(j << codeLength) + code] = value;
}
}
}
return table;
}
private void loadFixed() {
for (int i = 0; i <= 143; i++) {
//
myCodeArray[i] = 48 + i;
myLengthArray[i] = 8;
}
for (int i = 144; i <= 255; i++) {
myLengthArray[i] = 9;
myCodeArray[i] = 256 + i;
}
for (int i = 256; i <= 279; i++) {
myLengthArray[i] = 7;
myCodeArray[i] = 0 + i - 256;
}
for (int i = 280; i <= 287; i++) {
myCodeArray[i] = 192 + i - 280;
myLengthArray[i] = 8;
}
public static void buildFixedHuffmanCodes(int[] table) {
CodeBuilder builder = new CodeBuilder(288);
final int[] codeArray = new int[288];
for (int i = 0; i <= 143; i++) {
builder.myLengthArray[i] = 8;
codeArray[i] = 48 + i;
}
for (int i = 144; i <= 255; i++) {
builder.myLengthArray[i] = 9;
codeArray[i] = 256 + i;
}
for (int i = 256; i <= 279; i++) {
builder.myLengthArray[i] = 7;
codeArray[i] = 0 + i - 256;
}
for (int i = 280; i <= 287; i++) {
builder.myLengthArray[i] = 8;
codeArray[i] = 192 + i - 280;
}
builder.buildTable(codeArray, table);
}
public static CodeBuilder buildFixedHuffmanCodes() {
CodeBuilder builder = new CodeBuilder(288);
builder.loadFixed();
return builder;
}
public static CodeBuilder buildFixedDistanceCodes() {
CodeBuilder builder = new CodeBuilder(32);
for (int i = 0; i < 32; i++) {
builder.myCodeArray[i] = i;
builder.myLengthArray[i] = 5;
}
return builder;
public static void buildFixedDistanceCodes(int[] table) {
CodeBuilder builder = new CodeBuilder(32);
final int[] codeArray = new int[32];
for (int i = 0; i < 32; i++) {
codeArray[i] = i;
builder.myLengthArray[i] = 5;
}
builder.buildTable(codeArray, table);
}
}

View file

@ -1,17 +1,26 @@
package org.amse.ys.zip;
import java.util.*;
import java.io.*;
public abstract class Decompressor {
public Decompressor(MyBufferedInputStream is, LocalFileHeader header) {
}
public abstract int read(byte b[], int off, int len) throws IOException, WrongZipFormatException;
public abstract int read() throws IOException, WrongZipFormatException;
protected Decompressor() {
}
private static Queue<DeflatingDecompressor> ourDeflators = new LinkedList<DeflatingDecompressor>();
static void storeDecompressor(Decompressor decompressor) {
if (decompressor instanceof DeflatingDecompressor) {
synchronized (ourDeflators) {
ourDeflators.add((DeflatingDecompressor)decompressor);
}
}
}
public static Decompressor init(MyBufferedInputStream is, LocalFileHeader header)
@ -20,10 +29,16 @@ public abstract class Decompressor {
case 0:
return new NoCompressionDecompressor(is, header);
case 8:
synchronized (ourDeflators) {
if (!ourDeflators.isEmpty()) {
DeflatingDecompressor decompressor = ourDeflators.poll();
decompressor.reset(is, header);
return decompressor;
}
}
return new DeflatingDecompressor(is, header);
default:
throw new WrongZipFormatException(
"Unsupported method of compression");
throw new WrongZipFormatException("Unsupported method of compression");
}
}

View file

@ -10,31 +10,52 @@ public class DeflatingDecompressor extends Decompressor {
private static final int ST_END_OF_FILE = 5;
// common variables
private final LocalFileHeader myHeader;
private final MyBufferedInputStream myStream;
private MyBufferedInputStream myStream;
private LocalFileHeader myHeader;
private int myState;
private int myTotalLength;
private int myBytesRead;
private int myCurrentPosition;
private boolean myTheBlockIsFinal = false;
private boolean myTheBlockIsFinal;
// for bit reader
private int myBitsInBuffer;
private int myTempInt; // should contain 16 bit available for reading
// output buffer
private final CircularBuffer myOutputBuffer;
private final CircularBuffer myOutputBuffer = new CircularBuffer();
// for no compression method
private int myCurrentBlockLength;
private int myReadInBlock;
// for Huffman codes
private int[] myHuffmanCodes;
private int[] myDistanceCodes;
private final int[] myHuffmanCodes = new int[1 << 15];
private final int[] myDistanceCodes = new int[1 << 15];
private final int[] myAuxCodes = new int[1 << 15];
public DeflatingDecompressor(MyBufferedInputStream inputStream, LocalFileHeader header) {
super();
reset(inputStream, header);
}
void reset(MyBufferedInputStream inputStream, LocalFileHeader header) {
myStream = inputStream;
myHeader = header;
myTotalLength = header.getCompressedSize();
myBytesRead = 0;
myCurrentPosition = 0;
myTheBlockIsFinal = false;
myState = ST_HEADER;
myOutputBuffer.reset();
myBitsInBuffer = 0;
myTempInt = 0;
myCurrentBlockLength = 0;
myReadInBlock = 0;
}
public int available() {
return (myHeader.getUncompressedSize() - myCurrentPosition);
return myHeader.getUncompressedSize() - myCurrentPosition;
}
private void ensure16BitsInBuffer() throws IOException {
@ -75,17 +96,6 @@ public class DeflatingDecompressor extends Decompressor {
return result;
}
public DeflatingDecompressor(MyBufferedInputStream is, LocalFileHeader header) {
super();
myHeader = header;
myStream = is;
myBitsInBuffer = 0;
myOutputBuffer = new CircularBuffer();
myTotalLength = header.getCompressedSize();
myBytesRead = 0;
myState = ST_HEADER;
}
private static final int MAX_LEN = CircularBuffer.DICTIONARY_LENGTH / 2;
public int read(byte b[], int off, int len) throws IOException, WrongZipFormatException {
@ -255,8 +265,8 @@ public class DeflatingDecompressor extends Decompressor {
break;
case 1:
myState = ST_FIXED_CODES;
myHuffmanCodes = CodeBuilder.buildFixedHuffmanCodes().buildTable();
myDistanceCodes = CodeBuilder.buildFixedDistanceCodes().buildTable();
CodeBuilder.buildFixedHuffmanCodes(myHuffmanCodes);
CodeBuilder.buildFixedDistanceCodes(myDistanceCodes);
break;
case 2:
myState = ST_DYNAMIC_CODES;
@ -288,12 +298,12 @@ public class DeflatingDecompressor extends Decompressor {
readIntegerByBit(3));
}
final int[] distHuffmanCodes = headerReadingCoder.buildTable();
headerReadingCoder.buildTable(myAuxCodes);
CodeBuilder usualCodeBuilder = new CodeBuilder(288);
int previousNumber = 0;
for (int i = 0; i < (numberOfLiteralCodes + 257); i++) {
int currentHuffmanCode = readHuffmanCode(distHuffmanCodes);
int currentHuffmanCode = readHuffmanCode(myAuxCodes);
//headersFound++;
if (currentHuffmanCode <= 15) {
usualCodeBuilder.addCodeLength(i, currentHuffmanCode);
@ -326,13 +336,13 @@ public class DeflatingDecompressor extends Decompressor {
}
}
// we can build huffman codes for charset
myHuffmanCodes = usualCodeBuilder.buildTable();
usualCodeBuilder.buildTable(myHuffmanCodes);
// building distance codes
CodeBuilder distanceCodeBuilder = new CodeBuilder(32);
previousNumber = 0;
for (int i = 0; i < (numberOfDistanceCodes + 1); i++) {
int currentHuffmanCode = readHuffmanCode(distHuffmanCodes);
int currentHuffmanCode = readHuffmanCode(myAuxCodes);
//headersFound++;
if (currentHuffmanCode <= 15) {
distanceCodeBuilder.addCodeLength(i, currentHuffmanCode);
@ -364,6 +374,6 @@ public class DeflatingDecompressor extends Decompressor {
i += (repeatNumber - 1);
}
}
myDistanceCodes = distanceCodeBuilder.buildTable();
distanceCodeBuilder.buildTable(myDistanceCodes);
}
}

View file

@ -59,12 +59,10 @@ public class LocalFileHeader {
}
void setSizes(int compressedSize, int uncompressedSize) {
if (mySizeIsKnown) {
throw new RuntimeException(
"Was attempt to change file sizes with use of setSizes");
if (!mySizeIsKnown) {
myCompressedSize = compressedSize;
myUncompressedSize = uncompressedSize;
mySizeIsKnown = true;
}
myCompressedSize = compressedSize;
myUncompressedSize = uncompressedSize;
mySizeIsKnown = true;
}
}

View file

@ -10,10 +10,10 @@ final class MyBufferedInputStream extends InputStream {
int myPositionInBuffer;
private int myCurrentPosition;
public MyBufferedInputStream(String s, int arraySize) throws IOException {
myFileName = s;
myFileInputStream = new FileInputStream(s);
myBuffer = new byte[arraySize];
public MyBufferedInputStream(String fileName, int bufferSize) throws IOException {
myFileName = fileName;
myFileInputStream = new FileInputStream(fileName);
myBuffer = new byte[bufferSize];
myBytesReady = 0;
myPositionInBuffer = 0;
}
@ -44,7 +44,7 @@ final class MyBufferedInputStream extends InputStream {
}
}
myBytesReady--;
return (myBuffer[myPositionInBuffer++] & 255);
return myBuffer[myPositionInBuffer++] & 255;
}
int read2Bytes() throws IOException {
@ -113,5 +113,4 @@ final class MyBufferedInputStream extends InputStream {
myFileInputStream.close();
myBytesReady = 0;
}
}

View file

@ -1,13 +1,14 @@
package org.amse.ys.zip;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collection;
import java.util.Queue;
import java.util.LinkedList;
import java.util.TreeMap;
public class ZipFile {
private final String myFileName;
private final ArrayList<LocalFileHeader> myFileHeaders = new ArrayList<LocalFileHeader>();
private final TreeMap<String,LocalFileHeader> myFileHeaders = new TreeMap<String,LocalFileHeader>();
private final MyBufferedInputStream myBaseStream;
private boolean myAllFilesAreRead;
@ -17,13 +18,13 @@ public class ZipFile {
myBaseStream = new MyBufferedInputStream(myFileName);
}
public List<LocalFileHeader> headers() {
public Collection<LocalFileHeader> headers() {
try {
readAllHeaders();
} catch (IOException e) {
} catch (WrongZipFormatException e) {
}
return Collections.unmodifiableList(myFileHeaders);
return myFileHeaders.values();
}
private boolean readFileHeader(String fileToFind) throws IOException {
@ -39,20 +40,16 @@ public class ZipFile {
final String fileName = myBaseStream.readString(fileNameSize);
myBaseStream.skip(extraField);
myFileHeaders.add(new LocalFileHeader(version2extract, generalFlag,
LocalFileHeader header = new LocalFileHeader(version2extract, generalFlag,
compressionMethod, compressedSize, uncompressedSize,
myBaseStream.offset(), fileName));
if (fileName.equals(fileToFind)) {
return true;
}
if ((generalFlag & 8) == 0) {
myBaseStream.offset(), fileName);
myFileHeaders.put(fileName, header);
if (header.sizeIsKnown()) {
myBaseStream.skip(compressedSize);
} else {
System.out
.println("Warning: flag 3 is set! Trying to find header.");
findAndReadDescriptor();
findAndReadDescriptor(header);
}
return false;
return fileName.equals(fileToFind);
}
private void readAllHeaders() throws IOException, WrongZipFormatException {
@ -61,6 +58,9 @@ public class ZipFile {
}
myAllFilesAreRead = true;
myBaseStream.reset();
myFileHeaders.clear();
while (true) {
int header = myBaseStream.read4Bytes();
if (header != LocalFileHeader.FILE_HEADER_SIGNATURE) {
@ -80,8 +80,7 @@ public class ZipFile {
/**
* Finds descriptor of the last header and installs sizes of files
*/
private void findAndReadDescriptor() throws IOException {
byte[] tempArray = new byte[12];
private void findAndReadDescriptor(LocalFileHeader header) throws IOException {
while (true) {
int signature = 0;
do {
@ -90,23 +89,13 @@ public class ZipFile {
throw new IOException(
"readFileHeaders. Unexpected end of file when looking for DataDescriptor");
}
signature = ((signature << 8) & (0x0ffffffff))
+ (byte) nextByte;
signature = ((signature << 8) & (0x0FFFFFFFF)) + (byte) nextByte;
} while (signature != LocalFileHeader.DATA_DESCRIPTOR_SIGNATURE);
myBaseStream.read(tempArray);
int compressedSize =
((tempArray[7] & 0xff) << 24) +
((tempArray[6] & 0xff) << 16) +
((tempArray[5] & 0xff) << 8) +
(tempArray[4] & 0xff);
int uncompressedSize =
((tempArray[11] & 0xff) << 24) +
((tempArray[10] & 0xff) << 16) +
((tempArray[9] & 0xff) << 8) +
(tempArray[8] & 0xff);
LocalFileHeader lastHeader = myFileHeaders.get(myFileHeaders.size() - 1);
if ((myBaseStream.offset() - lastHeader.OffsetOfLocalData - 16) == compressedSize) {
lastHeader.setSizes(compressedSize, uncompressedSize);
myBaseStream.skip(4);
int compressedSize = myBaseStream.read4Bytes();
int uncompressedSize = myBaseStream.read4Bytes();
if ((myBaseStream.offset() - header.OffsetOfLocalData - 16) == compressedSize) {
header.setSizes(compressedSize, uncompressedSize);
break;
} else {
myBaseStream.backSkip(12);
@ -115,30 +104,36 @@ public class ZipFile {
}
}
private final Queue<MyBufferedInputStream> myStoredStreams = new LinkedList<MyBufferedInputStream>();
synchronized void storeBaseStream(MyBufferedInputStream baseStream) {
myStoredStreams.add(baseStream);
}
synchronized private ZipInputStream createZipInputStream(LocalFileHeader header) throws IOException, WrongZipFormatException {
MyBufferedInputStream baseStream =
myStoredStreams.isEmpty() ?
new MyBufferedInputStream(myFileName) :
myStoredStreams.poll();
return new ZipInputStream(this, baseStream, header);
}
public InputStream getInputStream(String entryName) throws IOException {
if (!myFileHeaders.isEmpty()) {
// trying to find in already ready array
int i;
final int listSize = myFileHeaders.size();
LocalFileHeader header = null;
for (i = 0; i < listSize; i++) {
header = myFileHeaders.get(i);
if (header.FileName.equals(entryName)) {
try {
return new ZipInputStream(myFileName, header);
} catch (WrongZipFormatException e) {
return null;
}
LocalFileHeader header = myFileHeaders.get(entryName);
if (header != null) {
try {
return createZipInputStream(header);
} catch (WrongZipFormatException e) {
return null;
}
}
if (myAllFilesAreRead) {
return null;
}
if (header.sizeIsKnown()) {
myBaseStream.setPosition(header.OffsetOfLocalData + header.getCompressedSize());
} else {
findAndReadDescriptor();
}
}
// ready to read fileheader
do {
@ -153,13 +148,12 @@ public class ZipFile {
}
}
} while (!readFileHeader(entryName));
LocalFileHeader header = myFileHeaders.get(myFileHeaders.size() - 1);
if (header.FileName.equals(entryName)) {
try {
return new ZipInputStream(myFileName, header);
} catch (WrongZipFormatException e) {
return null;
}
LocalFileHeader header = myFileHeaders.get(entryName);
if (header != null) {
try {
return createZipInputStream(header);
} catch (WrongZipFormatException e) {
}
}
return null;
}

View file

@ -5,17 +5,17 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class ZipInputStream extends InputStream {
class ZipInputStream extends InputStream {
private final ZipFile myParent;
private final MyBufferedInputStream myBaseStream;
private final LocalFileHeader myHeader;
private final Decompressor myDecompressor;
private boolean myIsClosed;
public ZipInputStream(String fileName, LocalFileHeader header) throws IOException, WrongZipFormatException {
if (!header.sizeIsKnown()) {
throw new RuntimeException("Reading of files with flag 3 is not implemented yet");
}
myBaseStream = new MyBufferedInputStream(fileName);
myBaseStream.setPosition(header.OffsetOfLocalData);
public ZipInputStream(ZipFile parent, MyBufferedInputStream baseStream, LocalFileHeader header) throws IOException, WrongZipFormatException {
myParent = parent;
myBaseStream = baseStream;
baseStream.setPosition(header.OffsetOfLocalData);
myHeader = header;
myDecompressor = Decompressor.init(myBaseStream, header);
}
@ -50,6 +50,10 @@ public class ZipInputStream extends InputStream {
}
public void close() throws IOException {
myBaseStream.close();
if (!myIsClosed) {
myIsClosed = true;
myParent.storeBaseStream(myBaseStream);
Decompressor.storeDecompressor(myDecompressor);
}
}
}

View file

@ -33,9 +33,7 @@ public class OEBPlugin extends FormatPlugin {
public boolean acceptsFile(ZLFile file) {
final String extension = file.getExtension().intern();
return (extension == "opf") ||
(extension == "oebzip") ||
(extension == "epub");
return (extension == "opf") || (extension == "oebzip") || (extension == "epub");
}
private String getOpfFileName(String oebFileName) {

View file

@ -37,79 +37,81 @@ public class XHTMLReader extends ZLXMLReaderAdapter {
}
public static void fillTagTable() {
if (ourTagActions.isEmpty()) {
//addAction("html", new XHTMLTagAction());
addAction("body", new XHTMLTagBodyAction());
//addAction("title", new XHTMLTagAction());
//addAction("meta", new XHTMLTagAction());
//addAction("script", new XHTMLTagAction());
//addAction("font", new XHTMLTagAction());
//addAction("style", new XHTMLTagAction());
addAction("p", new XHTMLTagParagraphAction());
addAction("h1", new XHTMLTagParagraphWithControlAction(FBTextKind.H1));
addAction("h2", new XHTMLTagParagraphWithControlAction(FBTextKind.H2));
addAction("h3", new XHTMLTagParagraphWithControlAction(FBTextKind.H3));
addAction("h4", new XHTMLTagParagraphWithControlAction(FBTextKind.H4));
addAction("h5", new XHTMLTagParagraphWithControlAction(FBTextKind.H5));
addAction("h6", new XHTMLTagParagraphWithControlAction(FBTextKind.H6));
//addAction("ol", new XHTMLTagAction());
//addAction("ul", new XHTMLTagAction());
//addAction("dl", new XHTMLTagAction());
addAction("li", new XHTMLTagItemAction());
addAction("strong", new XHTMLTagControlAction(FBTextKind.STRONG));
addAction("b", new XHTMLTagControlAction(FBTextKind.BOLD));
addAction("em", new XHTMLTagControlAction(FBTextKind.EMPHASIS));
addAction("i", new XHTMLTagControlAction(FBTextKind.ITALIC));
final XHTMLTagAction codeControlAction = new XHTMLTagControlAction(FBTextKind.CODE);
addAction("code", codeControlAction);
addAction("tt", codeControlAction);
addAction("kbd", codeControlAction);
addAction("var", codeControlAction);
addAction("samp", codeControlAction);
addAction("cite", new XHTMLTagControlAction(FBTextKind.CITE));
addAction("sub", new XHTMLTagControlAction(FBTextKind.SUB));
addAction("sup", new XHTMLTagControlAction(FBTextKind.SUP));
addAction("dd", new XHTMLTagControlAction(FBTextKind.DEFINITION_DESCRIPTION));
addAction("dfn", new XHTMLTagControlAction(FBTextKind.DEFINITION));
addAction("strike", new XHTMLTagControlAction(FBTextKind.STRIKETHROUGH));
addAction("a", new XHTMLTagHyperlinkAction());
addAction("img", new XHTMLTagImageAction("src"));
addAction("object", new XHTMLTagImageAction("data"));
//addAction("area", new XHTMLTagAction());
//addAction("map", new XHTMLTagAction());
//addAction("base", new XHTMLTagAction());
//addAction("blockquote", new XHTMLTagAction());
addAction("br", new XHTMLTagRestartParagraphAction());
//addAction("center", new XHTMLTagAction());
addAction("div", new XHTMLTagParagraphAction());
//addAction("dt", new XHTMLTagAction());
//addAction("head", new XHTMLTagAction());
//addAction("hr", new XHTMLTagAction());
//addAction("link", new XHTMLTagAction());
//addAction("param", new XHTMLTagAction());
//addAction("q", new XHTMLTagAction());
//addAction("s", new XHTMLTagAction());
addAction("pre", new XHTMLTagPreAction());
//addAction("big", new XHTMLTagAction());
//addAction("small", new XHTMLTagAction());
//addAction("u", new XHTMLTagAction());
//addAction("table", new XHTMLTagAction());
addAction("td", new XHTMLTagParagraphAction());
addAction("th", new XHTMLTagParagraphAction());
//addAction("tr", new XHTMLTagAction());
//addAction("caption", new XHTMLTagAction());
//addAction("span", new XHTMLTagAction());
if (!ourTagActions.isEmpty()) {
return;
}
//addAction("html", new XHTMLTagAction());
addAction("body", new XHTMLTagBodyAction());
//addAction("title", new XHTMLTagAction());
//addAction("meta", new XHTMLTagAction());
//addAction("script", new XHTMLTagAction());
//addAction("font", new XHTMLTagAction());
//addAction("style", new XHTMLTagAction());
addAction("p", new XHTMLTagParagraphAction());
addAction("h1", new XHTMLTagParagraphWithControlAction(FBTextKind.H1));
addAction("h2", new XHTMLTagParagraphWithControlAction(FBTextKind.H2));
addAction("h3", new XHTMLTagParagraphWithControlAction(FBTextKind.H3));
addAction("h4", new XHTMLTagParagraphWithControlAction(FBTextKind.H4));
addAction("h5", new XHTMLTagParagraphWithControlAction(FBTextKind.H5));
addAction("h6", new XHTMLTagParagraphWithControlAction(FBTextKind.H6));
//addAction("ol", new XHTMLTagAction());
//addAction("ul", new XHTMLTagAction());
//addAction("dl", new XHTMLTagAction());
addAction("li", new XHTMLTagItemAction());
addAction("strong", new XHTMLTagControlAction(FBTextKind.STRONG));
addAction("b", new XHTMLTagControlAction(FBTextKind.BOLD));
addAction("em", new XHTMLTagControlAction(FBTextKind.EMPHASIS));
addAction("i", new XHTMLTagControlAction(FBTextKind.ITALIC));
final XHTMLTagAction codeControlAction = new XHTMLTagControlAction(FBTextKind.CODE);
addAction("code", codeControlAction);
addAction("tt", codeControlAction);
addAction("kbd", codeControlAction);
addAction("var", codeControlAction);
addAction("samp", codeControlAction);
addAction("cite", new XHTMLTagControlAction(FBTextKind.CITE));
addAction("sub", new XHTMLTagControlAction(FBTextKind.SUB));
addAction("sup", new XHTMLTagControlAction(FBTextKind.SUP));
addAction("dd", new XHTMLTagControlAction(FBTextKind.DEFINITION_DESCRIPTION));
addAction("dfn", new XHTMLTagControlAction(FBTextKind.DEFINITION));
addAction("strike", new XHTMLTagControlAction(FBTextKind.STRIKETHROUGH));
addAction("a", new XHTMLTagHyperlinkAction());
addAction("img", new XHTMLTagImageAction("src"));
addAction("object", new XHTMLTagImageAction("data"));
//addAction("area", new XHTMLTagAction());
//addAction("map", new XHTMLTagAction());
//addAction("base", new XHTMLTagAction());
//addAction("blockquote", new XHTMLTagAction());
addAction("br", new XHTMLTagRestartParagraphAction());
//addAction("center", new XHTMLTagAction());
addAction("div", new XHTMLTagParagraphAction());
//addAction("dt", new XHTMLTagAction());
//addAction("head", new XHTMLTagAction());
//addAction("hr", new XHTMLTagAction());
//addAction("link", new XHTMLTagAction());
//addAction("param", new XHTMLTagAction());
//addAction("q", new XHTMLTagAction());
//addAction("s", new XHTMLTagAction());
addAction("pre", new XHTMLTagPreAction());
//addAction("big", new XHTMLTagAction());
//addAction("small", new XHTMLTagAction());
//addAction("u", new XHTMLTagAction());
//addAction("table", new XHTMLTagAction());
addAction("td", new XHTMLTagParagraphAction());
addAction("th", new XHTMLTagParagraphAction());
//addAction("tr", new XHTMLTagAction());
//addAction("caption", new XHTMLTagAction());
//addAction("span", new XHTMLTagAction());
}
private final BookReader myModelReader;

View file

@ -45,6 +45,7 @@ public class ZLFile {
private ZLFileInfo myInfo;
private static final HashMap ourForcedFiles = new HashMap();
private static HashMap<String,ZipFile> ourZipFileMap = new HashMap<String,ZipFile>();
public boolean removeFile(String path) {
File file = new File(path);
@ -196,8 +197,6 @@ public class ZLFile {
return path;
}
//private static HashMap<String,ZipFile> ourZipFileMap = new HashMap<String,ZipFile>();
public InputStream getInputStream() throws IOException {
if (isDirectory()) {
return null;
@ -213,10 +212,13 @@ public class ZLFile {
if (base != null) {
if (0 != (baseFile.myArchiveType & ArchiveType.ZIP)) {
final String baseFileName = myPath.substring(0, index);
ZipFile zf = null;//ourZipFileMap.get(baseFileName);
if (zf == null) {
zf = new ZipFile(baseFileName);
//ourZipFileMap.put(baseFileName, zf);
ZipFile zf;
synchronized (ourZipFileMap) {
zf = ourZipFileMap.get(baseFileName);
if (zf == null) {
zf = new ZipFile(baseFileName);
ourZipFileMap.put(baseFileName, zf);
}
}
/*
ZipEntry entry = zf.getEntry(myPath.substring(index+1));