bool EReaderPlugin::readMetaInfo(Book &book) const { shared_ptr<ZLInputStream> 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); }
bool PluckerBookReader::readDocument() { myStream = ZLFile(myFilePath).inputStream(); if (myStream.isNull() || !myStream->open()) { return false; } PdbHeader header; if (!header.read(myStream)) { myStream->close(); return false; } setMainTextModel(); myFont = FT_REGULAR; for (std::vector<unsigned long>::const_iterator it = header.Offsets.begin(); it != header.Offsets.end(); ++it) { size_t currentOffset = myStream->offset(); if (currentOffset > *it) { break; } myStream->seek(*it - currentOffset, false); if (myStream->offset() != *it) { break; } size_t recordSize = ((it != header.Offsets.end() - 1) ? *(it + 1) : myStream->sizeOfOpened()) - *it; readRecord(recordSize); } myStream->close(); for (std::set<std::pair<int,int> >::const_iterator it = myReferencedParagraphs.begin(); it != myReferencedParagraphs.end(); ++it) { std::map<int,std::vector<int> >::const_iterator jt = myParagraphMap.find(it->first); if (jt != myParagraphMap.end()) { for (unsigned int k = it->second; k < jt->second.size(); ++k) { if (jt->second[k] != -1) { addHyperlinkLabel(fromNumber(it->first) + '#' + fromNumber(it->second), jt->second[k]); break; } } } } myReferencedParagraphs.clear(); myParagraphMap.clear(); return true; }
bool MobipocketPlugin::readDescription(const std::string &path, BookDescription &description) const { shared_ptr<ZLInputStream> stream = ZLFile(path).inputStream(); if (stream.isNull() || ! stream->open()) { return false; } PdbHeader header; if (!header.read(stream)) { return false; } stream->seek(header.Offsets[0] + 16, true); char test[5]; test[4] = '\0'; stream->read(test, 4); static const std::string MOBI = "MOBI"; if (MOBI != test) { return PalmDocLikePlugin::readDescription(path, description); } WritableBookDescription wDescription(description); unsigned long length; PdbUtil::readUnsignedLong(*stream, length); stream->seek(4, false); unsigned long encodingCode; PdbUtil::readUnsignedLong(*stream, encodingCode); if (wDescription.encoding().empty()) { ZLEncodingConverterInfoPtr info = ZLEncodingCollection::instance().info(encodingCode); if (!info.isNull()) { wDescription.encoding() = info->name(); } } stream->seek(52, false); unsigned long fullNameOffset; PdbUtil::readUnsignedLong(*stream, fullNameOffset); unsigned long fullNameLength; PdbUtil::readUnsignedLong(*stream, fullNameLength); unsigned long languageCode; PdbUtil::readUnsignedLong(*stream, languageCode); wDescription.language() = ZLLanguageUtil::languageByCode(languageCode & 0xFF, (languageCode >> 8) & 0xFF); stream->seek(32, false); unsigned long exthFlags; PdbUtil::readUnsignedLong(*stream, exthFlags); if (exthFlags & 0x40) { stream->seek(header.Offsets[0] + 16 + length, true); stream->read(test, 4); static const std::string EXTH = "EXTH"; if (EXTH == test) { stream->seek(4, false); unsigned long recordsNum; PdbUtil::readUnsignedLong(*stream, recordsNum); for (unsigned long i = 0; i < recordsNum; ++i) { unsigned long type; PdbUtil::readUnsignedLong(*stream, type); unsigned long size; PdbUtil::readUnsignedLong(*stream, size); if (size > 8) { std::string value(size - 8, '\0'); stream->read((char*)value.data(), size - 8); switch (type) { case 100: { int index = value.find(','); if (index != -1) { std::string part0 = value.substr(0, index); std::string part1 = value.substr(index + 1); ZLStringUtil::stripWhiteSpaces(part0); ZLStringUtil::stripWhiteSpaces(part1); value = part1 + ' ' + part0; } else { ZLStringUtil::stripWhiteSpaces(value); } wDescription.addAuthor(value); break; } case 105: wDescription.addTag(value); break; } } } } } stream->seek(header.Offsets[0] + fullNameOffset, true); std::string title(fullNameLength, '\0'); stream->read((char*)title.data(), fullNameLength); wDescription.title() = title; stream->close(); return PalmDocLikePlugin::readDescription(path, description); }