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/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[] = {
18 "Subject", "description",
20 "Keywords", "Keywords",
21 "Producer", "Producer",
22 "Creator", "CreatorTool",
23 "CreationDate", "CreateDate",
24 "ModDate", "ModifyDate",
25 "MetadataDate", "MetadataDate"
27 CPDF_Metadata::CPDF_Metadata()
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) {
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]);
40 CPDF_Metadata::~CPDF_Metadata()
42 FXSYS_assert(m_pData != NULL);
43 CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
45 CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
47 pStringMap->RemoveAll();
52 void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
54 FXSYS_assert(pDoc != NULL);
55 ((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc;
56 CPDF_Dictionary *pRoot = pDoc->GetRoot();
57 CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata"));
62 acc.LoadAllData(pStream, FALSE);
63 int size = acc.GetSize();
64 FX_LPCBYTE pBuf = acc.GetData();
65 CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
66 pXmlElmnt = CXML_Element::Parse(pBuf, size);
70 CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
71 if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) {
72 pElmntRdf = pXmlElmnt;
74 pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF"));
77 FX_INT32 CPDF_Metadata::GetString(FX_BSTR bsItem, CFX_WideString &wsStr)
79 if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) {
82 if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) {
86 if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) {
89 CFX_ByteString bsTag = (FX_LPCSTR)szTag;
91 CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
95 int nChild = pElmntRdf->CountChildren();
96 for (int i = 0; i < nChild; i++) {
97 CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i);
101 if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) {
102 CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
106 pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt"));
110 pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
114 wsStr = pElmnt->GetContent(0);
115 return wsStr.GetLength();
116 } else if (bsItem == FX_BSTRC("Author")) {
117 CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
121 pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
125 pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
129 wsStr = pElmnt->GetContent(0);
130 return wsStr.GetLength();
132 CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
136 wsStr = pElmnt->GetContent(0);
137 return wsStr.GetLength();
142 CXML_Element* CPDF_Metadata::GetRoot() const
144 return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
146 CXML_Element* CPDF_Metadata::GetRDF() const
148 return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;