// 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/fpdfdoc/fpdf_doc.h" | |
#include "../../include/fxcrt/fx_xml.h" | |
typedef struct _PDFDOC_METADATA { | |
CPDF_Document *m_pDoc; | |
CXML_Element *m_pXmlElmnt; | |
CXML_Element *m_pElmntRdf; | |
CFX_CMapByteStringToPtr *m_pStringMap; | |
} PDFDOC_METADATA, * PDFDOC_LPMETADATA; | |
typedef PDFDOC_METADATA const * PDFDOC_LPCMETADATA; | |
const FX_LPCSTR gs_FPDFDOC_Metadata_Titles[] = { | |
"Title", "title", | |
"Subject", "description", | |
"Author", "creator", | |
"Keywords", "Keywords", | |
"Producer", "Producer", | |
"Creator", "CreatorTool", | |
"CreationDate", "CreateDate", | |
"ModDate", "ModifyDate", | |
"MetadataDate", "MetadataDate" | |
}; | |
CPDF_Metadata::CPDF_Metadata() | |
{ | |
m_pData = FX_Alloc(PDFDOC_METADATA, 1); | |
FXSYS_memset32(m_pData, 0, sizeof(PDFDOC_METADATA)); | |
CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap; | |
pStringMap = FX_NEW(CFX_CMapByteStringToPtr); | |
if (pStringMap != NULL) { | |
CFX_ByteString bstr; | |
for (int i = 0; i < 18; i += 2) { | |
bstr = gs_FPDFDOC_Metadata_Titles[i]; | |
pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]); | |
} | |
} | |
} | |
CPDF_Metadata::~CPDF_Metadata() | |
{ | |
FXSYS_assert(m_pData != NULL); | |
CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt; | |
if (p) { | |
delete p; | |
} | |
CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap; | |
if (pStringMap) { | |
pStringMap->RemoveAll(); | |
FX_Free(pStringMap); | |
} | |
FX_Free(m_pData); | |
} | |
void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc) | |
{ | |
FXSYS_assert(pDoc != NULL); | |
((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc; | |
CPDF_Dictionary *pRoot = pDoc->GetRoot(); | |
CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata")); | |
if (!pStream) { | |
return; | |
} | |
CPDF_StreamAcc acc; | |
acc.LoadAllData(pStream, FALSE); | |
int size = acc.GetSize(); | |
FX_LPCBYTE pBuf = acc.GetData(); | |
CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt; | |
pXmlElmnt = CXML_Element::Parse(pBuf, size); | |
if (!pXmlElmnt) { | |
return; | |
} | |
CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf; | |
if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) { | |
pElmntRdf = pXmlElmnt; | |
} else { | |
pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF")); | |
} | |
} | |
FX_INT32 CPDF_Metadata::GetString(FX_BSTR bsItem, CFX_WideString &wsStr) | |
{ | |
if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) { | |
return -1; | |
} | |
if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) { | |
return -1; | |
} | |
void *szTag; | |
if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) { | |
return -1; | |
} | |
CFX_ByteString bsTag = (FX_LPCSTR)szTag; | |
wsStr = L""; | |
CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf; | |
if (!pElmntRdf) { | |
return -1; | |
} | |
int nChild = pElmntRdf->CountChildren(); | |
for (int i = 0; i < nChild; i++) { | |
CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i); | |
if (!pTag) { | |
continue; | |
} | |
if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) { | |
CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag); | |
if (!pElmnt) { | |
continue; | |
} | |
pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt")); | |
if (!pElmnt) { | |
continue; | |
} | |
pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li")); | |
if (!pElmnt) { | |
continue; | |
} | |
wsStr = pElmnt->GetContent(0); | |
return wsStr.GetLength(); | |
} else if (bsItem == FX_BSTRC("Author")) { | |
CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag); | |
if (!pElmnt) { | |
continue; | |
} | |
pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq")); | |
if (!pElmnt) { | |
continue; | |
} | |
pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li")); | |
if (!pElmnt) { | |
continue; | |
} | |
wsStr = pElmnt->GetContent(0); | |
return wsStr.GetLength(); | |
} else { | |
CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag); | |
if (!pElmnt) { | |
continue; | |
} | |
wsStr = pElmnt->GetContent(0); | |
return wsStr.GetLength(); | |
} | |
} | |
return -1; | |
} | |
CXML_Element* CPDF_Metadata::GetRoot() const | |
{ | |
return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt; | |
} | |
CXML_Element* CPDF_Metadata::GetRDF() const | |
{ | |
return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf; | |
} |