bool ZTXTStream::fillBuffer() { while (myBufferOffset == myBufferLength) { if (myRecordIndex + 1 > myMaxRecordIndex) { return false; } ++myRecordIndex; size_t currentOffset = myHeader.Offsets[myRecordIndex]; // Hmm, this works on examples from manybooks.net, // but I don't what thi code means :(( if (myRecordIndex == 1) { currentOffset += 2; } if (currentOffset < myBase->offset()) { return false; } myBase->seek(currentOffset, true); size_t nextOffset = (myRecordIndex + 1 < myHeader.Offsets.size()) ? myHeader.Offsets[myRecordIndex + 1] : myBase->sizeOfOpened(); if (nextOffset < currentOffset) { return false; } myBufferLength = ZLZDecompressor(nextOffset - currentOffset).decompress(*myBase, myBuffer, myMaxRecordSize); myBufferOffset = 0; } return true; }
bool EReaderStream::processRecord() { size_t currentOffset = myHeader.Offsets[myRecordIndex]; if (currentOffset < myBase->offset()) { return false; } myBase->seek(currentOffset, true); size_t nextOffset = (myRecordIndex + 1 < myHeader.Offsets.size()) ? myHeader.Offsets[myRecordIndex + 1] : myBase->sizeOfOpened(); 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; }
void PluckerBookReader::readRecord(size_t recordSize) { unsigned short uid; PdbUtil::readUnsignedShort(*myStream, uid); if (uid == 1) { PdbUtil::readUnsignedShort(*myStream, myCompressionVersion); } else { unsigned short paragraphs; PdbUtil::readUnsignedShort(*myStream, paragraphs); unsigned short size; PdbUtil::readUnsignedShort(*myStream, size); unsigned char type; myStream->read((char*)&type, 1); unsigned char flags; myStream->read((char*)&flags, 1); switch (type) { case 0: // text (TODO: found sample file and test this code) case 1: // compressed text { std::vector<int> pars; for (int i = 0; i < paragraphs; ++i) { unsigned short pSize; PdbUtil::readUnsignedShort(*myStream, pSize); pars.push_back(pSize); myStream->seek(2, false); } bool doProcess = false; if (type == 0) { doProcess = myStream->read(myCharBuffer, size) == size; } else if (myCompressionVersion == 1) { doProcess = DocDecompressor().decompress(*myStream, myCharBuffer, recordSize - 8 - 4 * paragraphs, size) == size; } else if (myCompressionVersion == 2) { myStream->seek(2, false); doProcess = ZLZDecompressor(recordSize - 10 - 4 * paragraphs). decompress(*myStream, myCharBuffer, size) == size; } if (doProcess) { addHyperlinkLabel(fromNumber(uid)); myParagraphVector = &myParagraphMap[uid]; processTextRecord(size, pars); if ((flags & 0x1) == 0) { insertEndOfTextParagraph(); } } break; } case 2: // image case 3: // compressed image { static const std::string mime = "image/palm"; ZLImage *image = 0; if (type == 2) { image = new ZLFileImage(mime, myFilePath, myStream->offset(), recordSize - 8); } else if (myCompressionVersion == 1) { image = new DocCompressedFileImage(mime, myFilePath, myStream->offset(), recordSize - 8); } else if (myCompressionVersion == 2) { image = new ZCompressedFileImage(mime, myFilePath, myStream->offset() + 2, recordSize - 10); } if (image != 0) { addImage(fromNumber(uid), image); } break; } case 9: // category record is ignored break; case 10: unsigned short typeCode; PdbUtil::readUnsignedShort(*myStream, typeCode); //std::cerr << "type = " << (int)type << "; "; //std::cerr << "typeCode = " << typeCode << "\n"; break; case 11: // style sheet record is ignored break; case 12: // font page record is ignored break; case 13: // TODO: process tables case 14: // TODO: process tables break; case 15: // multiimage { unsigned short columns; unsigned short rows; PdbUtil::readUnsignedShort(*myStream, columns); PdbUtil::readUnsignedShort(*myStream, rows); PluckerMultiImage *image = new PluckerMultiImage(rows, columns, model().imageMap()); for (int i = 0; i < size / 2 - 2; ++i) { unsigned short us; PdbUtil::readUnsignedShort(*myStream, us); image->addId(fromNumber(us)); } addImage(fromNumber(uid), image); break; } default: //std::cerr << "type = " << (int)type << "\n"; break; } } }