/* * Copyright (C) 2004-2012 Geometer Plus * * 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 #include #include #include #include #include #include "PdbPlugin.h" #include "EReaderStream.h" #include "PmlBookReader.h" #include "../../library/Book.h" bool EReaderPlugin::providesMetaInfo() const { return true; } bool EReaderPlugin::acceptsFile(const ZLFile &file) const { return PdbPlugin::fileType(file) == "PNRdPPrs"; } void EReaderPlugin::readDocumentInternal(const ZLFile &file, BookModel &model, const PlainTextFormat &format, const std::string &encoding, ZLInputStream &stream) const { if (!stream.open()) { //TODO maybe anything else opens stream return; } BookReader bookReader(model); PmlBookReader pmlBookReader(bookReader, format, encoding); bookReader.setMainTextModel(); pmlBookReader.readDocument(stream); EReaderStream &estream = (EReaderStream&)stream; const std::map& imageIds = estream.images(); for(std::map::const_iterator it = imageIds.begin(); it != imageIds.end(); ++it) { const std::string id = it->first; bookReader.addImage(id, new ZLFileImage(ZLFile(file.path(), it->second.Type), it->second.Offset, it->second.Size)); } const std::map& footnoteIds = estream.footnotes(); for(std::map::const_iterator it = footnoteIds.begin(); it != footnoteIds.end(); ++it) { const std::string id = it->first; if (estream.switchStreamDestination(EReaderStream::FOOTNOTE, id)) { bookReader.setFootnoteTextModel(id); bookReader.addHyperlinkLabel(id); pmlBookReader.readDocument(estream); } } stream.close(); } shared_ptr EReaderPlugin::createStream(const ZLFile &file) const { return new EReaderStream(file); } const std::string &EReaderPlugin::tryOpen(const ZLFile &file) const { EReaderStream stream(file); stream.open(); return stream.error(); } bool EReaderPlugin::readMetaInfo(Book &book) const { shared_ptr stream = book.file().inputStream(); if (stream.isNull() || ! stream->open()) { return false; } PdbHeader header; if (!header.read(stream)) { return false; } stream->seek(header.Offsets[0] + 46, true); unsigned short metaInfoOffset; PdbUtil::readUnsignedShort(*stream, metaInfoOffset); if (metaInfoOffset == 0 || metaInfoOffset >= header.Offsets.size()) { return false; } std::size_t currentOffset = header.Offsets[metaInfoOffset]; std::size_t nextOffset = (metaInfoOffset + 1 < (unsigned short)header.Offsets.size()) ? header.Offsets[metaInfoOffset + 1] : stream->sizeOfOpened(); if (nextOffset <= currentOffset) { return false; } std::size_t length = nextOffset - currentOffset; char* metaInfoBuffer = new char[length]; stream->seek(currentOffset, true); stream->read(metaInfoBuffer, length); std::string metaInfoStr(metaInfoBuffer, length); delete[] metaInfoBuffer; std::string metaInfoData[5]; // Title; Author; Rights; Publisher; isbn; for (std::size_t i = 0; i < 5; ++i) { const std::size_t index = metaInfoStr.find('\0'); metaInfoData[i] = metaInfoStr.substr(0,index); metaInfoStr = metaInfoStr.substr(index + 1); } if (!metaInfoData[0].empty()) { book.setTitle(metaInfoData[0]); } if (!metaInfoData[1].empty()) { book.addAuthor(metaInfoData[1]); } stream->close(); return SimplePdbPlugin::readMetaInfo(book); }