Home | History | Annotate | Download | only in fpdfdoc
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../include/fpdfdoc/fpdf_doc.h"
      8 #include "../../include/fxcrt/fx_xml.h"
      9 typedef struct _PDFDOC_METADATA {
     10     CPDF_Document *m_pDoc;
     11     CXML_Element *m_pXmlElmnt;
     12     CXML_Element *m_pElmntRdf;
     13     CFX_CMapByteStringToPtr *m_pStringMap;
     14 } PDFDOC_METADATA, * PDFDOC_LPMETADATA;
     15 typedef PDFDOC_METADATA const * PDFDOC_LPCMETADATA;
     16 const FX_LPCSTR gs_FPDFDOC_Metadata_Titles[] = {
     17     "Title", "title",
     18     "Subject", "description",
     19     "Author", "creator",
     20     "Keywords", "Keywords",
     21     "Producer", "Producer",
     22     "Creator", "CreatorTool",
     23     "CreationDate", "CreateDate",
     24     "ModDate", "ModifyDate",
     25     "MetadataDate", "MetadataDate"
     26 };
     27 CPDF_Metadata::CPDF_Metadata()
     28 {
     29     m_pData = FX_Alloc(PDFDOC_METADATA, 1);
     30     CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
     31     pStringMap = new CFX_CMapByteStringToPtr;
     32     CFX_ByteString bstr;
     33     for (int i = 0; i < 18; i += 2) {
     34         bstr = gs_FPDFDOC_Metadata_Titles[i];
     35         pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]);
     36     }
     37 
     38 }
     39 CPDF_Metadata::~CPDF_Metadata()
     40 {
     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_pStringMap;
     45     if (pStringMap) {
     46         pStringMap->RemoveAll();
     47         delete pStringMap;
     48     }
     49     FX_Free(m_pData);
     50 }
     51 void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
     52 {
     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     FX_LPCBYTE 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 }
     76 FX_INT32 CPDF_Metadata::GetString(FX_BSTR 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 = (FX_LPCSTR)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         } else if (bsItem == FX_BSTRC("Author")) {
    116             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
    117             if (!pElmnt) {
    118                 continue;
    119             }
    120             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
    121             if (!pElmnt) {
    122                 continue;
    123             }
    124             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
    125             if (!pElmnt) {
    126                 continue;
    127             }
    128             wsStr = pElmnt->GetContent(0);
    129             return wsStr.GetLength();
    130         } else {
    131             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
    132             if (!pElmnt) {
    133                 continue;
    134             }
    135             wsStr = pElmnt->GetContent(0);
    136             return wsStr.GetLength();
    137         }
    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 }
    149