bool PdfBookReader::readReferenceTable(ZLInputStream &stream, int xrefOffset) {
	while (true) {
		stream.seek(xrefOffset, true);
		readLine(stream, myBuffer);
		stripBuffer(myBuffer);
		if (myBuffer != "xref") {
			return false;
		}

		while (true) {
			readLine(stream, myBuffer);
			stripBuffer(myBuffer);
			if (myBuffer == "trailer") {
				break;
			}
			const int index = myBuffer.find(' ');
			const int start = atoi(myBuffer.c_str());
			const int len = atoi(myBuffer.c_str() + index + 1);
			for (int i = 0; i < len; ++i) {
				readLine(stream, myBuffer);
				stripBuffer(myBuffer);
				if (myBuffer.length() != 18) {
					return false;
				}
				const int objectOffset = atoi(myBuffer.c_str());
				const int objectGeneration = atoi(myBuffer.c_str() + 11);
				const bool objectInUse = myBuffer[17] == 'n';
				if (objectInUse) {
					myObjectLocationMap[std::pair<int,int>(start + i, objectGeneration)] = objectOffset;
				}
			}
		}
		char ch = 0;
		shared_ptr<PdfObject> trailer = PdfObject::readObject(stream, ch);
		if (trailer.isNull() || (trailer->type() != PdfObject::DICTIONARY)) {
			return false;
		}
		if (myTrailer.isNull()) {
			myTrailer = trailer;
		}
		PdfDictionaryObject &trailerDictionary = (PdfDictionaryObject&)*trailer;
		shared_ptr<PdfObject> previous = trailerDictionary["Prev"];
		if (previous.isNull()) {
			return true;
		}

		if (previous->type() != PdfObject::INTEGER_NUMBER) {
			return false;
		}
		xrefOffset = ((PdfIntegerObject&)*previous).value();
	}
}
Esempio n. 2
0
void FoamObject::readFile(QString file_name)
{
  file_name = m_CaseDir + "/" + file_name;
  if(m_BufferedFileName != m_CaseDir + "/" + file_name) {
    m_BufferedFileName = file_name;
    QFile file(file_name);
    if (!file.open(QIODevice::ReadOnly)) {
      EG_ERR_RETURN(QString("error loading file:\n") + file_name);
    }
    QTextStream f(&file);
    m_Buffer = "";
    m_Buffer.reserve(file.size());
    while(!f.atEnd())
    {
      m_Buffer += f.readLine() + "\n";
    }
    stripBuffer();
  }
}
bool PdfBookReader::readBook(shared_ptr<ZLInputStream> stream) {
	if (stream.isNull() || !stream->open()) {
		return false;
	}

	readLine(*stream, myBuffer);
	if (!ZLStringUtil::stringStartsWith(myBuffer, "%PDF-")) {
		return false;
	}

	std::string version = myBuffer.substr(5);
	std::cerr << "version = " << version << "\n";

	size_t eofOffset = stream->sizeOfOpened();
	if (eofOffset < 100) {
		return false;
	}

	stream->seek(eofOffset - 100, true);
	bool readXrefOffset = false;
	size_t xrefOffset = (size_t)-1;
	while (true) {
		readLine(*stream, myBuffer);
		if (myBuffer.empty()) {
			break;
		}
		stripBuffer(myBuffer);
		if (readXrefOffset) {
			if (!myBuffer.empty()) {
				xrefOffset = atoi(myBuffer.c_str());
				break;
			}
		} else if (myBuffer == "startxref") {
			readXrefOffset = true;
		}
	}

	if (!readReferenceTable(*stream, xrefOffset)) {
		return false;
	}

	PdfDictionaryObject &trailerDictionary = (PdfDictionaryObject&)*myTrailer;
	shared_ptr<PdfObject> root = resolveReference(trailerDictionary["Root"], *stream);
	if (root.isNull() || (root->type() != PdfObject::DICTIONARY)) {
		return false;
	}

	PdfDictionaryObject &rootDictionary = (PdfDictionaryObject&)*root;
	if (rootDictionary["Type"] != PdfNameObject::nameObject("Catalog")) {
		return false;
	}
	shared_ptr<PdfObject> pageRootNode = resolveReference(rootDictionary["Pages"], *stream);
	if (pageRootNode.isNull() || (pageRootNode->type() != PdfObject::DICTIONARY)) {
		return false;
	}
	PdfDictionaryObject &pageRootNodeDictionary = (PdfDictionaryObject&)*pageRootNode;
	if (pageRootNodeDictionary["Type"] != PdfNameObject::nameObject("Pages")) {
		return false;
	}
	
	/*
	shared_ptr<PdfObject> count = pageRootNodeDictionary["Count"];
	if (!count.isNull() && (count->type() == PdfObject::INTEGER_NUMBER)) {
		std::cerr << "count = " << ((PdfIntegerObject&)*count).value() << "\n";
	}
	*/
	shared_ptr<PdfObject> pages = pageRootNodeDictionary["Kids"];
	if (pages.isNull() || (pages->type() != PdfObject::ARRAY)) {
		return false;
	}
	const PdfArrayObject& pagesArray = (const PdfArrayObject&)*pages;
	const size_t pageNumber = pagesArray.size();
	for (size_t i = 0; i < pageNumber; ++i) {
		processPage(pagesArray[i], *stream);
	}

	return true;
}