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