1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fpdfapi/parser/cfdf_document.h" 8 9 #include <memory> 10 #include <sstream> 11 #include <utility> 12 13 #include "core/fpdfapi/parser/cpdf_dictionary.h" 14 #include "core/fpdfapi/parser/cpdf_syntax_parser.h" 15 #include "core/fpdfapi/parser/fpdf_parser_utility.h" 16 #include "core/fxcrt/cfx_readonlymemorystream.h" 17 #include "third_party/base/ptr_util.h" 18 #include "third_party/base/span.h" 19 20 CFDF_Document::CFDF_Document() = default; 21 22 CFDF_Document::~CFDF_Document() = default; 23 CreateNewDoc()24std::unique_ptr<CFDF_Document> CFDF_Document::CreateNewDoc() { 25 auto pDoc = pdfium::MakeUnique<CFDF_Document>(); 26 pDoc->m_pRootDict.Reset(pDoc->NewIndirect<CPDF_Dictionary>()); 27 pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF"); 28 return pDoc; 29 } 30 ParseMemory(pdfium::span<const uint8_t> span)31std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory( 32 pdfium::span<const uint8_t> span) { 33 auto pDoc = pdfium::MakeUnique<CFDF_Document>(); 34 pDoc->ParseStream(pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(span)); 35 return pDoc->m_pRootDict ? std::move(pDoc) : nullptr; 36 } 37 ParseStream(RetainPtr<IFX_SeekableReadStream> pFile)38void CFDF_Document::ParseStream(RetainPtr<IFX_SeekableReadStream> pFile) { 39 m_pFile = std::move(pFile); 40 CPDF_SyntaxParser parser(m_pFile); 41 while (1) { 42 bool bNumber; 43 ByteString word = parser.GetNextWord(&bNumber); 44 if (bNumber) { 45 uint32_t objnum = FXSYS_atoui(word.c_str()); 46 if (!objnum) 47 break; 48 49 word = parser.GetNextWord(&bNumber); 50 if (!bNumber) 51 break; 52 53 word = parser.GetNextWord(nullptr); 54 if (word != "obj") 55 break; 56 57 RetainPtr<CPDF_Object> pObj = parser.GetObjectBody(this); 58 if (!pObj) 59 break; 60 61 ReplaceIndirectObjectIfHigherGeneration(objnum, std::move(pObj)); 62 word = parser.GetNextWord(nullptr); 63 if (word != "endobj") 64 break; 65 } else { 66 if (word != "trailer") 67 break; 68 69 RetainPtr<CPDF_Dictionary> pMainDict = 70 ToDictionary(parser.GetObjectBody(this)); 71 if (pMainDict) 72 m_pRootDict.Reset(pMainDict->GetDictFor("Root")); 73 74 break; 75 } 76 } 77 } 78 WriteToString() const79ByteString CFDF_Document::WriteToString() const { 80 if (!m_pRootDict) 81 return ByteString(); 82 83 std::ostringstream buf; 84 buf << "%FDF-1.2\r\n"; 85 for (const auto& pair : *this) 86 buf << pair.first << " 0 obj\r\n" 87 << pair.second.Get() << "\r\nendobj\r\n\r\n"; 88 89 buf << "trailer\r\n<</Root " << m_pRootDict->GetObjNum() 90 << " 0 R>>\r\n%%EOF\r\n"; 91 92 return ByteString(buf); 93 } 94