• 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/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()24 std::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)31 std::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)38 void 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() const79 ByteString 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