std::vector<HFAEntry*> HFAEntry::FindChildren( const char *pszName, const char *pszType ) { std::vector<HFAEntry*> apoChildren; HFAEntry *poEntry; if( this == NULL ) return apoChildren; for( poEntry = GetChild(); poEntry != NULL; poEntry = poEntry->GetNext() ) { std::vector<HFAEntry*> apoEntryChildren; size_t i; if( (pszName == NULL || EQUAL(poEntry->GetName(),pszName)) && (pszType == NULL || EQUAL(poEntry->GetType(),pszType)) ) apoChildren.push_back( poEntry ); apoEntryChildren = poEntry->FindChildren( pszName, pszType ); for( i = 0; i < apoEntryChildren.size(); i++ ) apoChildren.push_back( apoEntryChildren[i] ); } return apoChildren; }
std::vector<HFAEntry*> HFAEntry::FindChildren( const char *pszName, const char *pszType, int nRecLevel, int* pbErrorDetected ) { std::vector<HFAEntry*> apoChildren; if( *pbErrorDetected ) return apoChildren; if( nRecLevel == 50 ) { CPLError(CE_Failure, CPLE_AppDefined, "Bad entry structure: recursion detected !"); *pbErrorDetected = TRUE; return apoChildren; } for( HFAEntry *poEntry = GetChild(); poEntry != NULL; poEntry = poEntry->GetNext() ) { std::vector<HFAEntry*> apoEntryChildren; if( (pszName == NULL || EQUAL(poEntry->GetName(), pszName)) && (pszType == NULL || EQUAL(poEntry->GetType(), pszType)) ) apoChildren.push_back( poEntry ); apoEntryChildren = poEntry->FindChildren(pszName, pszType, nRecLevel + 1, pbErrorDetected); if( *pbErrorDetected ) return apoChildren; for( size_t i = 0; i < apoEntryChildren.size(); i++ ) apoChildren.push_back( apoEntryChildren[i] ); } return apoChildren; }
HFAHandle HFAOpen( const char * pszFilename, const char * pszAccess ) { FILE *fp; char szHeader[16]; HFAInfo_t *psInfo; GUInt32 nHeaderPos; HFAEntry *poNode; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( EQUAL(pszAccess,"r") || EQUAL(pszAccess,"rb" ) ) fp = VSIFOpen( pszFilename, "rb" ); else fp = VSIFOpen( pszFilename, "r+b" ); /* should this be changed to use some sort of CPLFOpen() which will set the error? */ if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File open of %s failed.", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Read and verify the header. */ /* -------------------------------------------------------------------- */ if( VSIFRead( szHeader, 16, 1, fp ) < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to read 16 byte header failed for\n%s.", pszFilename ); return NULL; } if( !EQUALN(szHeader,"EHFA_HEADER_TAG",15) ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s is not an Imagine HFA file ... header wrong.", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the HFAInfo_t */ /* -------------------------------------------------------------------- */ psInfo = (HFAInfo_t *) CPLCalloc(sizeof(HFAInfo_t),1); psInfo->fp = fp; /* -------------------------------------------------------------------- */ /* Where is the header? */ /* -------------------------------------------------------------------- */ VSIFRead( &nHeaderPos, sizeof(GInt32), 1, fp ); HFAStandard( 4, &nHeaderPos ); /* -------------------------------------------------------------------- */ /* Read the header. */ /* -------------------------------------------------------------------- */ VSIFSeek( fp, nHeaderPos, SEEK_SET ); VSIFRead( &(psInfo->nVersion), sizeof(GInt32), 1, fp ); HFAStandard( 4, &(psInfo->nVersion) ); VSIFRead( szHeader, 4, 1, fp ); /* skip freeList */ VSIFRead( &(psInfo->nRootPos), sizeof(GInt32), 1, fp ); HFAStandard( 4, &(psInfo->nRootPos) ); VSIFRead( &(psInfo->nEntryHeaderLength), sizeof(GInt16), 1, fp ); HFAStandard( 2, &(psInfo->nEntryHeaderLength) ); VSIFRead( &(psInfo->nDictionaryPos), sizeof(GInt32), 1, fp ); HFAStandard( 4, &(psInfo->nDictionaryPos) ); /* -------------------------------------------------------------------- */ /* Instantiate the root entry. */ /* -------------------------------------------------------------------- */ psInfo->poRoot = new HFAEntry( psInfo, psInfo->nRootPos, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Read the dictionary */ /* -------------------------------------------------------------------- */ psInfo->pszDictionary = HFAGetDictionary( psInfo ); psInfo->poDictionary = new HFADictionary( psInfo->pszDictionary ); /* -------------------------------------------------------------------- */ /* Find the first band node. */ /* -------------------------------------------------------------------- */ psInfo->nBands = 0; poNode = psInfo->poRoot->GetChild(); while( poNode != NULL ) { if( EQUAL(poNode->GetType(),"Eimg_Layer") ) { if( psInfo->nBands == 0 ) { psInfo->nXSize = poNode->GetIntField("width"); psInfo->nYSize = poNode->GetIntField("height"); } else if( poNode->GetIntField("width") != psInfo->nXSize || poNode->GetIntField("height") != psInfo->nYSize ) { CPLAssert( FALSE ); continue; } psInfo->papoBand = (HFABand **) CPLRealloc(psInfo->papoBand, sizeof(HFABand *) * (psInfo->nBands+1)); psInfo->papoBand[psInfo->nBands] = new HFABand( psInfo, poNode ); psInfo->nBands++; } poNode = poNode->GetNext(); } return psInfo; }