/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/config.h>
#include <memory>
#include <test/bootstrapfixture.hxx>
#include <unotest/macros_test.hxx>
#include <vcl/filter/pdfdocument.hxx>
class PDFDocumentTest : public test::BootstrapFixture, public unotest::MacrosTest
{
public :
PDFDocumentTest() = default ;
};
constexpr OUString DATA_DIRECTORY = u"/vcl/qa/cppunit/data/" _ustr;
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseBasicPDF)
{
OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "basic.pdf" ;
vcl::filter::PDFDocument aDocument;
SvFileStream aStream(aURL, StreamMode::READ);
CPPUNIT_ASSERT(aDocument.Read(aStream));
std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
CPPUNIT_ASSERT_EQUAL(size_t(1), aPages.size());
vcl::filter::PDFObjectElement* pResources = aPages[0]->LookupObject("Resources" _ostr);
CPPUNIT_ASSERT(pResources);
vcl::filter::PDFObjectElement* pTest = pResources->LookupObject("Test" _ostr);
CPPUNIT_ASSERT(pTest);
vcl::filter::PDFObjectElement* pTestArray1 = pTest->LookupObject("TestArray1" _ostr);
CPPUNIT_ASSERT(pTestArray1);
{
CPPUNIT_ASSERT_EQUAL(size_t(5), pTestArray1->GetArray()->GetElements().size());
}
vcl::filter::PDFObjectElement* pTestArray2 = pTest->LookupObject("TestArray2" _ostr);
CPPUNIT_ASSERT(pTestArray2);
{
CPPUNIT_ASSERT_EQUAL(size_t(2), pTestArray2->GetArray()->GetElements().size());
}
vcl::filter::PDFObjectElement* pTestDictionary = pTest->LookupObject("TestDictionary" _ostr);
{
sal_uInt64 nOffset = pTestDictionary->GetDictionaryOffset();
sal_uInt64 nLength = pTestDictionary->GetDictionaryLength();
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL(
"/TestReference 7 0 R/TestNumber "
"123/TestName/SomeName/TestDictionary<>/TestArray[1 2 3]" _ostr,
aString);
}
CPPUNIT_ASSERT(pTestDictionary);
{
auto const & rItems = pTestDictionary->GetDictionaryItems();
CPPUNIT_ASSERT_EQUAL(size_t(5), rItems.size());
auto * pReference = dynamic_cast <vcl::filter::PDFReferenceElement*>(
pTestDictionary->Lookup("TestReference" _ostr));
CPPUNIT_ASSERT(pReference);
CPPUNIT_ASSERT_EQUAL(7, pReference->GetObjectValue());
auto * pNumber = dynamic_cast <vcl::filter::PDFNumberElement*>(
pTestDictionary->Lookup("TestNumber" _ostr));
CPPUNIT_ASSERT(pNumber);
CPPUNIT_ASSERT_EQUAL(123.0, pNumber->GetValue());
auto * pName
= dynamic_cast <vcl::filter::PDFNameElement*>(pTestDictionary->Lookup("TestName" _ostr));
CPPUNIT_ASSERT(pName);
CPPUNIT_ASSERT_EQUAL("SomeName" _ostr, pName->GetValue());
auto * pDictionary = dynamic_cast <vcl::filter::PDFDictionaryElement*>(
pTestDictionary->Lookup("TestDictionary" _ostr));
CPPUNIT_ASSERT(pDictionary);
auto * pArray = dynamic_cast <vcl::filter::PDFArrayElement*>(
pTestDictionary->Lookup("TestArray" _ostr));
CPPUNIT_ASSERT(pArray);
// Check offsets and lengths
{
sal_uInt64 nOffset
= pTestDictionary->GetDictionary()->GetKeyOffset("TestReference" _ostr);
sal_uInt64 nLength
= pTestDictionary->GetDictionary()->GetKeyValueLength("TestReference" _ostr);
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL("TestReference 7 0 R" _ostr, aString);
}
{
sal_uInt64 nOffset = pTestDictionary->GetDictionary()->GetKeyOffset("TestNumber" _ostr);
sal_uInt64 nLength
= pTestDictionary->GetDictionary()->GetKeyValueLength("TestNumber" _ostr);
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL("TestNumber 123" _ostr, aString);
}
{
sal_uInt64 nOffset = pTestDictionary->GetDictionary()->GetKeyOffset("TestName" _ostr);
sal_uInt64 nLength
= pTestDictionary->GetDictionary()->GetKeyValueLength("TestName" _ostr);
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL("TestName/SomeName" _ostr, aString);
}
{
sal_uInt64 nOffset
= pTestDictionary->GetDictionary()->GetKeyOffset("TestDictionary" _ostr);
sal_uInt64 nLength
= pTestDictionary->GetDictionary()->GetKeyValueLength("TestDictionary" _ostr);
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL("TestDictionary<>" _ostr, aString);
}
{
sal_uInt64 nOffset = pTestDictionary->GetDictionary()->GetKeyOffset("TestArray" _ostr);
sal_uInt64 nLength
= pTestDictionary->GetDictionary()->GetKeyValueLength("TestArray" _ostr);
aStream.Seek(nOffset);
std::vector<char > aBuffer(nLength + 1, 0);
aStream.ReadBytes(aBuffer.data(), nLength);
OString aString(aBuffer.data());
CPPUNIT_ASSERT_EQUAL("TestArray[1 2 3]" _ostr, aString);
}
}
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseDocumentWithNullAsWhitespace)
{
// tdf#140606
// Bug document contained a null, which cause the parser to panic,
// but other PDF readers can handle the file well.
OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "DocumentWithNull.pdf" ;
vcl::filter::PDFDocument aDocument;
SvFileStream aStream(aURL, StreamMode::READ);
CPPUNIT_ASSERT(aDocument.Read(aStream));
}
namespace
{
vcl::filter::PDFObjectElement*
addObjectElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements,
vcl::filter::PDFDocument& rDocument, int nObjectNumber, int nGenerationNumber)
{
auto pObject = std::make_unique<vcl::filter::PDFObjectElement>(rDocument, nObjectNumber,
nGenerationNumber);
auto pObjectPtr = pObject.get();
rElements.push_back(std::move(pObject));
return pObjectPtr;
}
vcl::filter::PDFTrailerElement*
addTrailerObjectElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements,
vcl::filter::PDFDocument& rDocument)
{
auto pTrailer = std::make_unique<vcl::filter::PDFTrailerElement>(rDocument);
auto pTrailerPtr = pTrailer.get();
rElements.push_back(std::move(pTrailer));
return pTrailerPtr;
}
void addEndObjectElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements)
{
rElements.push_back(std::make_unique<vcl::filter::PDFEndObjectElement>());
}
void addDictionaryElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements)
{
rElements.push_back(std::make_unique<vcl::filter::PDFDictionaryElement>());
}
void addEndDictionaryElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements)
{
rElements.push_back(std::make_unique<vcl::filter::PDFEndDictionaryElement>());
}
void addNameElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements,
OString const & rName)
{
auto pNameElement = std::make_unique<vcl::filter::PDFNameElement>();
pNameElement->SetValue(rName);
rElements.push_back(std::move(pNameElement));
}
vcl::filter::PDFNumberElement*
addNumberElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements, double fNumber)
{
auto pNumberElement = std::make_unique<vcl::filter::PDFNumberElement>();
auto pNumberElementPtr = pNumberElement.get();
pNumberElement->SetValue(fNumber);
rElements.push_back(std::move(pNumberElement));
return pNumberElementPtr;
}
void addReferenceElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements,
vcl::filter::PDFDocument& rDocument,
vcl::filter::PDFNumberElement* pNumber1,
vcl::filter::PDFNumberElement* pNumber2)
{
auto pReferenceElement
= std::make_unique<vcl::filter::PDFReferenceElement>(rDocument, *pNumber1, *pNumber2);
rElements.push_back(std::move(pReferenceElement));
}
void addArrayElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements,
vcl::filter::PDFObjectElement* pObjectPointer)
{
auto pArray = std::make_unique<vcl::filter::PDFArrayElement>(pObjectPointer);
rElements.push_back(std::move(pArray));
}
void addEndArrayElement(std::vector<std::unique_ptr<vcl::filter::PDFElement>>& rElements)
{
rElements.push_back(std::make_unique<vcl::filter::PDFEndArrayElement>());
}
} // end anonymous namespace
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseEmptyDictionary)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
addObjectElement(aElements, aDocument, 1, 0);
addDictionaryElement(aElements);
addEndDictionaryElement(aElements);
addEndObjectElement(aElements);
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetDictionary());
CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetDictionary()->GetItems().size());
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseDictionaryWithName)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
addObjectElement(aElements, aDocument, 1, 0);
addDictionaryElement(aElements);
addNameElement(aElements, "Test" _ostr);
addNumberElement(aElements, 30.0);
addEndDictionaryElement(aElements);
addEndObjectElement(aElements);
}
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetDictionary());
CPPUNIT_ASSERT_EQUAL(size_t(1), pObject->GetDictionary()->GetItems().size());
auto & rItems = pObject->GetDictionary()->GetItems();
auto pNumberElement = dynamic_cast <vcl::filter::PDFNumberElement*>(rItems.at("Test" _ostr));
CPPUNIT_ASSERT(pNumberElement);
CPPUNIT_ASSERT_DOUBLES_EQUAL(30.0, pNumberElement->GetValue(), 1e-4);
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseDictionaryNested)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
addObjectElement(aElements, aDocument, 1, 0);
addDictionaryElement(aElements);
addNameElement(aElements, "Nested1" _ostr);
addDictionaryElement(aElements);
{
addNameElement(aElements, "Nested2" _ostr);
addDictionaryElement(aElements);
{
addNameElement(aElements, "SomeOtherKey" _ostr);
addNameElement(aElements, "SomeOtherValue" _ostr);
}
addEndDictionaryElement(aElements);
}
addEndDictionaryElement(aElements);
addNameElement(aElements, "SomeOtherKey" _ostr);
addNameElement(aElements, "SomeOtherValue" _ostr);
addEndObjectElement(aElements);
}
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetDictionary());
CPPUNIT_ASSERT_EQUAL(size_t(2), pObject->GetDictionary()->GetItems().size());
CPPUNIT_ASSERT(pObject->Lookup("Nested1" _ostr));
CPPUNIT_ASSERT(pObject->Lookup("SomeOtherKey" _ostr));
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseEmptyArray)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
auto pObjectPtr = addObjectElement(aElements, aDocument, 1, 0);
addArrayElement(aElements, pObjectPtr);
addEndArrayElement(aElements);
addEndObjectElement(aElements);
}
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetArray());
CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetArray()->GetElements().size());
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseArrayWithSimpleElements)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
auto pObjectPtr = addObjectElement(aElements, aDocument, 1, 0);
addArrayElement(aElements, pObjectPtr);
addNameElement(aElements, "Test" _ostr);
addNumberElement(aElements, 30.0);
addEndArrayElement(aElements);
addEndObjectElement(aElements);
}
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetArray());
CPPUNIT_ASSERT_EQUAL(size_t(2), pObject->GetArray()->GetElements().size());
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseArrayNestedWithNumbers)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
// [ 1 [ 10 ] 2 ]
{
auto pObjectPtr = addObjectElement(aElements, aDocument, 1, 0);
addArrayElement(aElements, pObjectPtr);
{
addNumberElement(aElements, 1.0);
addArrayElement(aElements, pObjectPtr);
addNumberElement(aElements, 10.0);
addEndArrayElement(aElements);
addNumberElement(aElements, 2.0);
}
addEndArrayElement(aElements);
addEndObjectElement(aElements);
}
// Assert
{
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetArray());
CPPUNIT_ASSERT_EQUAL(size_t(3), pObject->GetArray()->GetElements().size());
auto pRootArray = pObject->GetArray();
auto pNumber1 = dynamic_cast <vcl::filter::PDFNumberElement*>(pRootArray->GetElement(0));
CPPUNIT_ASSERT(pNumber1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, pNumber1->GetValue(), 1e-4);
auto pArray3 = dynamic_cast <vcl::filter::PDFArrayElement*>(pRootArray->GetElement(1));
CPPUNIT_ASSERT(pArray3);
CPPUNIT_ASSERT_EQUAL(size_t(1), pArray3->GetElements().size());
auto pNumber2 = dynamic_cast <vcl::filter::PDFNumberElement*>(pRootArray->GetElement(2));
CPPUNIT_ASSERT(pNumber1);
CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, pNumber2->GetValue(), 1e-4);
}
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseArrayNestedWithNames)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
// [/Inner1/Inner2[/Inner31][/Inner41/Inner42[/Inner431/Inner432]][/Inner51[/Inner521]]]
{
auto pObjectPtr = addObjectElement(aElements, aDocument, 1, 0);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner1" _ostr);
addNameElement(aElements, "Inner2" _ostr);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner31" _ostr);
}
addEndArrayElement(aElements);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner41" _ostr);
addNameElement(aElements, "Inner42" _ostr);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner431" _ostr);
addNameElement(aElements, "Inner432" _ostr);
}
addEndArrayElement(aElements);
}
addEndArrayElement(aElements);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner51" _ostr);
addArrayElement(aElements, pObjectPtr);
{
addNameElement(aElements, "Inner521" _ostr);
}
addEndArrayElement(aElements);
}
addEndArrayElement(aElements);
}
addEndArrayElement(aElements);
addEndObjectElement(aElements);
}
// Assert
{
auto pObject = dynamic_cast <vcl::filter::PDFObjectElement*>(aElements[0].get());
CPPUNIT_ASSERT(pObject);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pObject);
CPPUNIT_ASSERT(pObject->GetArray());
CPPUNIT_ASSERT_EQUAL(size_t(5), pObject->GetArray()->GetElements().size());
auto pRootArray = pObject->GetArray();
auto pName1 = dynamic_cast <vcl::filter::PDFNameElement*>(pRootArray->GetElement(0));
CPPUNIT_ASSERT(pName1);
CPPUNIT_ASSERT_EQUAL("Inner1" _ostr, pName1->GetValue());
auto pName2 = dynamic_cast <vcl::filter::PDFNameElement*>(pRootArray->GetElement(1));
CPPUNIT_ASSERT(pName2);
CPPUNIT_ASSERT_EQUAL("Inner2" _ostr, pName2->GetValue());
auto pArray3 = dynamic_cast <vcl::filter::PDFArrayElement*>(pRootArray->GetElement(2));
CPPUNIT_ASSERT(pArray3);
CPPUNIT_ASSERT_EQUAL(size_t(1), pArray3->GetElements().size());
auto pInner31 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray3->GetElement(0));
CPPUNIT_ASSERT(pInner31);
CPPUNIT_ASSERT_EQUAL("Inner31" _ostr, pInner31->GetValue());
auto pArray4 = dynamic_cast <vcl::filter::PDFArrayElement*>(pRootArray->GetElement(3));
CPPUNIT_ASSERT(pArray4);
CPPUNIT_ASSERT_EQUAL(size_t(3), pArray4->GetElements().size());
auto pInner41 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray4->GetElement(0));
CPPUNIT_ASSERT(pInner41);
CPPUNIT_ASSERT_EQUAL("Inner41" _ostr, pInner41->GetValue());
auto pInner42 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray4->GetElement(1));
CPPUNIT_ASSERT(pInner42);
CPPUNIT_ASSERT_EQUAL("Inner42" _ostr, pInner42->GetValue());
auto pArray43 = dynamic_cast <vcl::filter::PDFArrayElement*>(pArray4->GetElement(2));
CPPUNIT_ASSERT(pArray43);
CPPUNIT_ASSERT_EQUAL(size_t(2), pArray43->GetElements().size());
auto pInner431 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray43->GetElement(0));
CPPUNIT_ASSERT(pInner431);
CPPUNIT_ASSERT_EQUAL("Inner431" _ostr, pInner431->GetValue());
auto pInner432 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray43->GetElement(1));
CPPUNIT_ASSERT(pInner432);
CPPUNIT_ASSERT_EQUAL("Inner432" _ostr, pInner432->GetValue());
auto pArray5 = dynamic_cast <vcl::filter::PDFArrayElement*>(pRootArray->GetElement(4));
CPPUNIT_ASSERT(pArray5);
CPPUNIT_ASSERT_EQUAL(size_t(2), pArray5->GetElements().size());
auto pInner51 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray5->GetElement(0));
CPPUNIT_ASSERT(pInner51);
CPPUNIT_ASSERT_EQUAL("Inner51" _ostr, pInner51->GetValue());
auto pArray52 = dynamic_cast <vcl::filter::PDFArrayElement*>(pArray5->GetElement(1));
CPPUNIT_ASSERT(pArray52);
CPPUNIT_ASSERT_EQUAL(size_t(1), pArray52->GetElements().size());
auto pInner521 = dynamic_cast <vcl::filter::PDFNameElement*>(pArray52->GetElement(0));
CPPUNIT_ASSERT(pInner521);
CPPUNIT_ASSERT_EQUAL("Inner521" _ostr, pInner521->GetValue());
}
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseTrailer)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
addTrailerObjectElement(aElements, aDocument);
addDictionaryElement(aElements);
addNameElement(aElements, "Size" _ostr);
addNumberElement(aElements, 11.0);
addEndDictionaryElement(aElements);
}
{
auto pTrailer = dynamic_cast <vcl::filter::PDFTrailerElement*>(aElements[0].get());
CPPUNIT_ASSERT(pTrailer);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pTrailer);
CPPUNIT_ASSERT(pTrailer->GetDictionary());
CPPUNIT_ASSERT_EQUAL(size_t(1), pTrailer->GetDictionary()->GetItems().size());
}
}
CPPUNIT_TEST_FIXTURE(PDFDocumentTest, testParseTrailerWithReference)
{
std::vector<std::unique_ptr<vcl::filter::PDFElement>> aElements;
vcl::filter::PDFDocument aDocument;
{
addTrailerObjectElement(aElements, aDocument);
addDictionaryElement(aElements);
addNameElement(aElements, "Reference" _ostr);
auto pNumberElement1 = addNumberElement(aElements, 11.0);
auto pNumberElement2 = addNumberElement(aElements, 0.0);
addReferenceElement(aElements, aDocument, pNumberElement1, pNumberElement2);
addEndDictionaryElement(aElements);
}
{
auto pTrailer = dynamic_cast <vcl::filter::PDFTrailerElement*>(aElements[0].get());
CPPUNIT_ASSERT(pTrailer);
vcl::filter::PDFObjectParser aParser(aElements);
aParser.parse(pTrailer);
CPPUNIT_ASSERT(pTrailer->GetDictionary());
CPPUNIT_ASSERT_EQUAL(size_t(1), pTrailer->GetDictionary()->GetItems().size());
auto pElement = pTrailer->Lookup("Reference" _ostr);
CPPUNIT_ASSERT(pElement);
auto pReference = dynamic_cast <vcl::filter::PDFReferenceElement*>(pElement);
CPPUNIT_ASSERT(pReference);
CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, pReference->GetObjectValue(), 1e-4);
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, pReference->GetGenerationValue(), 1e-4);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
quality 100%
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland