summaryrefslogtreecommitdiffstats
path: root/fbreader/src/formats/pdb/EReaderStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fbreader/src/formats/pdb/EReaderStream.cpp')
-rw-r--r--fbreader/src/formats/pdb/EReaderStream.cpp289
1 files changed, 0 insertions, 289 deletions
diff --git a/fbreader/src/formats/pdb/EReaderStream.cpp b/fbreader/src/formats/pdb/EReaderStream.cpp
deleted file mode 100644
index 9775773..0000000
--- a/fbreader/src/formats/pdb/EReaderStream.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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 <algorithm>
-#include <cctype>
-
-#include <ZLFile.h>
-#include <ZLResource.h>
-#include <ZLZDecompressor.h>
-
-#include "EReaderStream.h"
-#include "DocDecompressor.h"
-
-
-EReaderStream::EReaderStream(const ZLFile &file) : PalmDocLikeStream(file) {
- myDestination = TEXT;
-}
-
-EReaderStream::~EReaderStream() {
- close();
-}
-
-bool EReaderStream::switchStreamDestination(StreamDestination destination, const std::string& id) {
- bool result = true;
- switch(destination) {
- case TEXT:
- myDestination = TEXT;
- myRecordIndex = 1;
- break;
- case FOOTNOTE:
- std::map<std::string, unsigned short>::const_iterator footnoteIt = myFootnotes.find(id);
- if (footnoteIt != myFootnotes.end()) {
- myDestination = FOOTNOTE;
- myRecordIndex = footnoteIt->second;
- } else {
- result = false;
- }
- break;
- }
- return result;
-}
-
-bool EReaderStream::fillBuffer() {
- if (myDestination == TEXT) {
- return PalmDocLikeStream::fillBuffer();
- } else {
- while (myBufferOffset == myBufferLength) {
- if (!processRecord()) {
- return false;
- }
- }
- return true;
- }
-}
-
-bool EReaderStream::processRecord() {
- const std::size_t currentOffset = recordOffset(myRecordIndex);
- if (currentOffset < myBase->offset()) {
- return false;
- }
- myBase->seek(currentOffset, true);
- const std::size_t nextOffset = recordOffset(myRecordIndex + 1);
- if (nextOffset < currentOffset) {
- return false;
- }
-
- unsigned short myCompressedSize = nextOffset - currentOffset;
-
- switch (myCompressionVersion) {
- case 10: // Inflate compression
- myBase->seek(2, false);
- myBufferLength = ZLZDecompressor(myCompressedSize - 2).decompress(*myBase, myBuffer, myMaxRecordSize);
- break;
- case 2: // PalmDoc compression
- myBufferLength = DocDecompressor().decompress(*myBase, myBuffer, myCompressedSize, myMaxRecordSize);
- break;
- }
- clearBuffer('\0');
- myBufferOffset = 0;
- return true;
-}
-
-bool EReaderStream::processZeroRecord() {
- // Use it with offset presetting to zero record offset value
- PdbUtil::readUnsignedShort(*myBase, myCompressionVersion); // myBase offset: ^ + 2
- if (myCompressionVersion > 255) {
- myErrorCode = ERROR_ENCRYPTION;
- return false;
- } else {
- switch (myCompressionVersion) {
- case 2:
- case 10:
- break;
- default:
- myErrorCode = ERROR_COMPRESSION;
- return false;
- }
- }
- myBase->seek(10, false); // myBase offset: ^ + 12
- PdbUtil::readUnsignedShort(*myBase, myNonTextOffset); // myBase offset: ^ + 14
- PdbUtil::readUnsignedShort(*myBase, myNonTextOffsetReserved); // myBase offset: ^ + 16
- myBase->seek(12, false); // myBase offset: ^ + 28
- PdbUtil::readUnsignedShort(*myBase, myFootnoteRecords); // myBase offset: ^ + 30
- PdbUtil::readUnsignedShort(*myBase, mySidebarRecords); // myBase offset: ^ + 32
- PdbUtil::readUnsignedShort(*myBase, myBookmarksOffset); // myBase offset: ^ + 34
- myBase->seek(2, false); // myBase offset: ^ + 36
- PdbUtil::readUnsignedShort(*myBase, myNonTextOffsetExtraReserved); // myBase offset: ^ + 38
- myBase->seek(2, false); // myBase offset: ^ + 40
- PdbUtil::readUnsignedShort(*myBase, myImagedataOffset); // myBase offset: ^ + 42
- PdbUtil::readUnsignedShort(*myBase, myImagedataOffsetReserved); // myBase offset: ^ + 44
- PdbUtil::readUnsignedShort(*myBase, myMetadataOffset); // myBase offset: ^ + 46
- PdbUtil::readUnsignedShort(*myBase, myMetadataOffsetReserved); // myBase offset: ^ + 48
- PdbUtil::readUnsignedShort(*myBase, myFootnoteOffset); // myBase offset: ^ + 50
- PdbUtil::readUnsignedShort(*myBase, mySidebarOffset); // myBase offset: ^ + 52
- PdbUtil::readUnsignedShort(*myBase, myLastdataOffset); // myBase offset: ^ + 54
-
- unsigned short endSectionIndex = header().Offsets.size();
- myMaxRecordIndex = std::min((unsigned short) (myNonTextOffset - 1), (unsigned short) (endSectionIndex - 1));
-
- myMaxRecordSize = 65535; // Maximum size of addressable space in PalmOS
- // not more than 8192 bytes happens in the tested examples
-
- if (myFootnoteRecords) {
- bool isSuccess = processFootnoteIdsRecord();
- if (!isSuccess) {
- //TODO take in account returned bool value
- //false if wrong footnotes amount anounced in zero record
- //or corrupted or wrong footnote ids record
- }
- }
-
- if (myImagedataOffset != myMetadataOffset) {
- bool isSuccess = processImageHeaders();
- if (!isSuccess) {
- //TODO take in account returned bool value
- //false if one of image record is corrupted
- }
- }
-
- myBase->seek(header().Offsets[1], true);
-
- /*
- std::cerr << "EReaderStream::processZeroRecord():\n";
- std::cerr << "PDB header indentificator : " << header().Id << "\n";
- std::cerr << "PDB file system: sizeof opened : " << myBaseSize << "\n";
- std::cerr << "PDB header/record[0] max index : " << myMaxRecordIndex << "\n";
- std::cerr << "PDB record[0][0..2] compression : " << myCompressionVersion << "\n";
- std::cerr << "EReader record[0] myNonTextOffset : " << myNonTextOffset << std::endl;
- std::cerr << "EReader record[0] myNonTextOffset2 : " << myNonTextOffsetReserved << std::endl;
- std::cerr << "EReader record[0] myFootnoteRecords : " << myFootnoteRecords << std::endl;
- std::cerr << "EReader record[0] mySidebarRecords : " << mySidebarRecords << std::endl;
- std::cerr << "EReader record[0] myBookmarksOffset : " << myBookmarksOffset << std::endl;
- std::cerr << "EReader record[0] myNonTextOffset3 : " << myNonTextOffsetExtraReserved << std::endl;
- std::cerr << "EReader record[0] myImagedataOffset : " << myImagedataOffset << std::endl;
- std::cerr << "EReader record[0] myImagedataOffset2 : " << myImagedataOffsetReserved << std::endl;
- std::cerr << "EReader record[0] myMetadataOffset : " << myMetadataOffset << std::endl;
- std::cerr << "EReader record[0] myMetadataOffset2 : " << myMetadataOffsetReserved << std::endl;
- std::cerr << "EReader record[0] myFootnoteOffset : " << myFootnoteOffset << std::endl;
- std::cerr << "EReader record[0] mySidebarOffset : " << mySidebarOffset << std::endl;
- std::cerr << "EReader record[0] myLastdataOffset : " << myLastdataOffset << std::endl;
- std::cerr << "PDB header lastSectionIndex : " << endSectionIndex - 1 << "\n";
- */
- return true;
-}
-
-void EReaderStream::clearBuffer(unsigned char symbol) {
- myBufferLength = std::remove(myBuffer, myBuffer + myBufferLength, symbol) - myBuffer;
-}
-
-bool EReaderStream::processFootnoteIdsRecord() {
- char* footnoteIdBuffer = new char[myMaxRecordSize];
- myBase->seek(header().Offsets[myFootnoteOffset], true);
- const std::size_t currentOffset = recordOffset(myFootnoteOffset);
- const std::size_t nextOffset = recordOffset(myFootnoteOffset + 1);
- const std::size_t length = nextOffset - currentOffset;
- myBase->read(footnoteIdBuffer, length);
- std::string footnoteIdStr(footnoteIdBuffer, length);
- unsigned short footnoteIndex = myFootnoteOffset + 1;
- while (!footnoteIdStr.empty() && (footnoteIndex < myLastdataOffset)) {
- std::string id = findFootnoteId(footnoteIdStr);
- if (!id.empty()) {
- myFootnotes[id] = footnoteIndex;
- ++footnoteIndex;
- }
- }
- delete[] footnoteIdBuffer;
- return (myFootnoteRecords - 1 == (unsigned short)myFootnotes.size());
-}
-
-std::string EReaderStream::findFootnoteId(std::string &footnoteIdStr) const {
- std::string resultStr;
- if (!footnoteIdStr.empty()) {
- std::size_t counter = 0;
- for (; counter < footnoteIdStr.length(); ++counter) {
- if (std::isalnum(footnoteIdStr[counter])) {
- break;
- }
- }
- const std::size_t startIdIndex = counter;
- for (; counter < footnoteIdStr.length(); ++counter) {
- if (footnoteIdStr[counter] == '\0') {
- break;
- }
- }
- const std::size_t endIdIndex = counter;
- resultStr = footnoteIdStr.substr(startIdIndex, endIdIndex - startIdIndex);
- footnoteIdStr = footnoteIdStr.substr(endIdIndex);
- }
- return resultStr;
-}
-
-const std::map<std::string, unsigned short>& EReaderStream::footnotes() const {
- return myFootnotes;
-}
-
-bool EReaderStream::processImageHeaders() {
- unsigned short recordIndex = myImagedataOffset;
- bool result = true;
- myBase->seek(header().Offsets[recordIndex], true);
- while (recordIndex < myMetadataOffset && recordIndex < myLastdataOffset) {
- result = result && addImageInfo(recordIndex);
- ++recordIndex;
- }
- return result;
-}
-
-bool EReaderStream::addImageInfo(const unsigned short recordIndex) {
- const std::size_t bufferLength = 128;
- char *buffer = new char[bufferLength]; //TODO may be it's needed here more bytes
- ImageInfo image;
- const std::size_t currentOffset = recordOffset(recordIndex);
- const std::size_t nextOffset = recordOffset(recordIndex + 1);
-
- myBase->read(buffer, bufferLength);
- std::string header(buffer, bufferLength);
- delete[] buffer;
-
- image.Offset = currentOffset + header.find("\x89PNG"); //TODO treat situation when there isn't PNG in first 128 bytes
- image.Size = nextOffset - image.Offset;
- const int endType = header.find(' ');
- image.Type = ZLMimeType::get(header.substr(0, endType));
- header = header.substr(endType + 1);
- const int endId = header.find('\0');
- const std::string id = header.substr(0, endId);
- myBase->seek(nextOffset - currentOffset - bufferLength, false);
- if (id.empty()) {
- return false;
- }
- myImages[id] = image;
- return true;
-}
-
-
-/*bool EReaderStream::hasExtraSections() const {
- return false;
- //return myMaxRecordIndex < header().Offsets.size() - 1;
-}*/
-
-EReaderStream::ImageInfo EReaderStream::imageLocation(const std::string& id) {
- if (myImagedataOffset != myMetadataOffset && myImages.empty()) {
- processImageHeaders();
- }
- const std::map<std::string, ImageInfo>::const_iterator it = myImages.find(id);
- if (it != myImages.end()) {
- return it->second;
- } else {
- return ImageInfo();
- }
-}
-
-const std::map<std::string, EReaderStream::ImageInfo>& EReaderStream::images() const {
- return myImages;
-}