• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/edit/cpdf_creator.h"
14 #include "core/fpdfapi/parser/cpdf_dictionary.h"
15 #include "core/fpdfapi/parser/cpdf_syntax_parser.h"
16 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
17 #include "core/fxcrt/cfx_memorystream.h"
18 #include "third_party/base/ptr_util.h"
19 
CFDF_Document()20 CFDF_Document::CFDF_Document()
21     : CPDF_IndirectObjectHolder(), m_pRootDict(nullptr) {}
22 
~CFDF_Document()23 CFDF_Document::~CFDF_Document() {}
24 
CreateNewDoc()25 std::unique_ptr<CFDF_Document> CFDF_Document::CreateNewDoc() {
26   auto pDoc = pdfium::MakeUnique<CFDF_Document>();
27   pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>();
28   pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF");
29   return pDoc;
30 }
31 
ParseMemory(uint8_t * pData,uint32_t size)32 std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory(uint8_t* pData,
33                                                           uint32_t size) {
34   auto pDoc = pdfium::MakeUnique<CFDF_Document>();
35   pDoc->ParseStream(pdfium::MakeRetain<CFX_MemoryStream>(pData, size, false));
36   return pDoc->m_pRootDict ? std::move(pDoc) : nullptr;
37 }
38 
ParseStream(const RetainPtr<IFX_SeekableReadStream> & pFile)39 void CFDF_Document::ParseStream(
40     const RetainPtr<IFX_SeekableReadStream>& pFile) {
41   m_pFile = pFile;
42   CPDF_SyntaxParser parser;
43   parser.InitParser(m_pFile, 0);
44   while (1) {
45     bool bNumber;
46     ByteString word = parser.GetNextWord(&bNumber);
47     if (bNumber) {
48       uint32_t objnum = FXSYS_atoui(word.c_str());
49       if (!objnum)
50         break;
51 
52       word = parser.GetNextWord(&bNumber);
53       if (!bNumber)
54         break;
55 
56       word = parser.GetNextWord(nullptr);
57       if (word != "obj")
58         break;
59 
60       std::unique_ptr<CPDF_Object> pObj = parser.GetObjectBody(this);
61       if (!pObj)
62         break;
63 
64       ReplaceIndirectObjectIfHigherGeneration(objnum, std::move(pObj));
65       word = parser.GetNextWord(nullptr);
66       if (word != "endobj")
67         break;
68     } else {
69       if (word != "trailer")
70         break;
71 
72       std::unique_ptr<CPDF_Dictionary> pMainDict =
73           ToDictionary(parser.GetObjectBody(this));
74       if (pMainDict)
75         m_pRootDict = pMainDict->GetDictFor("Root");
76 
77       break;
78     }
79   }
80 }
81 
WriteToString() const82 ByteString CFDF_Document::WriteToString() const {
83   if (!m_pRootDict)
84     return ByteString();
85 
86   std::ostringstream buf;
87   buf << "%FDF-1.2\r\n";
88   for (const auto& pair : *this)
89     buf << pair.first << " 0 obj\r\n"
90         << pair.second.get() << "\r\nendobj\r\n\r\n";
91 
92   buf << "trailer\r\n<</Root " << m_pRootDict->GetObjNum()
93       << " 0 R>>\r\n%%EOF\r\n";
94 
95   return ByteString(buf);
96 }
97