LTP GCOV extension - code coverage report
Current view: directory - gcore - gdalmultidomainmetadata.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 108
Code covered: 96.3 % Executed lines: 104

       1                 : /******************************************************************************
       2                 :  * $Id: gdalmultidomainmetadata.cpp 17282 2009-06-22 19:19:46Z warmerdam $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALMultiDomainMetadata class.  This class
       6                 :  *           manages metadata items for a variable list of domains. 
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "gdal_pam.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : CPL_CVSID("$Id: gdalmultidomainmetadata.cpp 17282 2009-06-22 19:19:46Z warmerdam $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                      GDALMultiDomainMetadata()                       */
      38                 : /************************************************************************/
      39                 : 
      40         1079158 : GDALMultiDomainMetadata::GDALMultiDomainMetadata()
      41                 : 
      42                 : {
      43         1079158 :     papszDomainList = NULL;
      44         1079158 :     papapszMetadataLists = NULL;
      45         1079158 : }
      46                 : 
      47                 : /************************************************************************/
      48                 : /*                      ~GDALMultiDomainMetadata()                      */
      49                 : /************************************************************************/
      50                 : 
      51         1077909 : GDALMultiDomainMetadata::~GDALMultiDomainMetadata()
      52                 : 
      53                 : {
      54         1077909 :     Clear();
      55         1077909 : }
      56                 : 
      57                 : /************************************************************************/
      58                 : /*                               Clear()                                */
      59                 : /************************************************************************/
      60                 : 
      61         1077909 : void GDALMultiDomainMetadata::Clear()
      62                 : 
      63                 : {
      64                 :     int i, nDomainCount;
      65                 : 
      66         1077909 :     nDomainCount = CSLCount( papszDomainList );
      67         1077909 :     CSLDestroy( papszDomainList );
      68         1077909 :     papszDomainList = NULL;
      69                 : 
      70         1126775 :     for( i = 0; i < nDomainCount; i++ )
      71                 :     {
      72           48866 :         CSLDestroy( papapszMetadataLists[i] );
      73                 :     }
      74         1077909 :     CPLFree( papapszMetadataLists );
      75         1077909 :     papapszMetadataLists = NULL;
      76         1077909 : }
      77                 : 
      78                 : 
      79                 : /************************************************************************/
      80                 : /*                            GetMetadata()                             */
      81                 : /************************************************************************/
      82                 : 
      83           43833 : char **GDALMultiDomainMetadata::GetMetadata( const char *pszDomain )
      84                 : 
      85                 : {
      86           43833 :     if( pszDomain == NULL )
      87             328 :         pszDomain = "";
      88                 : 
      89           43833 :     int iDomain = CSLFindString( papszDomainList, pszDomain );
      90                 : 
      91           43833 :     if( iDomain == -1 )
      92           25480 :         return NULL;
      93                 :     else
      94           18353 :         return papapszMetadataLists[iDomain];
      95                 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                            SetMetadata()                             */
      99                 : /************************************************************************/
     100                 : 
     101                 : CPLErr GDALMultiDomainMetadata::SetMetadata( char **papszMetadata, 
     102            2945 :                                              const char *pszDomain )
     103                 : 
     104                 : {
     105            2945 :     if( pszDomain == NULL )
     106               0 :         pszDomain = "";
     107                 : 
     108            2945 :     int iDomain = CSLFindString( papszDomainList, pszDomain );
     109                 : 
     110            2945 :     if( iDomain == -1 )
     111                 :     {
     112                 :         int nDomainCount;
     113                 : 
     114            2452 :         papszDomainList = CSLAddString( papszDomainList, pszDomain );
     115            2452 :         nDomainCount = CSLCount( papszDomainList );
     116                 : 
     117                 :         papapszMetadataLists = (char ***) 
     118            2452 :             CPLRealloc( papapszMetadataLists, sizeof(char*)*(nDomainCount+1) );
     119            2452 :         papapszMetadataLists[nDomainCount] = NULL;
     120            2452 :         papapszMetadataLists[nDomainCount-1] = CSLDuplicate( papszMetadata );
     121                 :     }
     122                 :     else
     123                 :     {
     124             493 :         CSLDestroy( papapszMetadataLists[iDomain] );
     125             493 :         papapszMetadataLists[iDomain] = CSLDuplicate( papszMetadata );
     126                 :     }
     127                 : 
     128            2945 :     return CE_None;
     129                 : }
     130                 : 
     131                 : /************************************************************************/
     132                 : /*                          GetMetadataItem()                           */
     133                 : /************************************************************************/
     134                 : 
     135                 : const char *GDALMultiDomainMetadata::GetMetadataItem( const char *pszName, 
     136           33444 :                                                       const char *pszDomain )
     137                 : 
     138                 : {
     139           33444 :     char **papszMD = GetMetadata( pszDomain );
     140           33444 :     if( papszMD != NULL )
     141           13168 :         return CSLFetchNameValue( papszMD, pszName );
     142                 :     else
     143           20276 :         return NULL;
     144                 : }
     145                 : 
     146                 : /************************************************************************/
     147                 : /*                          SetMetadataItem()                           */
     148                 : /************************************************************************/
     149                 : 
     150                 : CPLErr GDALMultiDomainMetadata::SetMetadataItem( const char *pszName,
     151                 :                                                  const char *pszValue,
     152          175886 :                                                  const char *pszDomain )
     153                 : 
     154                 : {
     155          175886 :     if( pszDomain == NULL )
     156               1 :         pszDomain = "";
     157                 : 
     158          175886 :     int iDomain = CSLFindString( papszDomainList, pszDomain );
     159                 : 
     160                 : /* -------------------------------------------------------------------- */
     161                 : /*      Create the domain if it does not already exist.                 */
     162                 : /* -------------------------------------------------------------------- */
     163          175886 :     if( iDomain == -1 )
     164                 :     {
     165                 :         int nDomainCount;
     166                 : 
     167           47651 :         papszDomainList = CSLAddString( papszDomainList, pszDomain );
     168           47651 :         nDomainCount = CSLCount( papszDomainList );
     169                 : 
     170                 :         papapszMetadataLists = (char ***) 
     171           47651 :             CPLRealloc( papapszMetadataLists, sizeof(char*)*(nDomainCount+1) );
     172           47651 :         papapszMetadataLists[nDomainCount] = NULL;
     173           47651 :         iDomain = nDomainCount-1;
     174           47651 :         papapszMetadataLists[iDomain] = NULL;
     175                 :     }
     176                 : 
     177                 : /* -------------------------------------------------------------------- */
     178                 : /*      Set the value in the domain list.                               */
     179                 : /* -------------------------------------------------------------------- */
     180          175886 :     if( pszValue != NULL )
     181                 :     {
     182                 :         papapszMetadataLists[iDomain] = 
     183                 :             CSLSetNameValue( papapszMetadataLists[iDomain], 
     184          175886 :                              pszName, pszValue );
     185                 :     }
     186                 : 
     187                 : /* -------------------------------------------------------------------- */
     188                 : /*      Remove the target key from the domain list.                     */
     189                 : /* -------------------------------------------------------------------- */
     190                 :     else
     191                 :     {
     192               0 :         int iKey = CSLFindName( papapszMetadataLists[iDomain], pszName );
     193                 : 
     194               0 :         if( iKey != -1 )
     195                 :             papapszMetadataLists[iDomain] = 
     196               0 :                 CSLRemoveStrings(papapszMetadataLists[iDomain],iKey,1,NULL);
     197                 :     }
     198                 : 
     199          175886 :     return CE_None;
     200                 : }
     201                 : 
     202                 : /************************************************************************/
     203                 : /*                              XMLInit()                               */
     204                 : /*                                                                      */
     205                 : /*      This method should be invoked on the parent of the              */
     206                 : /*      <Metadata> elements.                                            */
     207                 : /************************************************************************/
     208                 : 
     209            1198 : int GDALMultiDomainMetadata::XMLInit( CPLXMLNode *psTree, int bMerge )
     210                 : 
     211                 : {
     212                 :     CPLXMLNode *psMetadata;
     213                 : 
     214                 : /* ==================================================================== */
     215                 : /*      Process all <Metadata> elements, each for one domain.           */
     216                 : /* ==================================================================== */
     217            5080 :     for( psMetadata = psTree->psChild; 
     218                 :          psMetadata != NULL; psMetadata = psMetadata->psNext )
     219                 :     {
     220            3882 :         char **papszMD = NULL;
     221                 :         CPLXMLNode *psMDI;
     222                 :         const char *pszDomain, *pszFormat;
     223                 : 
     224            3882 :         if( psMetadata->eType != CXT_Element
     225                 :             || !EQUAL(psMetadata->pszValue,"Metadata") )
     226            3343 :             continue;
     227                 : 
     228             539 :         pszDomain = CPLGetXMLValue( psMetadata, "domain", "" );
     229             539 :         pszFormat = CPLGetXMLValue( psMetadata, "format", "" );
     230                 : 
     231                 : /* -------------------------------------------------------------------- */
     232                 : /*      XML format subdocuments.                                        */
     233                 : /* -------------------------------------------------------------------- */
     234             539 :         if( EQUAL(pszFormat,"xml") )
     235                 :         {
     236                 :             CPLXMLNode *psSubDoc;
     237                 : 
     238                 :             /* find first non-attribute child of current element */
     239               3 :             psSubDoc = psMetadata->psChild;
     240              12 :             while( psSubDoc != NULL && psSubDoc->eType == CXT_Attribute )
     241               6 :                 psSubDoc = psSubDoc->psNext;
     242                 :             
     243               3 :             char *pszDoc = CPLSerializeXMLTree( psSubDoc );
     244                 : 
     245               3 :             papszMD = (char **) CPLCalloc(sizeof(char*),2);
     246               3 :             papszMD[0] = pszDoc;
     247                 :         }
     248                 : 
     249                 : /* -------------------------------------------------------------------- */
     250                 : /*      Name value format.                                              */
     251                 : /*      <MDI key="...">value_Text</MDI>                                 */
     252                 : /* -------------------------------------------------------------------- */
     253                 :         else
     254                 :         {
     255             536 :             if( bMerge )
     256                 :             {
     257             536 :                 papszMD = GetMetadata( pszDomain );
     258             536 :                 if( papszMD != NULL )
     259             277 :                     papszMD = CSLDuplicate( papszMD );
     260                 :             }
     261                 :             
     262            3754 :             for( psMDI = psMetadata->psChild; psMDI != NULL; 
     263                 :                  psMDI = psMDI->psNext )
     264                 :             {
     265            3218 :                 if( !EQUAL(psMDI->pszValue,"MDI") 
     266                 :                     || psMDI->eType != CXT_Element 
     267                 :                     || psMDI->psChild == NULL 
     268                 :                     || psMDI->psChild->psNext == NULL 
     269                 :                     || psMDI->psChild->eType != CXT_Attribute
     270                 :                     || psMDI->psChild->psChild == NULL )
     271            1180 :                     continue;
     272                 :                 
     273                 :                 papszMD = 
     274                 :                     CSLSetNameValue( papszMD, 
     275                 :                                      psMDI->psChild->psChild->pszValue, 
     276            2038 :                                      psMDI->psChild->psNext->pszValue );
     277                 :             }
     278                 :         }
     279                 : 
     280             539 :         SetMetadata( papszMD, pszDomain );
     281             539 :         CSLDestroy( papszMD );
     282                 :     }
     283                 : 
     284            1198 :     return CSLCount(papszDomainList) != 0;
     285                 : }
     286                 : 
     287                 : /************************************************************************/
     288                 : /*                             Serialize()                              */
     289                 : /************************************************************************/
     290                 : 
     291            1758 : CPLXMLNode *GDALMultiDomainMetadata::Serialize()
     292                 : 
     293                 : {
     294            1758 :     CPLXMLNode *psFirst = NULL;
     295                 : 
     296            2603 :     for( int iDomain = 0; 
     297                 :          papszDomainList != NULL && papszDomainList[iDomain] != NULL; 
     298                 :          iDomain++)
     299                 :     {
     300             845 :         char **papszMD = papapszMetadataLists[iDomain];
     301                 :         CPLXMLNode *psMD;
     302             845 :         int bFormatXML = FALSE;
     303                 :         
     304             845 :         psMD = CPLCreateXMLNode( NULL, CXT_Element, "Metadata" );
     305                 : 
     306             845 :         if( strlen( papszDomainList[iDomain] ) > 0 )
     307                 :             CPLCreateXMLNode( 
     308                 :                 CPLCreateXMLNode( psMD, CXT_Attribute, "domain" ), 
     309             154 :                 CXT_Text, papszDomainList[iDomain] );
     310                 : 
     311             845 :         if( EQUALN(papszDomainList[iDomain],"xml:",4) 
     312                 :             && CSLCount(papszMD) == 1 )
     313                 :         {
     314               1 :             CPLXMLNode *psValueAsXML = CPLParseXMLString( papszMD[0] );
     315               1 :             if( psValueAsXML != NULL )
     316                 :             {
     317               1 :                 bFormatXML = TRUE;
     318                 : 
     319                 :                 CPLCreateXMLNode( 
     320                 :                     CPLCreateXMLNode( psMD, CXT_Attribute, "format" ), 
     321               1 :                     CXT_Text, "xml" );
     322                 :                 
     323               1 :                 CPLAddXMLChild( psMD, psValueAsXML );
     324                 :             }
     325                 :         }
     326                 : 
     327             845 :         if( !bFormatXML )
     328                 :         {
     329            4142 :             for( int i = 0; papszMD != NULL && papszMD[i] != NULL; i++ )
     330                 :             {
     331                 :                 const char *pszRawValue;
     332                 :                 char *pszKey;
     333                 :                 CPLXMLNode *psMDI;
     334                 :                 
     335            3298 :                 pszRawValue = CPLParseNameValue( papszMD[i], &pszKey );
     336                 :                 
     337            3298 :                 psMDI = CPLCreateXMLNode( psMD, CXT_Element, "MDI" );
     338            3298 :                 CPLSetXMLValue( psMDI, "#key", pszKey );
     339            3298 :                 CPLCreateXMLNode( psMDI, CXT_Text, pszRawValue );
     340                 :                 
     341            3298 :                 CPLFree( pszKey );
     342                 :             }
     343                 :         }
     344                 :             
     345             845 :         if( psFirst == NULL )
     346             780 :             psFirst = psMD;
     347                 :         else
     348              65 :             CPLAddXMLSibling( psFirst, psMD );
     349                 :     }
     350                 : 
     351            1758 :     return psFirst;
     352                 : }
     353                 : 

Generated by: LTP GCOV extension version 1.5