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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fpdfapi/fpdf_serial.h"
8 CFDF_Document::CFDF_Document() : CPDF_IndirectObjects(NULL)
14 CFDF_Document::~CFDF_Document()
16 if (m_bOwnFile && m_pFile) {
20 CFDF_Document* CFDF_Document::CreateNewDoc()
22 CFDF_Document* pDoc = new CFDF_Document;
23 pDoc->m_pRootDict = new CPDF_Dictionary;
24 pDoc->AddIndirectObject(pDoc->m_pRootDict);
25 CPDF_Dictionary* pFDFDict = new CPDF_Dictionary;
26 pDoc->m_pRootDict->SetAt(FX_BSTRC("FDF"), pFDFDict);
29 CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead *pFile, FX_BOOL bOwnFile)
34 CFDF_Document* pDoc = new CFDF_Document;
35 pDoc->ParseStream(pFile, bOwnFile);
36 if (pDoc->m_pRootDict == NULL) {
42 CFDF_Document* CFDF_Document::ParseMemory(FX_LPCBYTE pData, FX_DWORD size)
44 return CFDF_Document::ParseFile(FX_CreateMemoryStream((FX_LPBYTE)pData, size), TRUE);
46 void CFDF_Document::ParseStream(IFX_FileRead *pFile, FX_BOOL bOwnFile)
49 m_bOwnFile = bOwnFile;
50 CPDF_SyntaxParser parser;
51 parser.InitParser(m_pFile, 0);
54 CFX_ByteString word = parser.GetNextWord(bNumber);
56 FX_DWORD objnum = FXSYS_atoi(word);
57 word = parser.GetNextWord(bNumber);
61 word = parser.GetNextWord(bNumber);
62 if (word != FX_BSTRC("obj")) {
65 CPDF_Object* pObj = parser.GetObject(this, objnum, 0, FALSE);
69 InsertIndirectObject(objnum, pObj);
70 word = parser.GetNextWord(bNumber);
71 if (word != FX_BSTRC("endobj")) {
75 if (word != FX_BSTRC("trailer")) {
78 CPDF_Dictionary* pMainDict = (CPDF_Dictionary*)parser.GetObject(this, 0, 0, 0);
79 if (pMainDict == NULL || pMainDict->GetType() != PDFOBJ_DICTIONARY) {
82 m_pRootDict = pMainDict->GetDict(FX_BSTRC("Root"));
88 FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const
90 if (m_pRootDict == NULL) {
93 buf << FX_BSTRC("%FDF-1.2\r\n");
94 FX_POSITION pos = m_IndirectObjs.GetStartPosition();
98 m_IndirectObjs.GetNextAssoc(pos, (FX_LPVOID&)objnum, (FX_LPVOID&)pObj);
99 buf << (FX_DWORD)objnum << FX_BSTRC(" 0 obj\r\n") << pObj << FX_BSTRC("\r\nendobj\r\n\r\n");
101 buf << FX_BSTRC("trailer\r\n<</Root ") << m_pRootDict->GetObjNum() << FX_BSTRC(" 0 R>>\r\n%%EOF\r\n");
104 CFX_WideString CFDF_Document::GetWin32Path() const
106 CPDF_Dictionary* pDict = m_pRootDict ? m_pRootDict->GetDict(FX_BSTRC("FDF")) : NULL;
107 CPDF_Object* pFileSpec = pDict ? pDict->GetElementValue(FX_BSTRC("F")) : NULL;
108 if (pFileSpec == NULL) {
109 return CFX_WideString();
111 if (pFileSpec->GetType() == PDFOBJ_STRING) {
112 return FPDF_FileSpec_GetWin32Path(m_pRootDict->GetDict(FX_BSTRC("FDF")));
114 return FPDF_FileSpec_GetWin32Path(pFileSpec);
116 static CFX_WideString ChangeSlash(FX_LPCWSTR str)
118 CFX_WideString result;
122 } else if (*str == '/') {
131 void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec, const CFX_WideString& filepath)
133 CFX_WideString result;
134 if (filepath.GetLength() > 1 && filepath[1] == ':') {
136 result += filepath[0];
137 if (filepath[2] != '\\') {
140 result += ChangeSlash(filepath.c_str() + 2);
141 } else if (filepath.GetLength() > 1 && filepath[0] == '\\' && filepath[1] == '\\') {
142 result = ChangeSlash(filepath.c_str() + 1);
144 result = ChangeSlash(filepath);
146 if (pFileSpec->GetType() == PDFOBJ_STRING) {
147 pFileSpec->SetString(CFX_ByteString::FromUnicode(result));
148 } else if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
149 ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(result));
150 ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(result));
151 ((CPDF_Dictionary*)pFileSpec)->RemoveAt(FX_BSTRC("FS"));
154 CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec)
156 CFX_WideString wsFileName;
157 if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
158 CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFileSpec;
159 wsFileName = pDict->GetUnicodeText(FX_BSTRC("UF"));
160 if (wsFileName.IsEmpty()) {
161 wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F")));
163 if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) {
166 if (wsFileName.IsEmpty() && pDict->KeyExist(FX_BSTRC("DOS"))) {
167 wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS")));
171 wsFileName = CFX_WideString();
173 wsFileName = CFX_WideString::FromLocal(pFileSpec->GetString());
175 if (wsFileName[0] != '/') {
176 return ChangeSlash(wsFileName);
178 if (wsFileName[2] == '/') {
179 CFX_WideString result;
180 result += wsFileName[1];
182 result += ChangeSlash(wsFileName.c_str() + 2);
185 CFX_WideString result;
187 result += ChangeSlash(wsFileName);