summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp')
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp
new file mode 100644
index 0000000000..22f9aa713f
--- /dev/null
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_fdf.cpp
@@ -0,0 +1,224 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fpdfapi/fpdf_serial.h"
+CFDF_Document::CFDF_Document() : CPDF_IndirectObjects(NULL)
+{
+ m_pRootDict = NULL;
+ m_pFile = NULL;
+ m_bOwnFile = FALSE;
+}
+CFDF_Document::~CFDF_Document()
+{
+ if (m_bOwnFile && m_pFile) {
+ m_pFile->Release();
+ }
+}
+CFDF_Document* CFDF_Document::CreateNewDoc()
+{
+ CFDF_Document* pDoc = FX_NEW CFDF_Document;
+ pDoc->m_pRootDict = FX_NEW CPDF_Dictionary;
+ pDoc->AddIndirectObject(pDoc->m_pRootDict);
+ CPDF_Dictionary* pFDFDict = FX_NEW CPDF_Dictionary;
+ pDoc->m_pRootDict->SetAt(FX_BSTRC("FDF"), pFDFDict);
+ return pDoc;
+}
+CFDF_Document* CFDF_Document::ParseFile(FX_LPCSTR file_path)
+{
+ return CFDF_Document::ParseFile(FX_CreateFileRead(file_path), TRUE);
+}
+CFDF_Document* CFDF_Document::ParseFile(FX_LPCWSTR file_path)
+{
+ return CFDF_Document::ParseFile(FX_CreateFileRead(file_path), TRUE);
+}
+CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead *pFile, FX_BOOL bOwnFile)
+{
+ if (!pFile) {
+ return NULL;
+ }
+ CFDF_Document* pDoc = FX_NEW CFDF_Document;
+ pDoc->ParseStream(pFile, bOwnFile);
+ if (pDoc->m_pRootDict == NULL) {
+ delete pDoc;
+ return NULL;
+ }
+ return pDoc;
+}
+CFDF_Document* CFDF_Document::ParseMemory(FX_LPCBYTE pData, FX_DWORD size)
+{
+ return CFDF_Document::ParseFile(FX_CreateMemoryStream((FX_LPBYTE)pData, size), TRUE);
+}
+void CFDF_Document::ParseStream(IFX_FileRead *pFile, FX_BOOL bOwnFile)
+{
+ m_pFile = pFile;
+ m_bOwnFile = bOwnFile;
+ CPDF_SyntaxParser parser;
+ parser.InitParser(m_pFile, 0);
+ while (1) {
+ FX_BOOL bNumber;
+ CFX_ByteString word = parser.GetNextWord(bNumber);
+ if (bNumber) {
+ FX_DWORD objnum = FXSYS_atoi(word);
+ word = parser.GetNextWord(bNumber);
+ if (!bNumber) {
+ break;
+ }
+ word = parser.GetNextWord(bNumber);
+ if (word != FX_BSTRC("obj")) {
+ break;
+ }
+ CPDF_Object* pObj = parser.GetObject(this, objnum, 0, FALSE);
+ if (pObj == NULL) {
+ break;
+ }
+ InsertIndirectObject(objnum, pObj);
+ word = parser.GetNextWord(bNumber);
+ if (word != FX_BSTRC("endobj")) {
+ break;
+ }
+ } else {
+ if (word != FX_BSTRC("trailer")) {
+ break;
+ }
+ CPDF_Dictionary* pMainDict = (CPDF_Dictionary*)parser.GetObject(this, 0, 0, 0);
+ if (pMainDict == NULL || pMainDict->GetType() != PDFOBJ_DICTIONARY) {
+ break;
+ }
+ m_pRootDict = pMainDict->GetDict(FX_BSTRC("Root"));
+ pMainDict->Release();
+ break;
+ }
+ }
+}
+FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const
+{
+ if (m_pRootDict == NULL) {
+ return FALSE;
+ }
+ buf << FX_BSTRC("%FDF-1.2\r\n");
+ FX_POSITION pos = m_IndirectObjs.GetStartPosition();
+ while(pos) {
+ size_t objnum;
+ CPDF_Object* pObj;
+ m_IndirectObjs.GetNextAssoc(pos, (FX_LPVOID&)objnum, (FX_LPVOID&)pObj);
+ buf << (FX_DWORD)objnum << FX_BSTRC(" 0 obj\r\n") << pObj << FX_BSTRC("\r\nendobj\r\n\r\n");
+ }
+ buf << FX_BSTRC("trailer\r\n<</Root ") << m_pRootDict->GetObjNum() << FX_BSTRC(" 0 R>>\r\n%%EOF\r\n");
+ return TRUE;
+}
+CFX_WideString CFDF_Document::GetWin32Path() const
+{
+ CPDF_Object* pFileSpec = m_pRootDict->GetDict(FX_BSTRC("FDF"))->GetElementValue(FX_BSTRC("F"));
+ if (pFileSpec == NULL) {
+ return CFX_WideString();
+ }
+ if (pFileSpec->GetType() == PDFOBJ_STRING) {
+ return FPDF_FileSpec_GetWin32Path(m_pRootDict->GetDict(FX_BSTRC("FDF")));
+ }
+ return FPDF_FileSpec_GetWin32Path(pFileSpec);
+}
+FX_BOOL CFDF_Document::WriteFile(FX_LPCSTR file_path) const
+{
+ IFX_FileWrite *pFile = FX_CreateFileWrite(file_path);
+ if (!pFile) {
+ return FALSE;
+ }
+ FX_BOOL bRet = WriteFile(pFile);
+ pFile->Release();
+ return bRet;
+}
+FX_BOOL CFDF_Document::WriteFile(FX_LPCWSTR file_path) const
+{
+ IFX_FileWrite *pFile = FX_CreateFileWrite(file_path);
+ if (!pFile) {
+ return FALSE;
+ }
+ FX_BOOL bRet = WriteFile(pFile);
+ pFile->Release();
+ return bRet;
+}
+FX_BOOL CFDF_Document::WriteFile(IFX_FileWrite *pFile) const
+{
+ CFX_ByteTextBuf buf;
+ WriteBuf(buf);
+ FX_BOOL bRet = pFile->WriteBlock(buf.GetBuffer(), buf.GetSize());
+ if (bRet) {
+ pFile->Flush();
+ }
+ return bRet;
+}
+static CFX_WideString ChangeSlash(FX_LPCWSTR str)
+{
+ CFX_WideString result;
+ while (*str) {
+ if (*str == '\\') {
+ result += '/';
+ } else if (*str == '/') {
+ result += '\\';
+ } else {
+ result += *str;
+ }
+ str ++;
+ }
+ return result;
+}
+void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec, const CFX_WideString& filepath)
+{
+ CFX_WideString result;
+ if (filepath.GetLength() > 1 && filepath[1] == ':') {
+ result = L"/";
+ result += filepath[0];
+ if (filepath[2] != '\\') {
+ result += '/';
+ }
+ result += ChangeSlash((FX_LPCWSTR)filepath + 2);
+ } else if (filepath.GetLength() > 1 && filepath[0] == '\\' && filepath[1] == '\\') {
+ result = ChangeSlash((FX_LPCWSTR)filepath + 1);
+ } else {
+ result = ChangeSlash(filepath);
+ }
+ if (pFileSpec->GetType() == PDFOBJ_STRING) {
+ pFileSpec->SetString(CFX_ByteString::FromUnicode(result));
+ } else if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
+ ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(result));
+ ((CPDF_Dictionary*)pFileSpec)->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(result));
+ ((CPDF_Dictionary*)pFileSpec)->RemoveAt(FX_BSTRC("FS"));
+ }
+}
+CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec)
+{
+ CFX_WideString wsFileName;
+ if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
+ CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFileSpec;
+ wsFileName = pDict->GetUnicodeText(FX_BSTRC("UF"));
+ if (wsFileName.IsEmpty()) {
+ wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F")));
+ }
+ if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) {
+ return wsFileName;
+ }
+ if (wsFileName.IsEmpty() && pDict->KeyExist(FX_BSTRC("DOS"))) {
+ wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS")));
+ }
+ } else {
+ wsFileName = CFX_WideString::FromLocal(pFileSpec->GetString());
+ }
+ if (wsFileName[0] != '/') {
+ return ChangeSlash(wsFileName);
+ }
+ if (wsFileName[2] == '/') {
+ CFX_WideString result;
+ result += wsFileName[1];
+ result += ':';
+ result += ChangeSlash(((FX_LPCWSTR)wsFileName) + 2);
+ return result;
+ } else {
+ CFX_WideString result;
+ result += '\\';
+ result += ChangeSlash(wsFileName);
+ return result;
+ }
+}