1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 17:59:33 +02:00

better RTF encoding detection; don't fail on RTF files with .doc extension; fixed XML serialisation

This commit is contained in:
Nikolay Pultsin 2015-02-14 12:20:05 +00:00
parent a6c8ead2bf
commit 7e9d47bba9
5 changed files with 84 additions and 33 deletions

View file

@ -6,11 +6,13 @@
* (planned) Fixed authors list/tags list editing
* (planned) CSS selectors priority
===== 2.3 (Feb ??, 2015) =====
===== 2.3 (Feb 14, 2015) =====
* File format filter option (can be changed from the bookshelf plugin)
* Samsung multi-window support
* Bookshelf view item in the library
* Updated Persian localisation by biomanw (https://github.com/biomanw)
* Better RTF encoding detection
* Don't fail on RTF files with .doc extension
===== 2.2.7 (Jan 30, 2015) =====
* Fixed behaviour for pages with multiple images (fb2.zip only)

View file

@ -7,7 +7,7 @@
<node name="txt" value="txt"/>
<node name="msdoc" value="Microsoft Word"/>
<node name="HTML" value="HTML"/>
<node name="rtf" value="RTF"/>
<node name="RTF" value="RTF"/>
<node name="PDF" value="PDF"/>
<node name="DjVu" value="DjVu"/>
<node name="CBZ" value="Comic book archive (cbz, cbr)"/>

View file

@ -27,6 +27,7 @@
#include "DocMetaInfoReader.h"
#include "DocBookReader.h"
#include "DocStreams.h"
#include "../rtf/RtfPlugin.h"
#include "../../bookmodel/BookModel.h"
#include "../../library/Book.h"
@ -36,6 +37,17 @@ DocPlugin::DocPlugin() {
DocPlugin::~DocPlugin() {
}
static bool isRtf(const Book &book) {
shared_ptr<ZLInputStream> stream = book.file().inputStream();
if (stream.isNull() || !stream->open()) {
return false;
}
char buffer[6] = { 0 };
stream->read(buffer, 5);
static const std::string RTF_BYTES = "{\\rtf";
return RTF_BYTES == buffer;
}
bool DocPlugin::providesMetainfo() const {
return true;
}
@ -49,6 +61,10 @@ bool DocPlugin::acceptsFile(const ZLFile &file) const {
}
bool DocPlugin::readMetainfo(Book &book) const {
if (::isRtf(book)) {
return RtfPlugin().readMetainfo(book);
}
if (!DocMetaInfoReader(book).readMetainfo()) {
return false;
}
@ -71,5 +87,9 @@ bool DocPlugin::readLanguageAndEncoding(Book &/*book*/) const {
}
bool DocPlugin::readModel(BookModel &model) const {
if (::isRtf(*model.book())) {
return RtfPlugin().readModel(model);
}
return DocBookReader(model, model.book()->encoding()).readBook();
}

View file

@ -34,23 +34,16 @@ bool RtfPlugin::providesMetainfo() const {
}
const std::string RtfPlugin::supportedFileType() const {
return "rtf";
return "RTF";
}
bool RtfPlugin::readMetainfo(Book &book) const {
readLanguageAndEncoding(book);
if (!RtfDescriptionReader(book).readDocument(book.file())) {
return false;
}
if (book.encoding().empty()) {
book.setEncoding(ZLEncodingConverter::UTF8);
} else if (book.language().empty()) {
shared_ptr<ZLInputStream> stream = new RtfReaderStream(book.file(), 50000);
if (!stream.isNull()) {
detectLanguage(book, *stream, book.encoding());
}
}
return true;
}
@ -64,5 +57,19 @@ bool RtfPlugin::readModel(BookModel &model) const {
}
bool RtfPlugin::readLanguageAndEncoding(Book &book) const {
if (book.encoding().empty()) {
shared_ptr<ZLInputStream> stream = new RtfReaderStream(book.file(), 50000);
if (!stream.isNull()) {
detectEncodingAndLanguage(book, *stream);
}
if (book.encoding().empty()) {
book.setEncoding(ZLEncodingConverter::UTF8);
}
} else if (book.language().empty()) {
shared_ptr<ZLInputStream> stream = new RtfReaderStream(book.file(), 50000);
if (!stream.isNull()) {
detectLanguage(book, *stream, book.encoding());
}
}
return true;
}

View file

@ -35,9 +35,13 @@ import org.geometerplus.zlibrary.core.util.ZLColor;
import org.geometerplus.zlibrary.text.view.ZLTextPosition;
class XMLSerializer extends AbstractSerializer {
private StringBuilder builder() {
return new StringBuilder("<?xml version='1.1' encoding='UTF-8'?>");
}
@Override
public String serialize(BookQuery query) {
final StringBuilder buffer = new StringBuilder();
final StringBuilder buffer = builder();
appendTag(buffer, "query", false,
"limit", String.valueOf(query.Limit),
"page", String.valueOf(query.Page)
@ -136,7 +140,7 @@ class XMLSerializer extends AbstractSerializer {
@Override
public String serialize(BookmarkQuery query) {
final StringBuilder buffer = new StringBuilder();
final StringBuilder buffer = builder();
appendTag(buffer, "query", false,
"visible", String.valueOf(query.Visible),
"limit", String.valueOf(query.Limit),
@ -164,7 +168,7 @@ class XMLSerializer extends AbstractSerializer {
@Override
public String serialize(Book book) {
final StringBuilder buffer = new StringBuilder();
final StringBuilder buffer = builder();
serialize(buffer, book);
return buffer.toString();
}
@ -262,7 +266,7 @@ class XMLSerializer extends AbstractSerializer {
@Override
public String serialize(Bookmark bookmark) {
final StringBuilder buffer = new StringBuilder();
final StringBuilder buffer = builder();
appendTag(
buffer, "bookmark", false,
"id", String.valueOf(bookmark.getId()),
@ -325,7 +329,7 @@ class XMLSerializer extends AbstractSerializer {
@Override
public String serialize(HighlightingStyle style) {
final StringBuilder buffer = new StringBuilder();
final StringBuilder buffer = builder();
final ZLColor bgColor = style.getBackgroundColor();
final ZLColor fgColor = style.getForegroundColor();
appendTag(buffer, "style", true,
@ -441,23 +445,41 @@ class XMLSerializer extends AbstractSerializer {
}
}
private static String escapeForXml(String data) {
if (data.indexOf('&') != -1) {
data = data.replaceAll("&", "&amp;");
private static CharSequence escapeForXml(String data) {
final StringBuilder buffer = new StringBuilder();
final int len = data.length();
for (int i = 0; i < len; ++i) {
final char ch = data.charAt(i);
switch (ch) {
case '\u0009':
buffer.append(ch);
break;
default:
if ((ch >= '\u0020' && ch <= '\uD7FF') ||
(ch >= '\u0E00' && ch <= '\uFFFD')) {
buffer.append(ch);
}
break;
case '&':
buffer.append("&amp;");
break;
case '<':
buffer.append("&lt;");
break;
case '>':
buffer.append("&gt;");
break;
case '"':
buffer.append("&quot;");
break;
case '\'':
buffer.append("&apos;");
break;
}
}
if (data.indexOf('<') != -1) {
data = data.replaceAll("<", "&lt;");
}
if (data.indexOf('>') != -1) {
data = data.replaceAll(">", "&gt;");
}
if (data.indexOf('\'') != -1) {
data = data.replaceAll("'", "&apos;");
}
if (data.indexOf('"') != -1) {
data = data.replaceAll("\"", "&quot;");
}
return data;
return buffer;
}
private static void clear(StringBuilder buffer) {