mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-04 02:09:35 +02:00
fb2 plugin code is included into master branch
This commit is contained in:
parent
29e018ee65
commit
ae40ca59a6
12 changed files with 1248 additions and 0 deletions
326
jni/NativeFormats/fbreader/src/formats/fb2/FB2BookReader.cpp
Normal file
326
jni/NativeFormats/fbreader/src/formats/fb2/FB2BookReader.cpp
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
#include <ZLBase64EncodedImage.h>
|
||||||
|
|
||||||
|
#include <ZLTextParagraph.h>
|
||||||
|
|
||||||
|
#include "FB2BookReader.h"
|
||||||
|
#include "../../library/Book.h"
|
||||||
|
#include "../../bookmodel/BookModel.h"
|
||||||
|
|
||||||
|
FB2BookReader::FB2BookReader(BookModel &model) : myModelReader(model) {
|
||||||
|
myInsideCoverpage = false;
|
||||||
|
myParagraphsBeforeBodyNumber = (size_t)-1;
|
||||||
|
myInsidePoem = false;
|
||||||
|
mySectionDepth = 0;
|
||||||
|
myBodyCounter = 0;
|
||||||
|
myReadMainText = false;
|
||||||
|
myCurrentImage = 0;
|
||||||
|
myProcessingImage = false;
|
||||||
|
mySectionStarted = false;
|
||||||
|
myInsideTitle = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2BookReader::characterDataHandler(const char *text, size_t len) {
|
||||||
|
if ((len > 0) && (myProcessingImage || myModelReader.paragraphIsOpen())) {
|
||||||
|
std::string str(text, len);
|
||||||
|
if (myProcessingImage) {
|
||||||
|
myImageBuffer.push_back(str);
|
||||||
|
} else {
|
||||||
|
myModelReader.addData(str);
|
||||||
|
if (myInsideTitle) {
|
||||||
|
myModelReader.addContentsData(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2BookReader::startElementHandler(int tag, const char **xmlattributes) {
|
||||||
|
const char *id = attributeValue(xmlattributes, "id");
|
||||||
|
if (id != 0) {
|
||||||
|
if (!myReadMainText) {
|
||||||
|
myModelReader.setFootnoteTextModel(id);
|
||||||
|
}
|
||||||
|
myModelReader.addHyperlinkLabel(id);
|
||||||
|
}
|
||||||
|
switch (tag) {
|
||||||
|
case _P:
|
||||||
|
if (mySectionStarted) {
|
||||||
|
mySectionStarted = false;
|
||||||
|
} else if (myInsideTitle) {
|
||||||
|
static const std::string SPACE = " ";
|
||||||
|
myModelReader.addContentsData(SPACE);
|
||||||
|
}
|
||||||
|
myModelReader.beginParagraph();
|
||||||
|
break;
|
||||||
|
case _V:
|
||||||
|
myModelReader.pushKind(VERSE);
|
||||||
|
myModelReader.beginParagraph();
|
||||||
|
break;
|
||||||
|
case _SUBTITLE:
|
||||||
|
myModelReader.pushKind(SUBTITLE);
|
||||||
|
myModelReader.beginParagraph();
|
||||||
|
break;
|
||||||
|
case _TEXT_AUTHOR:
|
||||||
|
myModelReader.pushKind(AUTHOR);
|
||||||
|
myModelReader.beginParagraph();
|
||||||
|
break;
|
||||||
|
case _DATE:
|
||||||
|
myModelReader.pushKind(DATEKIND);
|
||||||
|
myModelReader.beginParagraph();
|
||||||
|
break;
|
||||||
|
case _CITE:
|
||||||
|
myModelReader.pushKind(CITE);
|
||||||
|
break;
|
||||||
|
case _SECTION:
|
||||||
|
if (myReadMainText) {
|
||||||
|
myModelReader.insertEndOfSectionParagraph();
|
||||||
|
++mySectionDepth;
|
||||||
|
myModelReader.beginContentsParagraph();
|
||||||
|
mySectionStarted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _TITLE:
|
||||||
|
if (myInsidePoem) {
|
||||||
|
myModelReader.pushKind(POEM_TITLE);
|
||||||
|
} else if (mySectionDepth == 0) {
|
||||||
|
myModelReader.insertEndOfSectionParagraph();
|
||||||
|
myModelReader.pushKind(TITLE);
|
||||||
|
} else {
|
||||||
|
myModelReader.pushKind(SECTION_TITLE);
|
||||||
|
myModelReader.enterTitle();
|
||||||
|
myInsideTitle = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _POEM:
|
||||||
|
myInsidePoem = true;
|
||||||
|
break;
|
||||||
|
case _STANZA:
|
||||||
|
myModelReader.pushKind(STANZA);
|
||||||
|
myModelReader.beginParagraph(ZLTextParagraph::BEFORE_SKIP_PARAGRAPH);
|
||||||
|
myModelReader.endParagraph();
|
||||||
|
break;
|
||||||
|
case _EPIGRAPH:
|
||||||
|
myModelReader.pushKind(EPIGRAPH);
|
||||||
|
break;
|
||||||
|
case _ANNOTATION:
|
||||||
|
if (myBodyCounter == 0) {
|
||||||
|
myModelReader.setMainTextModel();
|
||||||
|
}
|
||||||
|
myModelReader.pushKind(ANNOTATION);
|
||||||
|
break;
|
||||||
|
case _COVERPAGE:
|
||||||
|
if (myBodyCounter == 0) {
|
||||||
|
myInsideCoverpage = true;
|
||||||
|
myModelReader.setMainTextModel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _SUB:
|
||||||
|
myModelReader.addControl(SUB, true);
|
||||||
|
break;
|
||||||
|
case _SUP:
|
||||||
|
myModelReader.addControl(SUP, true);
|
||||||
|
break;
|
||||||
|
case _CODE:
|
||||||
|
myModelReader.addControl(CODE, true);
|
||||||
|
break;
|
||||||
|
case _STRIKETHROUGH:
|
||||||
|
myModelReader.addControl(STRIKETHROUGH, true);
|
||||||
|
break;
|
||||||
|
case _STRONG:
|
||||||
|
myModelReader.addControl(STRONG, true);
|
||||||
|
break;
|
||||||
|
case _EMPHASIS:
|
||||||
|
myModelReader.addControl(EMPHASIS, true);
|
||||||
|
break;
|
||||||
|
case _A:
|
||||||
|
{
|
||||||
|
const std::string hrefName = xlinkNamespace() + ":href";
|
||||||
|
const char *ref = attributeValue(xmlattributes, hrefName.c_str());
|
||||||
|
if (ref != 0) {
|
||||||
|
if (ref[0] == '#') {
|
||||||
|
const char *type = attributeValue(xmlattributes, "type");
|
||||||
|
static const std::string NOTE = "note";
|
||||||
|
if ((type != 0) && (NOTE == type)) {
|
||||||
|
myHyperlinkType = FOOTNOTE;
|
||||||
|
} else {
|
||||||
|
myHyperlinkType = INTERNAL_HYPERLINK;
|
||||||
|
}
|
||||||
|
++ref;
|
||||||
|
} else {
|
||||||
|
myHyperlinkType = EXTERNAL_HYPERLINK;
|
||||||
|
}
|
||||||
|
myModelReader.addHyperlinkControl(myHyperlinkType, ref);
|
||||||
|
} else {
|
||||||
|
myHyperlinkType = FOOTNOTE;
|
||||||
|
myModelReader.addControl(myHyperlinkType, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _IMAGE:
|
||||||
|
{
|
||||||
|
const std::string hrefName = xlinkNamespace() + ":href";
|
||||||
|
const char *ref = attributeValue(xmlattributes, hrefName.c_str());
|
||||||
|
//const char *vOffset = attributeValue(xmlattributes, "voffset");
|
||||||
|
//char offset = (vOffset != 0) ? atoi(vOffset) : 0;
|
||||||
|
if ((ref != 0) && (*ref == '#')) {
|
||||||
|
++ref;
|
||||||
|
if ((myCoverImageReference != ref) ||
|
||||||
|
(myParagraphsBeforeBodyNumber != myModelReader.model().bookTextModel()->paragraphsNumber())) {
|
||||||
|
myModelReader.addImageReference(ref);
|
||||||
|
}
|
||||||
|
if (myInsideCoverpage) {
|
||||||
|
myCoverImageReference = ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _BINARY:
|
||||||
|
{
|
||||||
|
static const std::string STRANGE_MIME_TYPE = "text/xml";
|
||||||
|
const char *contentType = attributeValue(xmlattributes, "content-type");
|
||||||
|
if ((contentType != 0) && (id != 0) && (STRANGE_MIME_TYPE != contentType)) {
|
||||||
|
myCurrentImage = new ZLBase64EncodedImage(contentType);
|
||||||
|
myCurrentImageId.assign(id);
|
||||||
|
myProcessingImage = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _EMPTY_LINE:
|
||||||
|
myModelReader.beginParagraph(ZLTextParagraph::EMPTY_LINE_PARAGRAPH);
|
||||||
|
myModelReader.endParagraph();
|
||||||
|
break;
|
||||||
|
case _BODY:
|
||||||
|
++myBodyCounter;
|
||||||
|
myParagraphsBeforeBodyNumber = myModelReader.model().bookTextModel()->paragraphsNumber();
|
||||||
|
if ((myBodyCounter == 1) || (attributeValue(xmlattributes, "name") == 0)) {
|
||||||
|
myModelReader.setMainTextModel();
|
||||||
|
myReadMainText = true;
|
||||||
|
}
|
||||||
|
myModelReader.pushKind(REGULAR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2BookReader::endElementHandler(int tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case _P:
|
||||||
|
myModelReader.endParagraph();
|
||||||
|
break;
|
||||||
|
case _V:
|
||||||
|
case _SUBTITLE:
|
||||||
|
case _TEXT_AUTHOR:
|
||||||
|
case _DATE:
|
||||||
|
myModelReader.popKind();
|
||||||
|
myModelReader.endParagraph();
|
||||||
|
break;
|
||||||
|
case _CITE:
|
||||||
|
myModelReader.popKind();
|
||||||
|
break;
|
||||||
|
case _SECTION:
|
||||||
|
if (myReadMainText) {
|
||||||
|
myModelReader.endContentsParagraph();
|
||||||
|
--mySectionDepth;
|
||||||
|
mySectionStarted = false;
|
||||||
|
} else {
|
||||||
|
myModelReader.unsetTextModel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _TITLE:
|
||||||
|
myModelReader.exitTitle();
|
||||||
|
myModelReader.popKind();
|
||||||
|
myInsideTitle = false;
|
||||||
|
break;
|
||||||
|
case _POEM:
|
||||||
|
myInsidePoem = false;
|
||||||
|
break;
|
||||||
|
case _STANZA:
|
||||||
|
myModelReader.beginParagraph(ZLTextParagraph::AFTER_SKIP_PARAGRAPH);
|
||||||
|
myModelReader.endParagraph();
|
||||||
|
myModelReader.popKind();
|
||||||
|
break;
|
||||||
|
case _EPIGRAPH:
|
||||||
|
myModelReader.popKind();
|
||||||
|
break;
|
||||||
|
case _ANNOTATION:
|
||||||
|
myModelReader.popKind();
|
||||||
|
if (myBodyCounter == 0) {
|
||||||
|
myModelReader.insertEndOfSectionParagraph();
|
||||||
|
myModelReader.unsetTextModel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _COVERPAGE:
|
||||||
|
if (myBodyCounter == 0) {
|
||||||
|
myInsideCoverpage = false;
|
||||||
|
myModelReader.insertEndOfSectionParagraph();
|
||||||
|
myModelReader.unsetTextModel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _SUB:
|
||||||
|
myModelReader.addControl(SUB, false);
|
||||||
|
break;
|
||||||
|
case _SUP:
|
||||||
|
myModelReader.addControl(SUP, false);
|
||||||
|
break;
|
||||||
|
case _CODE:
|
||||||
|
myModelReader.addControl(CODE, false);
|
||||||
|
break;
|
||||||
|
case _STRIKETHROUGH:
|
||||||
|
myModelReader.addControl(STRIKETHROUGH, false);
|
||||||
|
break;
|
||||||
|
case _STRONG:
|
||||||
|
myModelReader.addControl(STRONG, false);
|
||||||
|
break;
|
||||||
|
case _EMPHASIS:
|
||||||
|
myModelReader.addControl(EMPHASIS, false);
|
||||||
|
break;
|
||||||
|
case _A:
|
||||||
|
myModelReader.addControl(myHyperlinkType, false);
|
||||||
|
break;
|
||||||
|
case _BINARY:
|
||||||
|
if (!myImageBuffer.empty() && !myCurrentImageId.empty() && myCurrentImage != 0) {
|
||||||
|
myCurrentImage->addData(myImageBuffer);
|
||||||
|
myModelReader.addImage(myCurrentImageId, myCurrentImage);
|
||||||
|
myImageBuffer.clear();
|
||||||
|
myCurrentImageId.clear();
|
||||||
|
myCurrentImage = 0;
|
||||||
|
}
|
||||||
|
myProcessingImage = false;
|
||||||
|
break;
|
||||||
|
case _BODY:
|
||||||
|
myModelReader.popKind();
|
||||||
|
myModelReader.unsetTextModel();
|
||||||
|
myReadMainText = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2BookReader::readBook() {
|
||||||
|
return readDocument(myModelReader.model().book()->file());
|
||||||
|
}
|
60
jni/NativeFormats/fbreader/src/formats/fb2/FB2BookReader.h
Normal file
60
jni/NativeFormats/fbreader/src/formats/fb2/FB2BookReader.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2BOOKREADER_H__
|
||||||
|
#define __FB2BOOKREADER_H__
|
||||||
|
|
||||||
|
#include "FB2Reader.h"
|
||||||
|
#include "../../bookmodel/BookReader.h"
|
||||||
|
|
||||||
|
class BookModel;
|
||||||
|
class ZLBase64EncodedImage;
|
||||||
|
|
||||||
|
class FB2BookReader : public FB2Reader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB2BookReader(BookModel &model);
|
||||||
|
bool readBook();
|
||||||
|
|
||||||
|
void startElementHandler(int tag, const char **attributes);
|
||||||
|
void endElementHandler(int tag);
|
||||||
|
void characterDataHandler(const char *text, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int mySectionDepth;
|
||||||
|
int myBodyCounter;
|
||||||
|
bool myReadMainText;
|
||||||
|
bool myInsideCoverpage;
|
||||||
|
size_t myParagraphsBeforeBodyNumber;
|
||||||
|
std::string myCoverImageReference;
|
||||||
|
bool myInsidePoem;
|
||||||
|
BookReader myModelReader;
|
||||||
|
|
||||||
|
ZLBase64EncodedImage *myCurrentImage;
|
||||||
|
std::string myCurrentImageId;
|
||||||
|
bool myProcessingImage;
|
||||||
|
std::vector<std::string> myImageBuffer;
|
||||||
|
|
||||||
|
bool mySectionStarted;
|
||||||
|
bool myInsideTitle;
|
||||||
|
|
||||||
|
FBTextKind myHyperlinkType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FB2BOOKREADER_H__ */
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLBase64EncodedImage.h>
|
||||||
|
|
||||||
|
#include "FB2CoverReader.h"
|
||||||
|
|
||||||
|
#include "../../library/Book.h"
|
||||||
|
|
||||||
|
FB2CoverReader::FB2CoverReader(const ZLFile &file) : myFile(file) {
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ZLImage> FB2CoverReader::readCover() {
|
||||||
|
myReadCoverPage = false;
|
||||||
|
myImageReference.erase();
|
||||||
|
readDocument(myFile);
|
||||||
|
return myImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2CoverReader::startElementHandler(int tag, const char **attributes) {
|
||||||
|
switch (tag) {
|
||||||
|
case _COVERPAGE:
|
||||||
|
myReadCoverPage = true;
|
||||||
|
break;
|
||||||
|
case _IMAGE:
|
||||||
|
if (myReadCoverPage) {
|
||||||
|
const std::string hrefName = xlinkNamespace() + ":href";
|
||||||
|
const char *ref = attributeValue(attributes, hrefName.c_str());
|
||||||
|
if (ref != 0 && *ref == '#' && *(ref + 1) != '\0') {
|
||||||
|
myImageReference = ref + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _BINARY:
|
||||||
|
{
|
||||||
|
const char *id = attributeValue(attributes, "id");
|
||||||
|
const char *contentType = attributeValue(attributes, "content-type");
|
||||||
|
if (id != 0 && contentType != 0 && myImageReference == id) {
|
||||||
|
myImage = new ZLBase64EncodedImage(contentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2CoverReader::endElementHandler(int tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case _COVERPAGE:
|
||||||
|
myReadCoverPage = false;
|
||||||
|
break;
|
||||||
|
case _DESCRIPTION:
|
||||||
|
if (myImageReference.empty()) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _BINARY:
|
||||||
|
if (!myImage.isNull()) {
|
||||||
|
if (!myImageBuffer.empty()) {
|
||||||
|
((ZLBase64EncodedImage&)*myImage).addData(myImageBuffer);
|
||||||
|
myImageBuffer.clear();
|
||||||
|
} else {
|
||||||
|
myImage = 0;
|
||||||
|
}
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2CoverReader::characterDataHandler(const char *text, size_t len) {
|
||||||
|
if (len > 0 && !myImage.isNull()) {
|
||||||
|
myImageBuffer.push_back(std::string(text, len));
|
||||||
|
}
|
||||||
|
}
|
48
jni/NativeFormats/fbreader/src/formats/fb2/FB2CoverReader.h
Normal file
48
jni/NativeFormats/fbreader/src/formats/fb2/FB2CoverReader.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2COVERREADER_H__
|
||||||
|
#define __FB2COVERREADER_H__
|
||||||
|
|
||||||
|
#include "FB2Reader.h"
|
||||||
|
|
||||||
|
class Book;
|
||||||
|
class ZLfile;
|
||||||
|
class ZLImage;
|
||||||
|
|
||||||
|
class FB2CoverReader : public FB2Reader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB2CoverReader(const ZLFile &file);
|
||||||
|
shared_ptr<ZLImage> readCover();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void startElementHandler(int tag, const char **attributes);
|
||||||
|
void endElementHandler(int tag);
|
||||||
|
void characterDataHandler(const char *text, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ZLFile myFile;
|
||||||
|
bool myReadCoverPage;
|
||||||
|
std::string myImageReference;
|
||||||
|
shared_ptr<ZLImage> myImage;
|
||||||
|
std::vector<std::string> myImageBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FB2COVERREADER_H__ */
|
206
jni/NativeFormats/fbreader/src/formats/fb2/FB2MetaInfoReader.cpp
Normal file
206
jni/NativeFormats/fbreader/src/formats/fb2/FB2MetaInfoReader.cpp
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <ZLInputStream.h>
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
|
||||||
|
#include "FB2MetaInfoReader.h"
|
||||||
|
#include "FB2TagManager.h"
|
||||||
|
|
||||||
|
#include "../../library/Book.h"
|
||||||
|
|
||||||
|
FB2MetaInfoReader::FB2MetaInfoReader(Book &book) : myBook(book) {
|
||||||
|
myBook.removeAllAuthors();
|
||||||
|
myBook.setTitle(std::string());
|
||||||
|
myBook.setLanguage(std::string());
|
||||||
|
myBook.removeAllTags();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2MetaInfoReader::characterDataHandler(const char *text, size_t len) {
|
||||||
|
switch (myReadState) {
|
||||||
|
case READ_TITLE:
|
||||||
|
myBuffer.append(text, len);
|
||||||
|
break;
|
||||||
|
case READ_LANGUAGE:
|
||||||
|
myBuffer.append(text, len);
|
||||||
|
break;
|
||||||
|
case READ_AUTHOR_NAME_0:
|
||||||
|
myAuthorNames[0].append(text, len);
|
||||||
|
break;
|
||||||
|
case READ_AUTHOR_NAME_1:
|
||||||
|
myAuthorNames[1].append(text, len);
|
||||||
|
break;
|
||||||
|
case READ_AUTHOR_NAME_2:
|
||||||
|
myAuthorNames[2].append(text, len);
|
||||||
|
break;
|
||||||
|
case READ_GENRE:
|
||||||
|
myBuffer.append(text, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2MetaInfoReader::startElementHandler(int tag, const char **attributes) {
|
||||||
|
switch (tag) {
|
||||||
|
case _BODY:
|
||||||
|
myReturnCode = true;
|
||||||
|
interrupt();
|
||||||
|
break;
|
||||||
|
case _TITLE_INFO:
|
||||||
|
myReadState = READ_SOMETHING;
|
||||||
|
break;
|
||||||
|
case _BOOK_TITLE:
|
||||||
|
if (myReadState == READ_SOMETHING) {
|
||||||
|
myReadState = READ_TITLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _GENRE:
|
||||||
|
if (myReadState == READ_SOMETHING) {
|
||||||
|
myReadState = READ_GENRE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _AUTHOR:
|
||||||
|
if (myReadState == READ_SOMETHING) {
|
||||||
|
myReadState = READ_AUTHOR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _LANG:
|
||||||
|
if (myReadState == READ_SOMETHING) {
|
||||||
|
myReadState = READ_LANGUAGE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _FIRST_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR) {
|
||||||
|
myReadState = READ_AUTHOR_NAME_0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _MIDDLE_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR) {
|
||||||
|
myReadState = READ_AUTHOR_NAME_1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _LAST_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR) {
|
||||||
|
myReadState = READ_AUTHOR_NAME_2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _SEQUENCE:
|
||||||
|
if (myReadState == READ_SOMETHING) {
|
||||||
|
const char *name = attributeValue(attributes, "name");
|
||||||
|
if (name != 0) {
|
||||||
|
std::string seriesTitle = name;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(seriesTitle);
|
||||||
|
const char *number = attributeValue(attributes, "number");
|
||||||
|
myBook.setSeries(seriesTitle, number != 0 ? atoi(number) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2MetaInfoReader::endElementHandler(int tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case _TITLE_INFO:
|
||||||
|
myReadState = READ_NOTHING;
|
||||||
|
break;
|
||||||
|
case _BOOK_TITLE:
|
||||||
|
if (myReadState == READ_TITLE) {
|
||||||
|
myBook.setTitle(myBuffer);
|
||||||
|
myBuffer.erase();
|
||||||
|
myReadState = READ_SOMETHING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _GENRE:
|
||||||
|
if (myReadState == READ_GENRE) {
|
||||||
|
ZLStringUtil::stripWhiteSpaces(myBuffer);
|
||||||
|
if (!myBuffer.empty()) {
|
||||||
|
const std::vector<std::string> &tags =
|
||||||
|
FB2TagManager::Instance().humanReadableTags(myBuffer);
|
||||||
|
if (!tags.empty()) {
|
||||||
|
for (std::vector<std::string>::const_iterator it = tags.begin(); it != tags.end(); ++it) {
|
||||||
|
myBook.addTag(*it);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
myBook.addTag(myBuffer);
|
||||||
|
}
|
||||||
|
myBuffer.erase();
|
||||||
|
}
|
||||||
|
myReadState = READ_SOMETHING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _AUTHOR:
|
||||||
|
if (myReadState == READ_AUTHOR) {
|
||||||
|
ZLStringUtil::stripWhiteSpaces(myAuthorNames[0]);
|
||||||
|
ZLStringUtil::stripWhiteSpaces(myAuthorNames[1]);
|
||||||
|
ZLStringUtil::stripWhiteSpaces(myAuthorNames[2]);
|
||||||
|
std::string fullName = myAuthorNames[0];
|
||||||
|
if (!fullName.empty() && !myAuthorNames[1].empty()) {
|
||||||
|
fullName += ' ';
|
||||||
|
}
|
||||||
|
fullName += myAuthorNames[1];
|
||||||
|
if (!fullName.empty() && !myAuthorNames[2].empty()) {
|
||||||
|
fullName += ' ';
|
||||||
|
}
|
||||||
|
fullName += myAuthorNames[2];
|
||||||
|
myBook.addAuthor(fullName, myAuthorNames[2]);
|
||||||
|
myAuthorNames[0].erase();
|
||||||
|
myAuthorNames[1].erase();
|
||||||
|
myAuthorNames[2].erase();
|
||||||
|
myReadState = READ_SOMETHING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _LANG:
|
||||||
|
if (myReadState == READ_LANGUAGE) {
|
||||||
|
myBook.setLanguage(myBuffer);
|
||||||
|
myBuffer.erase();
|
||||||
|
myReadState = READ_SOMETHING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _FIRST_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR_NAME_0) {
|
||||||
|
myReadState = READ_AUTHOR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _MIDDLE_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR_NAME_1) {
|
||||||
|
myReadState = READ_AUTHOR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _LAST_NAME:
|
||||||
|
if (myReadState == READ_AUTHOR_NAME_2) {
|
||||||
|
myReadState = READ_AUTHOR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2MetaInfoReader::readMetaInfo() {
|
||||||
|
myReadState = READ_NOTHING;
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
myAuthorNames[i].erase();
|
||||||
|
}
|
||||||
|
return readDocument(myBook.file());
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2METAINFOREADER_H__
|
||||||
|
#define __FB2METAINFOREADER_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "FB2Reader.h"
|
||||||
|
|
||||||
|
class Book;
|
||||||
|
|
||||||
|
class FB2MetaInfoReader : public FB2Reader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB2MetaInfoReader(Book &book);
|
||||||
|
bool readMetaInfo();
|
||||||
|
|
||||||
|
void startElementHandler(int tag, const char **attributes);
|
||||||
|
void endElementHandler(int tag);
|
||||||
|
void characterDataHandler(const char *text, size_t len);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Book &myBook;
|
||||||
|
|
||||||
|
bool myReturnCode;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
READ_NOTHING,
|
||||||
|
READ_SOMETHING,
|
||||||
|
READ_TITLE,
|
||||||
|
READ_AUTHOR,
|
||||||
|
READ_AUTHOR_NAME_0,
|
||||||
|
READ_AUTHOR_NAME_1,
|
||||||
|
READ_AUTHOR_NAME_2,
|
||||||
|
READ_LANGUAGE,
|
||||||
|
READ_GENRE
|
||||||
|
} myReadState;
|
||||||
|
|
||||||
|
std::string myAuthorNames[3];
|
||||||
|
std::string myBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FB2METAINFOREADER_H__ */
|
46
jni/NativeFormats/fbreader/src/formats/fb2/FB2Plugin.cpp
Normal file
46
jni/NativeFormats/fbreader/src/formats/fb2/FB2Plugin.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLImage.h>
|
||||||
|
|
||||||
|
#include "FB2Plugin.h"
|
||||||
|
#include "FB2MetaInfoReader.h"
|
||||||
|
#include "FB2BookReader.h"
|
||||||
|
#include "FB2CoverReader.h"
|
||||||
|
|
||||||
|
const std::string FB2Plugin::supportedFileType() const {
|
||||||
|
return "fb2";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2Plugin::readMetaInfo(Book &book) const {
|
||||||
|
return FB2MetaInfoReader(book).readMetaInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2Plugin::readModel(BookModel &model) const {
|
||||||
|
return FB2BookReader(model).readBook();
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ZLImage> FB2Plugin::coverImage(const ZLFile &file) const {
|
||||||
|
return FB2CoverReader(file).readCover();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2Plugin::readLanguageAndEncoding(Book &book) const {
|
||||||
|
return true;
|
||||||
|
}
|
42
jni/NativeFormats/fbreader/src/formats/fb2/FB2Plugin.h
Normal file
42
jni/NativeFormats/fbreader/src/formats/fb2/FB2Plugin.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2PLUGIN_H__
|
||||||
|
#define __FB2PLUGIN_H__
|
||||||
|
|
||||||
|
#include "../FormatPlugin.h"
|
||||||
|
|
||||||
|
class FB2Plugin : public FormatPlugin {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB2Plugin();
|
||||||
|
~FB2Plugin();
|
||||||
|
bool providesMetaInfo() const;
|
||||||
|
const std::string supportedFileType() const;
|
||||||
|
bool readMetaInfo(Book &book) const;
|
||||||
|
bool readLanguageAndEncoding(Book &book) const;
|
||||||
|
bool readModel(BookModel &model) const;
|
||||||
|
shared_ptr<ZLImage> coverImage(const ZLFile &file) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FB2Plugin::FB2Plugin() {}
|
||||||
|
inline FB2Plugin::~FB2Plugin() {}
|
||||||
|
inline bool FB2Plugin::providesMetaInfo() const { return true; }
|
||||||
|
|
||||||
|
#endif /* __FB2PLUGIN_H__ */
|
101
jni/NativeFormats/fbreader/src/formats/fb2/FB2Reader.cpp
Normal file
101
jni/NativeFormats/fbreader/src/formats/fb2/FB2Reader.cpp
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <ZLibrary.h>
|
||||||
|
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
#include <ZLXMLNamespace.h>
|
||||||
|
|
||||||
|
#include "FB2Reader.h"
|
||||||
|
#include "../util/EntityFilesCollector.h"
|
||||||
|
|
||||||
|
void FB2Reader::startElementHandler(const char *t, const char **attributes) {
|
||||||
|
startElementHandler(tag(t), attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2Reader::endElementHandler(const char *t) {
|
||||||
|
endElementHandler(tag(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const FB2Reader::Tag TAGS[] = {
|
||||||
|
{"p", FB2Reader::_P},
|
||||||
|
{"subtitle", FB2Reader::_SUBTITLE},
|
||||||
|
{"cite", FB2Reader::_CITE},
|
||||||
|
{"text-author", FB2Reader::_TEXT_AUTHOR},
|
||||||
|
{"date", FB2Reader::_DATE},
|
||||||
|
{"section", FB2Reader::_SECTION},
|
||||||
|
{"v", FB2Reader::_V},
|
||||||
|
{"title", FB2Reader::_TITLE},
|
||||||
|
{"poem", FB2Reader::_POEM},
|
||||||
|
{"stanza", FB2Reader::_STANZA},
|
||||||
|
{"epigraph", FB2Reader::_EPIGRAPH},
|
||||||
|
{"annotation", FB2Reader::_ANNOTATION},
|
||||||
|
{"sub", FB2Reader::_SUB},
|
||||||
|
{"sup", FB2Reader::_SUP},
|
||||||
|
{"code", FB2Reader::_CODE},
|
||||||
|
{"strikethrough", FB2Reader::_STRIKETHROUGH},
|
||||||
|
{"strong", FB2Reader::_STRONG},
|
||||||
|
{"emphasis", FB2Reader::_EMPHASIS},
|
||||||
|
{"a", FB2Reader::_A},
|
||||||
|
{"image", FB2Reader::_IMAGE},
|
||||||
|
{"binary", FB2Reader::_BINARY},
|
||||||
|
{"description", FB2Reader::_DESCRIPTION},
|
||||||
|
{"body", FB2Reader::_BODY},
|
||||||
|
{"empty-line", FB2Reader::_EMPTY_LINE},
|
||||||
|
{"title-info", FB2Reader::_TITLE_INFO},
|
||||||
|
{"book-title", FB2Reader::_BOOK_TITLE},
|
||||||
|
{"author", FB2Reader::_AUTHOR},
|
||||||
|
{"lang", FB2Reader::_LANG},
|
||||||
|
{"first-name", FB2Reader::_FIRST_NAME},
|
||||||
|
{"middle-name", FB2Reader::_MIDDLE_NAME},
|
||||||
|
{"last-name", FB2Reader::_LAST_NAME},
|
||||||
|
{"coverpage", FB2Reader::_COVERPAGE},
|
||||||
|
{"sequence", FB2Reader::_SEQUENCE},
|
||||||
|
{"genre", FB2Reader::_GENRE},
|
||||||
|
{0, FB2Reader::_UNKNOWN}
|
||||||
|
};
|
||||||
|
|
||||||
|
int FB2Reader::tag(const char *name) {
|
||||||
|
for (int i = 0; ; ++i) {
|
||||||
|
if ((TAGS[i].tagName == 0) || (strcmp(name, TAGS[i].tagName) == 0)) {
|
||||||
|
return TAGS[i].tagCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FB2Reader::processNamespaces() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2Reader::namespaceListChangedHandler() {
|
||||||
|
const std::map<std::string,std::string> namespaceMap = namespaces();
|
||||||
|
for (std::map<std::string,std::string>::const_iterator it = namespaceMap.begin(); it != namespaceMap.end(); ++it) {
|
||||||
|
if (ZLStringUtil::stringStartsWith(it->second, ZLXMLNamespace::XLink)) {
|
||||||
|
myXLinkNamespace = it->first;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myXLinkNamespace.erase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2Reader::collectExternalEntities(std::map<std::string,std::string> &entityMap) {
|
||||||
|
entityMap["FBReaderVersion"] = ZLibrary::Version();
|
||||||
|
}
|
100
jni/NativeFormats/fbreader/src/formats/fb2/FB2Reader.h
Normal file
100
jni/NativeFormats/fbreader/src/formats/fb2/FB2Reader.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2004-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2READER_H__
|
||||||
|
#define __FB2READER_H__
|
||||||
|
|
||||||
|
#include <ZLXMLReader.h>
|
||||||
|
|
||||||
|
class FB2Reader : public ZLXMLReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Tag {
|
||||||
|
const char *tagName;
|
||||||
|
int tagCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual int tag(const char *name);
|
||||||
|
|
||||||
|
virtual void startElementHandler(int tag, const char **attributes) = 0;
|
||||||
|
virtual void endElementHandler(int tag) = 0;
|
||||||
|
|
||||||
|
const std::string &xlinkNamespace() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void startElementHandler(const char *tag, const char **attributes);
|
||||||
|
void endElementHandler(const char *tag);
|
||||||
|
bool processNamespaces() const;
|
||||||
|
void namespaceListChangedHandler();
|
||||||
|
|
||||||
|
void collectExternalEntities(std::map<std::string,std::string> &entityMap);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum TagCode {
|
||||||
|
_P,
|
||||||
|
_SUBTITLE,
|
||||||
|
_CITE,
|
||||||
|
_TEXT_AUTHOR,
|
||||||
|
_DATE,
|
||||||
|
_SECTION,
|
||||||
|
_V,
|
||||||
|
_TITLE,
|
||||||
|
_POEM,
|
||||||
|
_STANZA,
|
||||||
|
_EPIGRAPH,
|
||||||
|
_ANNOTATION,
|
||||||
|
_SUB,
|
||||||
|
_SUP,
|
||||||
|
_CODE,
|
||||||
|
_STRIKETHROUGH,
|
||||||
|
_STRONG,
|
||||||
|
_EMPHASIS,
|
||||||
|
_A,
|
||||||
|
_IMAGE,
|
||||||
|
_BINARY,
|
||||||
|
_DESCRIPTION,
|
||||||
|
_BODY,
|
||||||
|
_EMPTY_LINE,
|
||||||
|
_TITLE_INFO,
|
||||||
|
_BOOK_TITLE,
|
||||||
|
_AUTHOR,
|
||||||
|
_LANG,
|
||||||
|
_FIRST_NAME,
|
||||||
|
_MIDDLE_NAME,
|
||||||
|
_LAST_NAME,
|
||||||
|
_COVERPAGE,
|
||||||
|
_SEQUENCE,
|
||||||
|
_GENRE,
|
||||||
|
_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FB2Reader();
|
||||||
|
~FB2Reader();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string myXLinkNamespace;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FB2Reader::FB2Reader() {}
|
||||||
|
inline FB2Reader::~FB2Reader() {}
|
||||||
|
inline const std::string &FB2Reader::xlinkNamespace() const { return myXLinkNamespace; }
|
||||||
|
|
||||||
|
#endif /* __FB2READER_H__ */
|
124
jni/NativeFormats/fbreader/src/formats/fb2/FB2TagManager.cpp
Normal file
124
jni/NativeFormats/fbreader/src/formats/fb2/FB2TagManager.cpp
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <ZLFile.h>
|
||||||
|
#include <ZLXMLReader.h>
|
||||||
|
#include <ZLibrary.h>
|
||||||
|
#include <ZLStringUtil.h>
|
||||||
|
|
||||||
|
#include "FB2TagManager.h"
|
||||||
|
|
||||||
|
class FB2TagInfoReader : public ZLXMLReader {
|
||||||
|
|
||||||
|
public:
|
||||||
|
FB2TagInfoReader(std::map<std::string,std::vector<std::string> > &tagMap);
|
||||||
|
|
||||||
|
void startElementHandler(const char *tag, const char **attributes);
|
||||||
|
void endElementHandler(const char *tag);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string,std::vector<std::string> > &myTagMap;
|
||||||
|
|
||||||
|
std::string myCategoryName;
|
||||||
|
std::string mySubCategoryName;
|
||||||
|
std::vector<std::string> myGenreIds;
|
||||||
|
std::string myLanguage;
|
||||||
|
};
|
||||||
|
|
||||||
|
FB2TagInfoReader::FB2TagInfoReader(std::map<std::string,std::vector<std::string> > &tagMap) : myTagMap(tagMap) {
|
||||||
|
myLanguage = ZLibrary::Language();
|
||||||
|
if (myLanguage != "ru") {
|
||||||
|
myLanguage = "en";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string CATEGORY_NAME_TAG = "root-descr";
|
||||||
|
static const std::string SUBCATEGORY_NAME_TAG = "genre-descr";
|
||||||
|
static const std::string GENRE_TAG = "genre";
|
||||||
|
static const std::string SUBGENRE_TAG = "subgenre";
|
||||||
|
static const std::string SUBGENRE_ALT_TAG = "genre-alt";
|
||||||
|
|
||||||
|
void FB2TagInfoReader::startElementHandler(const char *tag, const char **attributes) {
|
||||||
|
if ((SUBGENRE_TAG == tag) || (SUBGENRE_ALT_TAG == tag)) {
|
||||||
|
const char *id = attributeValue(attributes, "value");
|
||||||
|
if (id != 0) {
|
||||||
|
myGenreIds.push_back(id);
|
||||||
|
}
|
||||||
|
} else if (CATEGORY_NAME_TAG == tag) {
|
||||||
|
const char *lang = attributeValue(attributes, "lang");
|
||||||
|
if ((lang != 0) && (myLanguage == lang)) {
|
||||||
|
const char *name = attributeValue(attributes, "genre-title");
|
||||||
|
if (name != 0) {
|
||||||
|
myCategoryName = name;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(myCategoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (SUBCATEGORY_NAME_TAG == tag) {
|
||||||
|
const char *lang = attributeValue(attributes, "lang");
|
||||||
|
if ((lang != 0) && (myLanguage == lang)) {
|
||||||
|
const char *name = attributeValue(attributes, "title");
|
||||||
|
if (name != 0) {
|
||||||
|
mySubCategoryName = name;
|
||||||
|
ZLStringUtil::stripWhiteSpaces(mySubCategoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FB2TagInfoReader::endElementHandler(const char *tag) {
|
||||||
|
if (GENRE_TAG == tag) {
|
||||||
|
myCategoryName.erase();
|
||||||
|
mySubCategoryName.erase();
|
||||||
|
myGenreIds.clear();
|
||||||
|
} else if (SUBGENRE_TAG == tag) {
|
||||||
|
if (!myCategoryName.empty() && !mySubCategoryName.empty()) {
|
||||||
|
const std::string fullTagName = myCategoryName + '/' + mySubCategoryName;
|
||||||
|
for (std::vector<std::string>::const_iterator it = myGenreIds.begin(); it != myGenreIds.end(); ++it) {
|
||||||
|
myTagMap[*it].push_back(fullTagName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mySubCategoryName.erase();
|
||||||
|
myGenreIds.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FB2TagManager *FB2TagManager::ourInstance = 0;
|
||||||
|
|
||||||
|
const FB2TagManager &FB2TagManager::Instance() {
|
||||||
|
if (ourInstance == 0) {
|
||||||
|
ourInstance = new FB2TagManager();
|
||||||
|
}
|
||||||
|
return *ourInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
FB2TagManager::FB2TagManager() {
|
||||||
|
FB2TagInfoReader(myTagMap).readDocument(ZLFile(
|
||||||
|
ZLibrary::ApplicationDirectory() + ZLibrary::FileNameDelimiter +
|
||||||
|
"formats" + ZLibrary::FileNameDelimiter + "fb2" +
|
||||||
|
ZLibrary::FileNameDelimiter + "fb2genres.xml"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> &FB2TagManager::humanReadableTags(const std::string &id) const {
|
||||||
|
static const std::vector<std::string> EMPTY;
|
||||||
|
std::map<std::string,std::vector<std::string> >::const_iterator it = myTagMap.find(id);
|
||||||
|
return (it != myTagMap.end()) ? it->second : EMPTY;
|
||||||
|
}
|
45
jni/NativeFormats/fbreader/src/formats/fb2/FB2TagManager.h
Normal file
45
jni/NativeFormats/fbreader/src/formats/fb2/FB2TagManager.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008-2012 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __FB2TAGMANAGER_H__
|
||||||
|
#define __FB2TAGMANAGER_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class FB2TagManager {
|
||||||
|
|
||||||
|
private:
|
||||||
|
static FB2TagManager *ourInstance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const FB2TagManager &Instance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FB2TagManager();
|
||||||
|
|
||||||
|
public:
|
||||||
|
const std::vector<std::string> &humanReadableTags(const std::string &id) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string,std::vector<std::string> > myTagMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FB2TAGMANAGER_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue