LCOV - code coverage report
Current view: directory - frmts/pdf - pdfobject.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 109 89 81.7 %
Date: 2011-12-18 Functions: 32 19 59.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: pdfobject.cpp 22503 2011-06-04 22:08:34Z rouault $
       3                 :  *
       4                 :  * Project:  PDF driver
       5                 :  * Purpose:  GDALDataset driver for PDF dataset.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef bool GBool" */
      31                 : /* in include/poppler/goo/gtypes.h with the one defined in cpl_port.h */
      32                 : #define CPL_GBOOL_DEFINED
      33                 : 
      34                 : #include <vector>
      35                 : #include "pdfobject.h"
      36                 : 
      37                 : CPL_CVSID("$Id: pdfobject.cpp 22503 2011-06-04 22:08:34Z rouault $");
      38                 : 
      39             142 : GDALPDFObject::~GDALPDFObject()
      40                 : {
      41             142 : }
      42                 : 
      43              16 : GDALPDFDictionary::~GDALPDFDictionary()
      44                 : {
      45              16 : }
      46                 : 
      47              18 : GDALPDFArray::~GDALPDFArray()
      48                 : {
      49              18 : }
      50                 : 
      51                 : #ifdef USE_POPPLER
      52                 : 
      53                 : class GDALPDFDictionaryPoppler: public GDALPDFDictionary
      54                 : {
      55                 :     private:
      56                 :         Dict* m_poDict;
      57                 :         std::map<CPLString, GDALPDFObject*> m_map;
      58                 : 
      59                 :     public:
      60              16 :         GDALPDFDictionaryPoppler(Dict* poDict) : m_poDict(poDict) {}
      61                 :         virtual ~GDALPDFDictionaryPoppler();
      62                 : 
      63                 :         virtual GDALPDFObject* Get(const char* pszKey);
      64                 :         virtual std::map<CPLString, GDALPDFObject*>& GetValues();
      65                 : };
      66                 : 
      67                 : class GDALPDFArrayPoppler : public GDALPDFArray
      68                 : {
      69                 :     private:
      70                 :         Array* m_poArray;
      71                 :         std::vector<GDALPDFObject*> m_v;
      72                 : 
      73                 :     public:
      74              18 :         GDALPDFArrayPoppler(Array* poArray) : m_poArray(poArray) {}
      75                 :         virtual ~GDALPDFArrayPoppler();
      76                 : 
      77                 :         virtual int GetLength();
      78                 :         virtual GDALPDFObject* Get(int nIndex);
      79                 : };
      80                 : 
      81             142 : GDALPDFObjectPoppler::~GDALPDFObjectPoppler()
      82                 : {
      83             142 :     m_po->free();
      84             142 :     if (m_bDestroy)
      85             138 :         delete m_po;
      86             142 :     delete m_poDict;
      87             142 :     delete m_poArray;
      88             142 : }
      89                 : 
      90             792 : GDALPDFObjectType GDALPDFObjectPoppler::GetType()
      91                 : {
      92             792 :     switch(m_po->getType())
      93                 :     {
      94             172 :         case objInt:        return PDFObjectType_Int;
      95              64 :         case objReal:       return PDFObjectType_Real;
      96             234 :         case objString:     return PDFObjectType_String;
      97              16 :         case objName:       return PDFObjectType_Name;
      98             272 :         case objArray:      return PDFObjectType_Array;
      99              34 :         case objDict:       return PDFObjectType_Dictionary;
     100               0 :         case objStream:     return PDFObjectType_Dictionary;
     101               0 :         default:            return PDFObjectType_Unknown;
     102                 :     }
     103                 : }
     104                 : 
     105               0 : const char* GDALPDFObjectPoppler::GetTypeName()
     106                 : {
     107               0 :     return m_po->getTypeName();
     108                 : }
     109                 : 
     110              56 : int GDALPDFObjectPoppler::GetInt()
     111                 : {
     112              56 :     if (GetType() == PDFObjectType_Int)
     113              56 :         return m_po->getInt();
     114                 :     else
     115               0 :         return 0;
     116                 : }
     117                 : 
     118              16 : double GDALPDFObjectPoppler::GetReal()
     119                 : {
     120              16 :     if (GetType() == PDFObjectType_Real)
     121              16 :         return m_po->getReal();
     122                 :     else
     123               0 :         return 0.0;
     124                 : }
     125                 : 
     126              54 : const CPLString& GDALPDFObjectPoppler::GetString()
     127                 : {
     128              54 :     if (GetType() == PDFObjectType_String)
     129              52 :         return (osStr = m_po->getString()->getCString());
     130                 :     else
     131               2 :         return (osStr = "");
     132                 : }
     133                 : 
     134               8 : const CPLString& GDALPDFObjectPoppler::GetName()
     135                 : {
     136               8 :     if (GetType() == PDFObjectType_Name)
     137               8 :         return (osStr = m_po->getName());
     138                 :     else
     139               0 :         return (osStr = "");
     140                 : }
     141                 : 
     142              20 : GDALPDFDictionary* GDALPDFObjectPoppler::GetDictionary()
     143                 : {
     144              20 :     if (GetType() != PDFObjectType_Dictionary)
     145               0 :         return NULL;
     146                 : 
     147              20 :     if (m_poDict)
     148               4 :         return m_poDict;
     149                 : 
     150              16 :     Dict* poDict = (m_po->getType() == objStream) ? m_po->getStream()->getDict() : m_po->getDict();
     151              16 :     if (poDict == NULL)
     152               0 :         return NULL;
     153              16 :     m_poDict = new GDALPDFDictionaryPoppler(poDict);
     154              16 :     return m_poDict;
     155                 : }
     156                 : 
     157             136 : GDALPDFArray* GDALPDFObjectPoppler::GetArray()
     158                 : {
     159             136 :     if (GetType() != PDFObjectType_Array)
     160               0 :         return NULL;
     161                 : 
     162             136 :     if (m_poArray)
     163             118 :         return m_poArray;
     164                 : 
     165              18 :     Array* poArray = m_po->getArray();
     166              18 :     if (poArray == NULL)
     167               0 :         return NULL;
     168              18 :     m_poArray = new GDALPDFArrayPoppler(poArray);
     169              18 :     return m_poArray;
     170                 : }
     171                 : 
     172              16 : GDALPDFDictionaryPoppler::~GDALPDFDictionaryPoppler()
     173                 : {
     174              16 :     std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
     175              16 :     std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
     176              56 :     for(; oIter != oEnd; ++oIter)
     177              40 :         delete oIter->second;
     178              16 : }
     179                 : 
     180              56 : GDALPDFObject* GDALPDFDictionaryPoppler::Get(const char* pszKey)
     181                 : {
     182              56 :     std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
     183              56 :     if (oIter != m_map.end())
     184               2 :         return oIter->second;
     185                 : 
     186              54 :     Object* po = new Object;
     187             108 :     if (m_poDict->lookup((char*)pszKey, po) && !po->isNull())
     188                 :     {
     189              40 :          GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
     190              80 :          m_map[pszKey] = poObj;
     191              40 :          return poObj;
     192                 :     }
     193                 :     else
     194                 :     {
     195              14 :         delete po;
     196              14 :         return NULL;
     197                 :     }
     198                 : }
     199                 : 
     200               0 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPoppler::GetValues()
     201                 : {
     202               0 :     int i = 0;
     203               0 :     int nLength = m_poDict->getLength();
     204               0 :     for(i=0;i<nLength;i++)
     205                 :     {
     206               0 :         Get((const char*)m_poDict->getKey(i));
     207                 :     }
     208               0 :     return m_map;
     209                 : }
     210                 : 
     211              18 : GDALPDFArrayPoppler::~GDALPDFArrayPoppler()
     212                 : {
     213             116 :     for(int i=0;i<(int)m_v.size();i++)
     214                 :     {
     215              98 :         delete m_v[i];
     216                 :     }
     217              18 : }
     218                 : 
     219             146 : int GDALPDFArrayPoppler::GetLength()
     220                 : {
     221             146 :     return m_poArray->getLength();
     222                 : }
     223                 : 
     224             126 : GDALPDFObject* GDALPDFArrayPoppler::Get(int nIndex)
     225                 : {
     226             126 :     if (nIndex < 0 || nIndex >= GetLength())
     227               0 :         return NULL;
     228                 : 
     229             126 :     int nOldSize = (int)m_v.size();
     230             126 :     if (nIndex >= nOldSize)
     231                 :     {
     232              98 :         m_v.resize(nIndex+1);
     233             196 :         for(int i=nOldSize;i<=nIndex;i++)
     234                 :         {
     235              98 :             m_v[i] = NULL;
     236                 :         }
     237                 :     }
     238                 : 
     239             126 :     if (m_v[nIndex] != NULL)
     240              28 :         return m_v[nIndex];
     241                 : 
     242              98 :     Object* po = new Object;
     243             196 :     if (m_poArray->get(nIndex, po) && !po->isNull())
     244                 :     {
     245              98 :         GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
     246              98 :         m_v[nIndex] = poObj;
     247              98 :         return poObj;
     248                 :     }
     249                 :     else
     250                 :     {
     251               0 :         delete po;
     252               0 :         return NULL;
     253                 :     }
     254                 : }
     255                 : 
     256                 : #else
     257                 : 
     258                 : class GDALPDFDictionaryPodofo: public GDALPDFDictionary
     259                 : {
     260                 :     private:
     261                 :         PoDoFo::PdfDictionary* m_poDict;
     262                 :         PoDoFo::PdfVecObjects& m_poObjects;
     263                 :         std::map<CPLString, GDALPDFObject*> m_map;
     264                 : 
     265                 :     public:
     266                 :         GDALPDFDictionaryPodofo(PoDoFo::PdfDictionary* poDict, PoDoFo::PdfVecObjects& poObjects) : m_poDict(poDict), m_poObjects(poObjects) {}
     267                 :         virtual ~GDALPDFDictionaryPodofo();
     268                 : 
     269                 :         virtual GDALPDFObject* Get(const char* pszKey);
     270                 :         virtual std::map<CPLString, GDALPDFObject*>& GetValues();
     271                 : };
     272                 : 
     273                 : class GDALPDFArrayPodofo : public GDALPDFArray
     274                 : {
     275                 :     private:
     276                 :         PoDoFo::PdfArray* m_poArray;
     277                 :         PoDoFo::PdfVecObjects& m_poObjects;
     278                 :         std::vector<GDALPDFObject*> m_v;
     279                 : 
     280                 :     public:
     281                 :         GDALPDFArrayPodofo(PoDoFo::PdfArray* poArray, PoDoFo::PdfVecObjects& poObjects) : m_poArray(poArray), m_poObjects(poObjects) {}
     282                 :         virtual ~GDALPDFArrayPodofo();
     283                 : 
     284                 :         virtual int GetLength();
     285                 :         virtual GDALPDFObject* Get(int nIndex);
     286                 : };
     287                 : 
     288                 : GDALPDFObjectPodofo::GDALPDFObjectPodofo(PoDoFo::PdfObject* po, PoDoFo::PdfVecObjects& poObjects) :
     289                 :         m_po(po), m_poObjects(poObjects), m_poDict(NULL), m_poArray(NULL)
     290                 : {
     291                 :     if (m_po->GetDataType() == PoDoFo::ePdfDataType_Reference)
     292                 :     {
     293                 :         PoDoFo::PdfObject* poObj = m_poObjects.GetObject(m_po->GetReference());
     294                 :         if (poObj)
     295                 :             m_po = poObj;
     296                 :     }
     297                 : }
     298                 : 
     299                 : GDALPDFObjectPodofo::~GDALPDFObjectPodofo()
     300                 : {
     301                 :     delete m_poDict;
     302                 :     delete m_poArray;
     303                 : }
     304                 : 
     305                 : GDALPDFObjectType GDALPDFObjectPodofo::GetType()
     306                 : {
     307                 :     switch(m_po->GetDataType())
     308                 :     {
     309                 :         case PoDoFo::ePdfDataType_Bool:       return PDFObjectType_Int;
     310                 :         case PoDoFo::ePdfDataType_Number:     return PDFObjectType_Int;
     311                 :         case PoDoFo::ePdfDataType_Real:       return PDFObjectType_Real;
     312                 :         case PoDoFo::ePdfDataType_String:     return PDFObjectType_String;
     313                 :         case PoDoFo::ePdfDataType_Name:       return PDFObjectType_Name;
     314                 :         case PoDoFo::ePdfDataType_Array:      return PDFObjectType_Array;
     315                 :         case PoDoFo::ePdfDataType_Dictionary: return PDFObjectType_Dictionary;
     316                 :         default:                              return PDFObjectType_Unknown;
     317                 :     }
     318                 : }
     319                 : 
     320                 : const char* GDALPDFObjectPodofo::GetTypeName()
     321                 : {
     322                 :     return m_po->GetDataTypeString();
     323                 : }
     324                 : 
     325                 : int GDALPDFObjectPodofo::GetInt()
     326                 : {
     327                 :     if (m_po->GetDataType() == PoDoFo::ePdfDataType_Bool)
     328                 :         return m_po->GetBool();
     329                 :     else if (m_po->GetDataType() == PoDoFo::ePdfDataType_Number)
     330                 :         return (int)m_po->GetNumber();
     331                 :     else
     332                 :         return 0;
     333                 : }
     334                 : 
     335                 : double GDALPDFObjectPodofo::GetReal()
     336                 : {
     337                 :     if (GetType() == PDFObjectType_Real)
     338                 :         return m_po->GetReal();
     339                 :     else
     340                 :         return 0.0;
     341                 : }
     342                 : 
     343                 : const CPLString& GDALPDFObjectPodofo::GetString()
     344                 : {
     345                 :     if (GetType() == PDFObjectType_String)
     346                 :         return (osStr = m_po->GetString().GetStringUtf8());
     347                 :     else
     348                 :         return (osStr = "");
     349                 : }
     350                 : 
     351                 : const CPLString&  GDALPDFObjectPodofo::GetName()
     352                 : {
     353                 :     if (GetType() == PDFObjectType_Name)
     354                 :         return (osStr = m_po->GetName().GetName());
     355                 :     else
     356                 :         return (osStr = "");
     357                 : }
     358                 : 
     359                 : GDALPDFDictionary* GDALPDFObjectPodofo::GetDictionary()
     360                 : {
     361                 :     if (GetType() != PDFObjectType_Dictionary)
     362                 :         return NULL;
     363                 : 
     364                 :     if (m_poDict)
     365                 :         return m_poDict;
     366                 : 
     367                 :     m_poDict = new GDALPDFDictionaryPodofo(&m_po->GetDictionary(), m_poObjects);
     368                 :     return m_poDict;
     369                 : }
     370                 : 
     371                 : GDALPDFArray* GDALPDFObjectPodofo::GetArray()
     372                 : {
     373                 :     if (GetType() != PDFObjectType_Array)
     374                 :         return NULL;
     375                 : 
     376                 :     if (m_poArray)
     377                 :         return m_poArray;
     378                 : 
     379                 :     m_poArray = new GDALPDFArrayPodofo(&m_po->GetArray(), m_poObjects);
     380                 :     return m_poArray;
     381                 : }
     382                 : 
     383                 : GDALPDFDictionaryPodofo::~GDALPDFDictionaryPodofo()
     384                 : {
     385                 :     std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
     386                 :     std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
     387                 :     for(; oIter != oEnd; ++oIter)
     388                 :         delete oIter->second;
     389                 : }
     390                 : 
     391                 : GDALPDFObject* GDALPDFDictionaryPodofo::Get(const char* pszKey)
     392                 : {
     393                 :     std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
     394                 :     if (oIter != m_map.end())
     395                 :         return oIter->second;
     396                 : 
     397                 :     PoDoFo::PdfObject* poVal = m_poDict->GetKey(PoDoFo::PdfName(pszKey));
     398                 :     if (poVal)
     399                 :     {
     400                 :          GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(poVal, m_poObjects);
     401                 :          m_map[pszKey] = poObj;
     402                 :          return poObj;
     403                 :     }
     404                 :     else
     405                 :     {
     406                 :         return NULL;
     407                 :     }
     408                 : }
     409                 : 
     410                 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPodofo::GetValues()
     411                 : {
     412                 :     PoDoFo::TKeyMap::iterator oIter = m_poDict->GetKeys().begin();
     413                 :     PoDoFo::TKeyMap::iterator oEnd = m_poDict->GetKeys().end();
     414                 :     for( ; oIter != oEnd; ++oIter)
     415                 :     {
     416                 :         const char* pszKey = oIter->first.GetName().c_str();
     417                 :         Get(pszKey);
     418                 :     }
     419                 : 
     420                 :     return m_map;
     421                 : }
     422                 : 
     423                 : GDALPDFArrayPodofo::~GDALPDFArrayPodofo()
     424                 : {
     425                 :     for(int i=0;i<(int)m_v.size();i++)
     426                 :     {
     427                 :         delete m_v[i];
     428                 :     }
     429                 : }
     430                 : 
     431                 : int GDALPDFArrayPodofo::GetLength()
     432                 : {
     433                 :     return (int)m_poArray->GetSize();
     434                 : }
     435                 : 
     436                 : GDALPDFObject* GDALPDFArrayPodofo::Get(int nIndex)
     437                 : {
     438                 :     if (nIndex < 0 || nIndex >= GetLength())
     439                 :         return NULL;
     440                 : 
     441                 :     int nOldSize = (int)m_v.size();
     442                 :     if (nIndex >= nOldSize)
     443                 :     {
     444                 :         m_v.resize(nIndex+1);
     445                 :         for(int i=nOldSize;i<=nIndex;i++)
     446                 :         {
     447                 :             m_v[i] = NULL;
     448                 :         }
     449                 :     }
     450                 : 
     451                 :     if (m_v[nIndex] != NULL)
     452                 :         return m_v[nIndex];
     453                 : 
     454                 :     PoDoFo::PdfObject& oVal = (*m_poArray)[nIndex];
     455                 :     GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(&oVal, m_poObjects);
     456                 :     m_v[nIndex] = poObj;
     457                 :     return poObj;
     458                 : }
     459                 : 
     460                 : #endif

Generated by: LCOV version 1.7