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     FXSYS_memset32(m_pData, 0, sizeof(PDFDOC_METADATA));
     31     CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
     32     pStringMap = FX_NEW(CFX_CMapByteStringToPtr);
     33     if (pStringMap != NULL) {
     34         CFX_ByteString bstr;
     35         for (int i = 0; i < 18; i += 2) {
     36             bstr = gs_FPDFDOC_Metadata_Titles[i];
     37             pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]);
     38         }
     39     }
     40 }
     41 CPDF_Metadata::~CPDF_Metadata()
     42 {
     43     FXSYS_assert(m_pData != NULL);
     44     CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
     45     if (p) {
     46         delete p;
     47     }
     48     CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
     49     if (pStringMap) {
     50         pStringMap->RemoveAll();
     51         FX_Free(pStringMap);
     52     }
     53     FX_Free(m_pData);
     54 }
     55 void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
     56 {
     57     FXSYS_assert(pDoc != NULL);
     58     ((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc;
     59     CPDF_Dictionary *pRoot = pDoc->GetRoot();
     60     CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata"));
     61     if (!pStream) {
     62         return;
     63     }
     64     CPDF_StreamAcc acc;
     65     acc.LoadAllData(pStream, FALSE);
     66     int size = acc.GetSize();
     67     FX_LPCBYTE pBuf = acc.GetData();
     68     CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
     69     pXmlElmnt = CXML_Element::Parse(pBuf, size);
     70     if (!pXmlElmnt) {
     71         return;
     72     }
     73     CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
     74     if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) {
     75         pElmntRdf = pXmlElmnt;
     76     } else {
     77         pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF"));
     78     }
     79 }
     80 FX_INT32 CPDF_Metadata::GetString(FX_BSTR bsItem, CFX_WideString &wsStr)
     81 {
     82     if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) {
     83         return -1;
     84     }
     85     if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) {
     86         return -1;
     87     }
     88     void *szTag;
     89     if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) {
     90         return -1;
     91     }
     92     CFX_ByteString bsTag = (FX_LPCSTR)szTag;
     93     wsStr = L"";
     94     CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
     95     if (!pElmntRdf) {
     96         return -1;
     97     }
     98     int nChild = pElmntRdf->CountChildren();
     99     for (int i = 0; i < nChild; i++) {
    100         CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i);
    101         if (!pTag) {
    102             continue;
    103         }
    104         if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) {
    105             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
    106             if (!pElmnt) {
    107                 continue;
    108             }
    109             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt"));
    110             if (!pElmnt) {
    111                 continue;
    112             }
    113             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
    114             if (!pElmnt) {
    115                 continue;
    116             }
    117             wsStr = pElmnt->GetContent(0);
    118             return wsStr.GetLength();
    119         } else if (bsItem == FX_BSTRC("Author")) {
    120             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
    121             if (!pElmnt) {
    122                 continue;
    123             }
    124             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
    125             if (!pElmnt) {
    126                 continue;
    127             }
    128             pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
    129             if (!pElmnt) {
    130                 continue;
    131             }
    132             wsStr = pElmnt->GetContent(0);
    133             return wsStr.GetLength();
    134         } else {
    135             CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
    136             if (!pElmnt) {
    137                 continue;
    138             }
    139             wsStr = pElmnt->GetContent(0);
    140             return wsStr.GetLength();
    141         }
    142     }
    143     return -1;
    144 }
    145 CXML_Element* CPDF_Metadata::GetRoot() const
    146 {
    147     return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
    148 }
    149 CXML_Element* CPDF_Metadata::GetRDF() const
    150 {
    151     return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
    152 }
    153