blob: bf55527d62c4872bcf01affa4da5495c53b6e4e7 [file] [log] [blame]
// 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);
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;
}