package org.geometerplus.fbreader.formats.txt;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.geometerplus.fbreader.bookmodel.BookModel;
import org.geometerplus.fbreader.bookmodel.BookReader;
import org.geometerplus.fbreader.formats.JavaFormatPlugin;
import org.geometerplus.fbreader.library.ReadBook;
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
import org.geometerplus.zlibrary.core.filesystem.ZLTxtPhysicalFile;
import org.geometerplus.zlibrary.core.image.ZLImage;
import org.geometerplus.zlibrary.core.util.ZLArrayUtils;
import com.chineseall.reader.ui.view.FileLocalCache;
import com.chineseall.readerapi.exception.ErrorMsgException;
import com.chineseall.readerapi.util.LogUtil;
public class TxtPlugin extends JavaFormatPlugin {
private static final int BUFF_SIZE = 512 * 1024;
private static byte[] readBuffer = new byte[BUFF_SIZE];
BookReader txtReader;
public TxtPlugin() {
super(ZLTxtPhysicalFile.ExtensionName);
}
@Override
public String readAnnotation(ZLFile file) {
// TODO Auto-generated method stub
return null;
}
@Override
public ZLImage readCover(ZLFile file) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean readMetaInfo(ReadBook book) {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean readModel(BookModel model) {
// LogUtil.startTime("readmodel");
txtReader = new BookReader(model);
txtReader.setMainTextModel();
// LogUtil.endTime("readmodel");
LogUtil.startTime("read");
readContent(model.Book.File.getPath());
LogUtil.endTime("read");
return true;
}
private byte[] myUnderflowByteBuffer = new byte[4];
private int myUnderflowLength;
private int myTextBufferLength;
private char[] myTextBuffer = new char[512 * 1024];
CharsetDecoder myByteDecoder = null;
public final void addByteData(byte[] data, int start, int length) {
final int oldLength = myTextBufferLength;
// LogUtil.startTime("addbyte");
if (myTextBuffer.length < oldLength + length) {
myTextBuffer = ZLArrayUtils.createCopy(myTextBuffer, oldLength, oldLength + length);
}
final CharBuffer cb = CharBuffer.wrap(myTextBuffer, myTextBufferLength, length);
if (myUnderflowLength > 0) {
int l = myUnderflowLength;
while (length-- > 0 && l < 4) {
myUnderflowByteBuffer[l++] = data[start++];
final ByteBuffer ubb = ByteBuffer.wrap(myUnderflowByteBuffer);
myByteDecoder.decode(ubb, cb, false);
if (cb.position() != oldLength) {
myUnderflowLength = 0;
break;
}
}
if (length == 0) {
myUnderflowLength = l;
return;
}
}
// LogUtil.endTime("addbyte");
//
// LogUtil.startTime("addcontent");
ByteBuffer bb = ByteBuffer.wrap(data, start, length);
myByteDecoder.decode(bb, cb, false);
myTextBufferLength = cb.position();
int rem = bb.remaining();
if (rem > 0) {
for (int i = 0, j = start + length - rem; i < rem;) {
myUnderflowByteBuffer[i++] = data[j++];
}
myUnderflowLength = rem;
}
// LogUtil.startTime("=====addcontentData=");
addContentsData(myTextBuffer, oldLength, myTextBufferLength - oldLength);
// LogUtil.endTime("=====addcontentData=");
// LogUtil.endTime("addcontent");
}
/**
* 获取byte[]对应的格式化的段落字符数组
* 一个段落为一个一维的字符数组
* @param data
* @param start
* @param length
* @param isFrontToLastDataBlock 该数据块是不是位于上次操作数据块前面
* @return
*/
public final char[][] getFormatsParaphData(byte[] data, int start, int length, boolean isFrontToLastDataBlock) {
if(isFrontToLastDataBlock)
{
myUnderflowLength = 0;
}
final int oldLength = myTextBufferLength;
if (myTextBuffer.length < oldLength + length) {
myTextBuffer = ZLArrayUtils.createCopy(myTextBuffer, oldLength, oldLength + length);
}
final CharBuffer cb = CharBuffer.wrap(myTextBuffer, myTextBufferLength, length);
if (myUnderflowLength > 0) {
int l = myUnderflowLength;
while (length-- > 0 && l < 4) {
myUnderflowByteBuffer[l++] = data[start++];
final ByteBuffer ubb = ByteBuffer.wrap(myUnderflowByteBuffer);
myByteDecoder.decode(ubb, cb, false);
if (cb.position() != oldLength) {
myUnderflowLength = 0;
break;
}
}
if (length == 0) {
myUnderflowLength = l;
return null;
}
}
ByteBuffer bb = ByteBuffer.wrap(data, start, length);
myByteDecoder.decode(bb, cb, false);
myTextBufferLength = cb.position();
int rem = bb.remaining();
if (rem > 0) {
for (int i = 0, j = start + length - rem; i < rem;) {
myUnderflowByteBuffer[i++] = data[j++];
}
myUnderflowLength = rem;
}
return getContentsData(myTextBuffer, oldLength, myTextBufferLength - oldLength);
}
/**
*
*/
private StringBuilder cacheBuffer = new StringBuilder(1024 * 256);
private StringBuilder headerBuffer = new StringBuilder();
private StringBuilder endBuffer = new StringBuilder();
private char[][] getContentsData(char[] charBuffer, int offset, int length)
{
//cacheBuffer此时内容若不为空,则为上次读取时,末尾未结尾的段落内容.
if(charBuffer != null)
{
cacheBuffer.insert(0, headerBuffer);
headerBuffer.delete(0, headerBuffer.length());
cacheBuffer.append(headerBuffer, offset, length);
cacheBuffer.insert(cacheBuffer.length(), endBuffer);
endBuffer.delete(0, endBuffer.length());
}
charBuffer = null;
String formatContents =formatParagraph(cacheBuffer.toString());
String[] chapterContents = formatContents.split("\r\n");
formatContents = null;
char[][] contentData = null;
if(chapterContents.length > 2)
{
headerBuffer.append(chapterContents[0]);
contentData = new char[chapterContents.length - 2][];
for(int i = 1; i < chapterContents.length - 1; i++)
{
contentData[i - 1] = chapterContents[i].toCharArray();
chapterContents[i] = null;
}
endBuffer.append(chapterContents[chapterContents.length - 1]);
}
else
{
headerBuffer.append(chapterContents[0]);
endBuffer.append(chapterContents[0]);
}
chapterContents[chapterContents.length - 1] = null;
myTextBufferLength = 0;
chapterContents = null;
return contentData;
}
private void addContentsData(char[] charBuffer, int offset,
FBReader支持txt插件
最新推荐文章于 2021-05-28 22:47:32 发布