1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 18:29:23 +02:00
FBReaderJ/jni/NativeFormats/fbreader/src/formats/oeb/OEBPlugin.cpp
2014-06-10 10:17:26 +01:00

157 lines
4.6 KiB
C++

/*
* Copyright (C) 2004-2014 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 <ZLStringUtil.h>
#include <ZLUnicodeUtil.h>
#include <ZLDir.h>
#include <ZLInputStream.h>
#include <ZLLogger.h>
#include <ZLXMLReader.h>
#include "OEBPlugin.h"
#include "OEBMetaInfoReader.h"
#include "OEBEncryptionReader.h"
#include "OEBUidReader.h"
#include "OEBBookReader.h"
#include "OEBCoverReader.h"
#include "OEBTextStream.h"
#include "../../bookmodel/BookModel.h"
#include "../../library/Book.h"
static const std::string OPF = "opf";
static const std::string OEBZIP = "oebzip";
static const std::string EPUB = "epub";
class ContainerFileReader : public ZLXMLReader {
public:
const std::string &rootPath() const;
private:
void startElementHandler(const char *tag, const char **attributes);
private:
std::string myRootPath;
};
const std::string &ContainerFileReader::rootPath() const {
return myRootPath;
}
void ContainerFileReader::startElementHandler(const char *tag, const char **attributes) {
const std::string tagString = ZLUnicodeUtil::toLower(tag);
if (tagString == "rootfile") {
const char *path = attributeValue(attributes, "full-path");
if (path != 0) {
myRootPath = path;
interrupt();
}
}
}
OEBPlugin::~OEBPlugin() {
}
bool OEBPlugin::providesMetaInfo() const {
return true;
}
const std::string OEBPlugin::supportedFileType() const {
return "ePub";
}
ZLFile OEBPlugin::epubFile(const ZLFile &oebFile) {
const ZLFile epub = oebFile.extension() == OPF ? oebFile.getContainerArchive() : oebFile;
epub.forceArchiveType(ZLFile::ZIP);
return epub;
}
ZLFile OEBPlugin::opfFile(const ZLFile &oebFile) {
//ZLLogger::Instance().registerClass("epub");
if (oebFile.extension() == OPF) {
return oebFile;
}
ZLLogger::Instance().println("epub", "Looking for opf file in " + oebFile.path());
oebFile.forceArchiveType(ZLFile::ZIP);
shared_ptr<ZLDir> zipDir = oebFile.directory(false);
if (zipDir.isNull()) {
ZLLogger::Instance().println("epub", "Couldn't open zip archive");
return ZLFile::NO_FILE;
}
const ZLFile containerInfoFile(zipDir->itemPath("META-INF/container.xml"));
if (containerInfoFile.exists()) {
ZLLogger::Instance().println("epub", "Found container file " + containerInfoFile.path());
ContainerFileReader reader;
reader.readDocument(containerInfoFile);
const std::string &opfPath = reader.rootPath();
ZLLogger::Instance().println("epub", "opf path = " + opfPath);
if (!opfPath.empty()) {
return ZLFile(zipDir->itemPath(opfPath));
}
}
std::vector<std::string> fileNames;
zipDir->collectFiles(fileNames, false);
for (std::vector<std::string>::const_iterator it = fileNames.begin(); it != fileNames.end(); ++it) {
ZLLogger::Instance().println("epub", "Item: " + *it);
if (ZLStringUtil::stringEndsWith(*it, ".opf")) {
return ZLFile(zipDir->itemPath(*it));
}
}
ZLLogger::Instance().println("epub", "Opf file not found");
return ZLFile::NO_FILE;
}
bool OEBPlugin::readMetainfo(Book &book) const {
const ZLFile &file = book.file();
return OEBMetaInfoReader(book).readMetainfo(opfFile(file));
}
std::vector<shared_ptr<FileEncryptionInfo> > OEBPlugin::readEncryptionInfos(Book &book) const {
const ZLFile &opf = opfFile(book.file());
return OEBEncryptionReader().readEncryptionInfos(epubFile(opf), opf);
}
bool OEBPlugin::readUids(Book &book) const {
const ZLFile &file = book.file();
return OEBUidReader(book).readUids(opfFile(file));
}
bool OEBPlugin::readModel(BookModel &model) const {
const ZLFile &file = model.book()->file();
return OEBBookReader(model).readBook(opfFile(file));
}
shared_ptr<const ZLImage> OEBPlugin::coverImage(const ZLFile &file) const {
return OEBCoverReader().readCover(opfFile(file));
}
bool OEBPlugin::readLanguageAndEncoding(Book &book) const {
if (book.language().empty()) {
shared_ptr<ZLInputStream> oebStream = new OEBTextStream(opfFile(book.file()));
detectLanguage(book, *oebStream, book.encoding());
}
return true;
}