blob: f0c507f8cf3af3e4a53f431643f7fd503e93d072 [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_CHAR* const 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 = new CFX_CMapByteStringToPtr;
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;
delete p;
CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
if (pStringMap) {
pStringMap->RemoveAll();
delete 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();
const uint8_t* 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"));
}
}
int32_t CPDF_Metadata::GetString(const CFX_ByteStringC& 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 = (const FX_CHAR*)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;
}