Remove custom memory manager
[pdfium.git] / core / src / fpdfdoc / doc_metadata.cpp
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 "../../include/fpdfdoc/fpdf_doc.h"
8 #include "../../include/fxcrt/fx_xml.h"
9 typedef struct _PDFDOC_METADATA {
10     CPDF_Document *m_pDoc;
11     CXML_Element *m_pXmlElmnt;
12     CXML_Element *m_pElmntRdf;
13     CFX_CMapByteStringToPtr *m_pStringMap;
14 } PDFDOC_METADATA, * PDFDOC_LPMETADATA;
15 typedef PDFDOC_METADATA const * PDFDOC_LPCMETADATA;
16 const FX_LPCSTR gs_FPDFDOC_Metadata_Titles[] = {
17     "Title", "title",
18     "Subject", "description",
19     "Author", "creator",
20     "Keywords", "Keywords",
21     "Producer", "Producer",
22     "Creator", "CreatorTool",
23     "CreationDate", "CreateDate",
24     "ModDate", "ModifyDate",
25     "MetadataDate", "MetadataDate"
26 };
27 CPDF_Metadata::CPDF_Metadata()
28 {
29     m_pData = FX_Alloc(PDFDOC_METADATA, 1);
30     CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
31     pStringMap = FX_NEW(CFX_CMapByteStringToPtr);
32     if (pStringMap != NULL) {
33         CFX_ByteString bstr;
34         for (int i = 0; i < 18; i += 2) {
35             bstr = gs_FPDFDOC_Metadata_Titles[i];
36             pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]);
37         }
38     }
39 }
40 CPDF_Metadata::~CPDF_Metadata()
41 {
42     FXSYS_assert(m_pData != NULL);
43     CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
44     if (p) {
45         delete p;
46     }
47     CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
48     if (pStringMap) {
49         pStringMap->RemoveAll();
50         FX_Free(pStringMap);
51     }
52     FX_Free(m_pData);
53 }
54 void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
55 {
56     FXSYS_assert(pDoc != NULL);
57     ((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc;
58     CPDF_Dictionary *pRoot = pDoc->GetRoot();
59     CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata"));
60     if (!pStream) {
61         return;
62     }
63     CPDF_StreamAcc acc;
64     acc.LoadAllData(pStream, FALSE);
65     int size = acc.GetSize();
66     FX_LPCBYTE pBuf = acc.GetData();
67     CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
68     pXmlElmnt = CXML_Element::Parse(pBuf, size);
69     if (!pXmlElmnt) {
70         return;
71     }
72     CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
73     if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) {
74         pElmntRdf = pXmlElmnt;
75     } else {
76         pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF"));
77     }
78 }
79 FX_INT32 CPDF_Metadata::GetString(FX_BSTR bsItem, CFX_WideString &wsStr)
80 {
81     if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) {
82         return -1;
83     }
84     if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) {
85         return -1;
86     }
87     void *szTag;
88     if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) {
89         return -1;
90     }
91     CFX_ByteString bsTag = (FX_LPCSTR)szTag;
92     wsStr = L"";
93     CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
94     if (!pElmntRdf) {
95         return -1;
96     }
97     int nChild = pElmntRdf->CountChildren();
98     for (int i = 0; i < nChild; i++) {
99         CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i);
100         if (!pTag) {
101             continue;
102         }
103         if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) {
104             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
105             if (!pElmnt) {
106                 continue;
107             }
108             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt"));
109             if (!pElmnt) {
110                 continue;
111             }
112             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
113             if (!pElmnt) {
114                 continue;
115             }
116             wsStr = pElmnt->GetContent(0);
117             return wsStr.GetLength();
118         } else if (bsItem == FX_BSTRC("Author")) {
119             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
120             if (!pElmnt) {
121                 continue;
122             }
123             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
124             if (!pElmnt) {
125                 continue;
126             }
127             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
128             if (!pElmnt) {
129                 continue;
130             }
131             wsStr = pElmnt->GetContent(0);
132             return wsStr.GetLength();
133         } else {
134             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
135             if (!pElmnt) {
136                 continue;
137             }
138             wsStr = pElmnt->GetContent(0);
139             return wsStr.GetLength();
140         }
141     }
142     return -1;
143 }
144 CXML_Element* CPDF_Metadata::GetRoot() const
145 {
146     return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
147 }
148 CXML_Element* CPDF_Metadata::GetRDF() const
149 {
150     return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
151 }