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