blob: b617eecf8711003f1eef5efe8394de70e1f0e25b [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();
}
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();
}
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;
}