/**
* @file TxtReader.java
*
* @revision: none
*
* @version 0.0.01
* @author: Zenki (zhajun), zenki2001cn@163.com
* @date: 2011-6-20 下午01:52:00
*/
package org.geometerplus.fbreader.formats.txt;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.geometerplus.fbreader.bookmodel.BookModel;
import org.geometerplus.fbreader.bookmodel.BookReader;
abstract public class TxtReader extends BookReader {
static private final String TAG = "TxtReader";
protected final int BUFSIZE = 65535;
protected final int TAB_EQUAL_SPACE = 4;
protected final String mEncoding;
public TxtReader(BookModel model) {
super(model);
mEncoding = model.Book.getEncoding();
}
abstract protected void startDocumentHandler();
abstract protected void endDocumentHandler();
abstract protected boolean characterDataHandler(String str);
abstract protected boolean spaceDataHandler(int num);
abstract protected boolean newLineHandler();
abstract protected boolean newEmptyLineHandler();
public boolean readDocument(InputStream stream) {
if (null == stream) {
return false;
}
startDocumentHandler();
byte[] buffer = new byte[BUFSIZE];
String str = null;
int length = 0;
int start = 0;
int charsetLen = 0;
boolean skipNewLine = false;
do {
start = 0;
try {
length = stream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < length; i++) {
skipNewLine = false;
switch (buffer[i]) {
// new line
case '\n':
case '\r': {
if ((buffer[i] == '\r') && ((i + 1) < length)
&& (buffer[i + 1] == '\n')) {
skipNewLine = true;
}
if (charsetLen > 0) {
try {
str = new String(buffer, start, charsetLen,
mEncoding);
characterDataHandler(str);
charsetLen = 0;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
newLineHandler();
} else {
newEmptyLineHandler();
}
if (skipNewLine) {
++i;
}
start = i + 1;
}
break;
// space char handler
case 0x08:
case 0x0B:
case 0x0C:
case ' ': {
if (charsetLen > 0) {
try {
str = new String(buffer, start, charsetLen,
mEncoding);
characterDataHandler(str);
charsetLen = 0;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
spaceDataHandler(1);
start = i + 1;
}
break;
// horizontal tab handler
case '\t': {
int lack = TAB_EQUAL_SPACE;
if (charsetLen > 0) {
try {
str = new String(buffer, start, charsetLen,
mEncoding);
characterDataHandler(str);
charsetLen = 0;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
int left = charsetLen % TAB_EQUAL_SPACE;
if (left > 0) {
lack = TAB_EQUAL_SPACE - left;
} else {
lack = TAB_EQUAL_SPACE;
}
}
spaceDataHandler(lack);
start = i + 1;
}
break;
// normal char handler
default: {
charsetLen++;
}
break;
}
}
} while (length == BUFSIZE);
endDocumentHandler();
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}