void *VSIMalloc( size_t nSize ) { if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE"); nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nSize > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nSize > nMaxCumulAllocSize) return NULL; #endif // DEBUG_VSIMALLOC_STATS #ifdef DEBUG_VSIMALLOC_MPROTECT char* ptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&ptr, nPageSize, (3 * sizeof(void*) + nSize + nPageSize - 1) & ~(nPageSize - 1)); #else char* ptr = (char*) malloc(3 * sizeof(void*) + nSize); #endif // DEBUG_VSIMALLOC_MPROTECT if (ptr == NULL) return NULL; ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + sizeof(void*), &nSize, sizeof(void*)); ptr[2 * sizeof(void*) + nSize + 0] = 'E'; ptr[2 * sizeof(void*) + nSize + 1] = 'V'; ptr[2 * sizeof(void*) + nSize + 2] = 'S'; ptr[2 * sizeof(void*) + nSize + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE if( nSize > THRESHOLD_PRINT ) { fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p" #ifdef DEBUG_VSIMALLOC_STATS ", current_cumul = " CPL_FRMT_GUIB #ifdef DEBUG_BLOCK_CACHE_USE ", block_cache_used = " CPL_FRMT_GIB #endif ", mal+cal-free = %d" #endif "\n", (void*)CPLGetPID(), (int)nSize, ptr + 2 * sizeof(void*) #ifdef DEBUG_VSIMALLOC_STATS , (GUIntBig)(nCurrentTotalAllocs + nSize), #ifdef DEBUG_BLOCK_CACHE_USE , GDALGetCacheUsed64() #endif ,(int)(nVSIMallocs + nVSICallocs - nVSIFrees) #endif ); } #endif // DEBUG_VSIMALLOC_VERBOSE #ifdef DEBUG_VSIMALLOC_STATS nVSIMallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif // DEBUG_VSIMALLOC_STATS }
GDALDataset *HDF4Dataset::Open( GDALOpenInfo * poOpenInfo ) { int32 i; if( !Identify( poOpenInfo ) ) return NULL; CPLMutexHolderD(&hHDF4Mutex); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ int32 hHDF4; // Attempt to increase maximum number of opened HDF files #ifdef HDF4_HAS_MAXOPENFILES intn nCurrMax, nSysLimit; if ( SDget_maxopenfiles(&nCurrMax, &nSysLimit) >= 0 && nCurrMax < nSysLimit ) { intn res = SDreset_maxopenfiles( nSysLimit ); } #endif /* HDF4_HAS_MAXOPENFILES */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); if( hHDF4 <= 0 ) return( NULL ); Hclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ HDF4Dataset *poDS; CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex poDS = new HDF4Dataset(); CPLAcquireMutex(hHDF4Mutex, 1000.0); poDS->fp = poOpenInfo->fp; poOpenInfo->fp = NULL; /* -------------------------------------------------------------------- */ /* Open HDF SDS Interface. */ /* -------------------------------------------------------------------- */ poDS->hSD = SDstart( poOpenInfo->pszFilename, DFACC_READ ); if ( poDS->hSD == -1 ) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF4 file \"%s\" for SDS reading.\n", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Now read Global Attributes. */ /* -------------------------------------------------------------------- */ if ( poDS->ReadGlobalAttributes( poDS->hSD ) != CE_None ) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to read global attributes from HDF4 file \"%s\".\n", poOpenInfo->pszFilename ); return NULL; } poDS->SetMetadata( poDS->papszGlobalMetadata, "" ); /* -------------------------------------------------------------------- */ /* Determine type of file we read. */ /* -------------------------------------------------------------------- */ const char *pszValue; if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Signature")) && EQUAL( pszValue, pszGDALSignature ) ) { poDS->iSubdatasetType = H4ST_GDAL; poDS->pszSubdatasetType = "GDAL_HDF4"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-1A Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L1A; poDS->pszSubdatasetType = "SEAWIFS_L1A"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-2 Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L2; poDS->pszSubdatasetType = "SEAWIFS_L2"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-3 Standard Mapped Image" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L3; poDS->pszSubdatasetType = "SEAWIFS_L3"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "L1 File Generated By")) && EQUALN( pszValue, "HYP version ", 12 ) ) { poDS->iSubdatasetType = H4ST_HYPERION_L1; poDS->pszSubdatasetType = "HYPERION_L1"; } else { poDS->iSubdatasetType = H4ST_UNKNOWN; poDS->pszSubdatasetType = "UNKNOWN"; } /* -------------------------------------------------------------------- */ /* If we have HDF-EOS dataset, process it here. */ /* -------------------------------------------------------------------- */ char szName[VSNAMELENMAX + 1], szTemp[8192]; char *pszString; const char *pszName; int nCount; int32 aiDimSizes[H4_MAX_VAR_DIMS]; int32 iRank, iNumType, nAttrs; bool bIsHDF = true; // Sometimes "HDFEOSVersion" attribute is not defined and we will // determine HDF-EOS datasets using other records // (see ReadGlobalAttributes() method). if ( poDS->bIsHDFEOS || CSLFetchNameValue(poDS->papszGlobalMetadata, "HDFEOSVersion") ) { bIsHDF = false; int32 nSubDatasets, nStrBufSize; /* -------------------------------------------------------------------- */ /* Process swath layers. */ /* -------------------------------------------------------------------- */ hHDF4 = SWopen( poOpenInfo->pszFilename, DFACC_READ ); if( hHDF4 < 0) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF-EOS file \"%s\" for swath reading.\n", poOpenInfo->pszFilename ); return NULL; } nSubDatasets = SWinqswath(poOpenInfo->pszFilename, NULL, &nStrBufSize); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS swaths: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszSwathList; char **papszSwaths; pszSwathList = (char *)CPLMalloc( nStrBufSize + 1 ); SWinqswath( poOpenInfo->pszFilename, pszSwathList, &nStrBufSize ); pszSwathList[nStrBufSize] = '\0'; #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS swaths: %s", pszSwathList ); #endif papszSwaths = CSLTokenizeString2( pszSwathList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszSwathList ); if ( nSubDatasets != CSLCount(papszSwaths) ) { CSLDestroy( papszSwaths ); CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hSW, nFields, j; hSW = SWattach( hHDF4, papszSwaths[i] ); nFields = SWnentries( hSW, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); SWinqdatafields( hSW, pszFieldList, paiRank, paiNumType ); #if DEBUG { char *pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of data fields in swath %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of data fields in swath %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Data fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { SWfieldinfo( hSW, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("HDF4_EOS:EOS_SWATH:\"%s\":%s:%s", poOpenInfo->pszFilename, papszSwaths[i], papszFields[j]) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s %s (%s)", pszString, papszFields[j], papszSwaths[i], poDS->GetDataTypeName(iNumType) ) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); SWdetach( hSW ); } CSLDestroy( papszSwaths ); } SWclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Process grid layers. */ /* -------------------------------------------------------------------- */ hHDF4 = GDopen( poOpenInfo->pszFilename, DFACC_READ ); nSubDatasets = GDinqgrid( poOpenInfo->pszFilename, NULL, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS grids: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszGridList; char **papszGrids; pszGridList = (char *)CPLMalloc( nStrBufSize + 1 ); GDinqgrid( poOpenInfo->pszFilename, pszGridList, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS grids: %s", pszGridList ); #endif papszGrids = CSLTokenizeString2( pszGridList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszGridList ); if ( nSubDatasets != CSLCount(papszGrids) ) { CSLDestroy( papszGrids ); GDclose( hHDF4 ); CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hGD, nFields, j; hGD = GDattach( hHDF4, papszGrids[i] ); nFields = GDnentries( hGD, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); GDinqfields( hGD, pszFieldList, paiRank, paiNumType ); #if DEBUG { char* pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of fields in grid %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of fields in grid %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { GDfieldinfo( hGD, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_EOS:EOS_GRID:\"%s\":%s:%s", poOpenInfo->pszFilename, papszGrids[i], papszFields[j])); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("[%s] %s %s (%s)", pszString, papszFields[j], papszGrids[i], poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); GDdetach( hGD ); } CSLDestroy( papszGrids ); } GDclose( hHDF4 ); bIsHDF = ( nSubDatasets == 0 ); // Try to read as HDF } if( bIsHDF ) { /* -------------------------------------------------------------------- */ /* Make a list of subdatasets from SDSs contained in input HDF file. */ /* -------------------------------------------------------------------- */ int32 nDatasets; if ( SDfileinfo( poDS->hSD, &nDatasets, &nAttrs ) != 0 ) return NULL; for ( i = 0; i < nDatasets; i++ ) { int32 iSDS; iSDS = SDselect( poDS->hSD, i ); if ( SDgetinfo( iSDS, szName, &iRank, aiDimSizes, &iNumType, &nAttrs) != 0 ) return NULL; if ( iRank == 1 ) // Skip 1D datsets continue; // Do sort of known datasets. We will display only image bands if ( (poDS->iSubdatasetType == H4ST_SEAWIFS_L1A ) && !EQUALN( szName, "l1a_data", 8 ) ) continue; else pszName = szName; // Add datasets with multiple dimensions to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use SDS index as an identificator, because SDS names // are not unique. Filename also needed for further file opening poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_SDS:%s:\"%s\":%ld", poDS->pszSubdatasetType, poOpenInfo->pszFilename, (long)i) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s (%s)", pszString, pszName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); SDendaccess( iSDS ); } SDend( poDS->hSD ); poDS->hSD = 0; } /* -------------------------------------------------------------------- */ /* Build a list of raster images. Note, that HDF-EOS dataset may */ /* contain a raster image as well. */ /* -------------------------------------------------------------------- */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); poDS->hGR = GRstart( hHDF4 ); if ( poDS->hGR != -1 ) { if ( GRfileinfo( poDS->hGR, &poDS->nImages, &nAttrs ) == -1 ) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } for ( i = 0; i < poDS->nImages; i++ ) { int32 iInterlaceMode; int32 iGR = GRselect( poDS->hGR, i ); // iRank in GR interface has another meaning. It represents number // of samples per pixel. aiDimSizes has only two dimensions. if ( GRgetiminfo( iGR, szName, &iRank, &iNumType, &iInterlaceMode, aiDimSizes, &nAttrs ) != 0 ) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp,CPLSPrintf( "HDF4_GR:UNKNOWN:\"%s\":%ld", poOpenInfo->pszFilename, (long)i)); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, 2, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%sx%ld] %s (%s)", pszString, (long)iRank, szName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); GRendaccess( iGR ); } GRend( poDS->hGR ); poDS->hGR = 0; } Hclose( hHDF4 ); poDS->nRasterXSize = poDS->nRasterYSize = 512; // XXX: bogus values // Make sure we don't try to do any pam stuff with this dataset. poDS->nPamFlags |= GPF_NOSAVE; /* -------------------------------------------------------------------- */ /* If we have single subdataset only, open it immediately */ /* -------------------------------------------------------------------- */ if ( CSLCount( poDS->papszSubDatasets ) / 2 == 1 ) { char *pszSDSName; pszSDSName = CPLStrdup( CSLFetchNameValue( poDS->papszSubDatasets, "SUBDATASET_1_NAME" )); CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; poDS = NULL; GDALDataset* poRetDS = (GDALDataset*) GDALOpen( pszSDSName, poOpenInfo->eAccess ); CPLFree( pszSDSName ); CPLAcquireMutex(hHDF4Mutex, 1000.0); if (poRetDS) { poRetDS->SetDescription(poOpenInfo->pszFilename); } return poRetDS; } else { /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLReleaseMutex(hHDF4Mutex); // Release mutex otherwise we'll deadlock with GDALDataset own mutex delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_NotSupported, "The HDF4 driver does not support update access to existing" " datasets.\n" ); return NULL; } } return( poDS ); }
void *VSICalloc( size_t nCount, size_t nSize ) { #ifdef DEBUG_VSIMALLOC size_t nMul = nCount * nSize; if (nCount != 0 && nMul / nCount != nSize) { fprintf(stderr, "Overflow in VSICalloc(%d, %d)\n", (int)nCount, (int)nSize); return NULL; } if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; char* pszMaxCumulAllocSize = getenv("CPL_MAX_CUMUL_ALLOC_SIZE"); nMaxCumulAllocSize = (pszMaxCumulAllocSize) ? atoi(pszMaxCumulAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nMul > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nMul > nMaxCumulAllocSize) return NULL; #endif #ifdef DEBUG_VSIMALLOC_MPROTECT char* ptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&ptr, nPageSize, (3 * sizeof(void*) + nMul + nPageSize - 1) & ~(nPageSize - 1)); if (ptr == NULL) return NULL; memset(ptr + 2 * sizeof(void*), 0, nMul); #else char* ptr = (char*) calloc(1, 3 * sizeof(void*) + nMul); if (ptr == NULL) return NULL; #endif ptr[0] = 'V'; ptr[1] = 'S'; ptr[2] = 'I'; ptr[3] = 'M'; memcpy(ptr + sizeof(void*), &nMul, sizeof(void*)); ptr[2 * sizeof(void*) + nMul + 0] = 'E'; ptr[2 * sizeof(void*) + nMul + 1] = 'V'; ptr[2 * sizeof(void*) + nMul + 2] = 'S'; ptr[2 * sizeof(void*) + nMul + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE if( nMul > THRESHOLD_PRINT ) { fprintf(stderr, "Thread[%p] VSICalloc(%d,%d) = %p\n", (void*)CPLGetPID(), (int)nCount, (int)nSize, ptr + 2 * sizeof(void*)); } #endif #ifdef DEBUG_VSIMALLOC_STATS nVSICallocs ++; if (nMaxTotalAllocs == 0) atexit(VSIShowMemStats); nCurrentTotalAllocs += nMul; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 2 * sizeof(void*); #else return calloc( nCount, nSize ); #endif }
GDALProxyPoolCacheEntry* GDALDatasetPool::RefDataset(const char* pszFileName, GDALAccess eAccess) { CPLMutexHolderD( GDALGetphDLMutex() ); return singleton->_RefDataset(pszFileName, eAccess); }
void GDALDatasetPool::UnrefDataset(GDALProxyPoolCacheEntry* cacheEntry) { CPLMutexHolderD( GDALGetphDLMutex() ); cacheEntry->refCount --; }
void CPLDebug( const char * pszCategory, const char * pszFormat, ... ) { CPLErrorContext *psCtx = CPLGetErrorContext(); char *pszMessage; va_list args; const char *pszDebug = CPLGetConfigOption("CPL_DEBUG",NULL); #define ERROR_MAX 25000 /* -------------------------------------------------------------------- */ /* Does this message pass our current criteria? */ /* -------------------------------------------------------------------- */ if( pszDebug == NULL ) return; if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") ) { size_t i, nLen = strlen(pszCategory); for( i = 0; pszDebug[i] != '\0'; i++ ) { if( EQUALN(pszCategory,pszDebug+i,nLen) ) break; } if( pszDebug[i] == '\0' ) return; } /* -------------------------------------------------------------------- */ /* Allocate a block for the error. */ /* -------------------------------------------------------------------- */ pszMessage = (char *) VSIMalloc( ERROR_MAX ); if( pszMessage == NULL ) return; /* -------------------------------------------------------------------- */ /* Dal -- always log a timestamp as the first part of the line */ /* to ensure one is looking at what one should be looking at! */ /* -------------------------------------------------------------------- */ pszMessage[0] = '\0'; #ifdef TIMESTAMP_DEBUG if( CPLGetConfigOption( "CPL_TIMESTAMP", NULL ) != NULL ) { strcpy( pszMessage, VSICTime( VSITime(NULL) ) ); // On windows anyway, ctime puts a \n at the end, but I'm not // convinced this is standard behaviour, so we'll get rid of it // carefully if (pszMessage[strlen(pszMessage) -1 ] == '\n') { pszMessage[strlen(pszMessage) - 1] = 0; // blow it out } strcat( pszMessage, ": " ); } #endif /* -------------------------------------------------------------------- */ /* Add the process memory size. */ /* -------------------------------------------------------------------- */ #ifdef MEMORY_DEBUG char szVmSize[32]; CPLsprintf( szVmSize, "[VmSize: %d] ", CPLGetProcessMemorySize()); strcat( pszMessage, szVmSize ); #endif //sprintf(pszMessage,"[%d] ", (int)getpid()); /* -------------------------------------------------------------------- */ /* Add the category. */ /* -------------------------------------------------------------------- */ strcat( pszMessage, pszCategory ); strcat( pszMessage, ": " ); /* -------------------------------------------------------------------- */ /* Format the application provided portion of the debug message. */ /* -------------------------------------------------------------------- */ va_start(args, pszFormat); CPLvsnprintf(pszMessage+strlen(pszMessage), ERROR_MAX - strlen(pszMessage), pszFormat, args); va_end(args); /* -------------------------------------------------------------------- */ /* Obfuscate any password in error message */ /* -------------------------------------------------------------------- */ char* pszPassword = strstr(pszMessage, "password="******"password="); while( *pszIter != ' ' && *pszIter != '\0' ) { *pszIter = 'X'; pszIter ++; } } /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None, pszMessage ); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler( CE_Debug, CPLE_None, pszMessage ); } VSIFree( pszMessage ); }
OGRDataSource *FGdbDriver::Open( const char* pszFilename, int bUpdate ) { // First check if we have to do any work. size_t nLen = strlen(pszFilename); if(! ((nLen >= 4 && EQUAL(pszFilename + nLen - 4, ".gdb")) || (nLen >= 5 && EQUAL(pszFilename + nLen - 5, ".gdb/"))) ) return NULL; long hr; /* Check that the filename is really a directory, to avoid confusion with */ /* Garmin MapSource - gdb format which can be a problem when the FileGDB */ /* driver is loaded as a plugin, and loaded before the GPSBabel driver */ /* (http://trac.osgeo.org/osgeo4w/ticket/245) */ VSIStatBuf stat; if( CPLStat( pszFilename, &stat ) != 0 || !VSI_ISDIR(stat.st_mode) ) { return NULL; } CPLMutexHolderD(&hMutex); FGdbDatabaseConnection* pConnection = oMapConnections[pszFilename]; if( pConnection != NULL ) { if( pConnection->IsFIDHackInProgress() ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open geodatabase at the moment since it is in 'FID hack mode'"); return NULL; } pConnection->m_nRefCount ++; CPLDebug("FileGDB", "ref_count of %s = %d now", pszFilename, pConnection->m_nRefCount); } else { Geodatabase* pGeoDatabase = new Geodatabase; hr = ::OpenGeodatabase(StringToWString(pszFilename), *pGeoDatabase); if (FAILED(hr)) { delete pGeoDatabase; if( OGRGetDriverByName("OpenFileGDB") != NULL && bUpdate == FALSE ) { std::wstring fgdb_error_desc_w; std::string fgdb_error_desc("Unknown error"); fgdbError er; er = FileGDBAPI::ErrorInfo::GetErrorDescription(static_cast<fgdbError>(hr), fgdb_error_desc_w); if ( er == S_OK ) { fgdb_error_desc = WStringToString(fgdb_error_desc_w); } CPLDebug("FileGDB", "Cannot open %s with FileGDB driver: %s. Failing silently so OpenFileGDB can be tried", pszFilename, fgdb_error_desc.c_str()); } else { GDBErr(hr, "Failed to open Geodatabase"); } oMapConnections.erase(pszFilename); return NULL; } CPLDebug("FileGDB", "Really opening %s", pszFilename); pConnection = new FGdbDatabaseConnection(pszFilename, pGeoDatabase); oMapConnections[pszFilename] = pConnection; } FGdbDataSource* pDS; pDS = new FGdbDataSource(this, pConnection); if(!pDS->Open( pszFilename, bUpdate, NULL ) ) { delete pDS; return NULL; } else { OGRMutexedDataSource* poMutexedDS = new OGRMutexedDataSource(pDS, TRUE, hMutex, TRUE); if( bUpdate ) return OGRCreateEmulatedTransactionDataSourceWrapper(poMutexedDS, this, TRUE, FALSE); else return poMutexedDS; } }
void CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args ) { CPLErrorContext *psCtx = CPLGetErrorContext(); /* -------------------------------------------------------------------- */ /* Expand the error message */ /* -------------------------------------------------------------------- */ #if defined(HAVE_VSNPRINTF) { int nPR; va_list wrk_args; #ifdef va_copy va_copy( wrk_args, args ); #else wrk_args = args; #endif while( ((nPR = vsnprintf( psCtx->szLastErrMsg, psCtx->nLastErrMsgMax, fmt, wrk_args )) == -1 || nPR >= psCtx->nLastErrMsgMax-1) && psCtx->nLastErrMsgMax < 1000000 ) { #ifdef va_copy va_end( wrk_args ); va_copy( wrk_args, args ); #else wrk_args = args; #endif psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } va_end( wrk_args ); } #else vsprintf( psCtx->szLastErrMsg, fmt, args); #endif /* -------------------------------------------------------------------- */ /* If the user provided his own error handling function, then */ /* call it, otherwise print the error to stderr and return. */ /* -------------------------------------------------------------------- */ psCtx->nLastErrNo = err_no; psCtx->eLastErrType = eErrClass; if( CPLGetConfigOption("CPL_LOG_ERRORS",NULL) != NULL ) CPLDebug( "CPLError", "%s", psCtx->szLastErrMsg ); /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler(eErrClass, err_no, psCtx->szLastErrMsg); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler(eErrClass, err_no, psCtx->szLastErrMsg); } if( eErrClass == CE_Fatal ) abort(); }
void GDALDatasetPool::CloseDataset(const char* pszFileName, GDALAccess eAccess) { CPLMutexHolderD( GDALGetphDLMutex() ); singleton->_CloseDataset(pszFileName, eAccess); }
static bool LoadProjLibrary() { CPLMutexHolderD( &hPROJMutex ); return LoadProjLibrary_unlocked(); }
int OGRProj4CT::InitializeNoLock( OGRSpatialReference * poSourceIn, OGRSpatialReference * poTargetIn ) { if( poSourceIn == NULL || poTargetIn == NULL ) return FALSE; poSRSSource = poSourceIn->Clone(); poSRSTarget = poTargetIn->Clone(); bSourceLatLong = CPL_TO_BOOL(poSRSSource->IsGeographic()); bTargetLatLong = CPL_TO_BOOL(poSRSTarget->IsGeographic()); /* -------------------------------------------------------------------- */ /* Setup source and target translations to radians for lat/long */ /* systems. */ /* -------------------------------------------------------------------- */ dfSourceToRadians = DEG_TO_RAD; bSourceWrap = false; dfSourceWrapLong = 0.0; if( bSourceLatLong ) { OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { dfSourceToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue()); if( dfSourceToRadians == 0.0 ) dfSourceToRadians = DEG_TO_RAD; } } dfTargetFromRadians = RAD_TO_DEG; bTargetWrap = false; dfTargetWrapLong = 0.0; if( bTargetLatLong ) { OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" ); if( poUNITS && poUNITS->GetChildCount() >= 2 ) { double dfTargetToRadians = CPLAtof(poUNITS->GetChild(1)->GetValue()); if( dfTargetToRadians != 0.0 ) dfTargetFromRadians = 1 / dfTargetToRadians; } } /* -------------------------------------------------------------------- */ /* Preliminary logic to setup wrapping. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL ) { bSourceWrap = true; bTargetWrap = true; dfSourceWrapLong = dfTargetWrapLong = CPLAtof(CPLGetConfigOption( "CENTER_LONG", "" )); CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong ); } const char *pszCENTER_LONG = poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfSourceWrapLong = CPLAtof(pszCENTER_LONG); bSourceWrap = true; CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong ); } pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" ); if( pszCENTER_LONG != NULL ) { dfTargetWrapLong = CPLAtof(pszCENTER_LONG); bTargetWrap = true; CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong ); } bCheckWithInvertProj = CPLTestBool(CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", "NO" )); // The threshold is experimental. Works well with the cases of ticket #2305. if( bSourceLatLong ) dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", ".1" )); else // 1 works well for most projections, except for +proj=aeqd that // requires a tolerance of 10000. dfThreshold = CPLAtof(CPLGetConfigOption( "THRESHOLD", "10000" )); // OGRThreadSafety: The following variable is not a thread safety issue // since the only issue is incrementing while accessing which at worse // means debug output could be one "increment" late. static int nDebugReportCount = 0; char *pszSrcProj4Defn = NULL; if( poSRSSource->exportToProj4( &pszSrcProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); return FALSE; } if( strlen(pszSrcProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for source SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } char *pszDstProj4Defn = NULL; if( poSRSTarget->exportToProj4( &pszDstProj4Defn ) != OGRERR_NONE ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } if( strlen(pszDstProj4Defn) == 0 ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); CPLError( CE_Failure, CPLE_AppDefined, "No PROJ.4 translation for destination SRS, coordinate\n" "transformation initialization has failed." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Optimization to avoid useless nadgrids evaluation. */ /* For example when converting between WGS84 and WebMercator */ /* -------------------------------------------------------------------- */ if( pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] == ' ' ) pszSrcProj4Defn[strlen(pszSrcProj4Defn)-1] = 0; if( pszDstProj4Defn[strlen(pszDstProj4Defn)-1] == ' ' ) pszDstProj4Defn[strlen(pszDstProj4Defn)-1] = 0; char* pszNeedle = strstr(pszSrcProj4Defn, " "); if( pszNeedle ) memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1); pszNeedle = strstr(pszDstProj4Defn, " "); if( pszNeedle ) memmove(pszNeedle, pszNeedle + 1, strlen(pszNeedle + 1)+1); if( (strstr(pszSrcProj4Defn, "+datum=WGS84") != NULL || strstr(pszSrcProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) && strstr(pszDstProj4Defn, "+nadgrids=@null ") != NULL && strstr(pszDstProj4Defn, "+towgs84") == NULL ) { char* pszDst = strstr(pszSrcProj4Defn, "+towgs84=0,0,0,0,0,0,0 "); if( pszDst != NULL ) { char *pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } else { memcpy(strstr(pszSrcProj4Defn, "+datum=WGS84"), "+ellps", 6); } pszDst = strstr(pszDstProj4Defn, "+nadgrids=@null "); char *pszSrc = pszDst + strlen("+nadgrids=@null "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); pszDst = strstr(pszDstProj4Defn, "+wktext "); if( pszDst ) { pszSrc = pszDst + strlen("+wktext "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } //bWGS84ToWebMercator = // strcmp(pszSrcProj4Defn, "+proj=longlat +ellps=WGS84 +no_defs") == 0 && // strcmp(pszDstProj4Defn, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0; } else if( (strstr(pszDstProj4Defn, "+datum=WGS84") != NULL || strstr(pszDstProj4Defn, "+ellps=WGS84 +towgs84=0,0,0,0,0,0,0 ") != NULL) && strstr(pszSrcProj4Defn, "+nadgrids=@null ") != NULL && strstr(pszSrcProj4Defn, "+towgs84") == NULL ) { char* pszDst = strstr(pszDstProj4Defn, "+towgs84=0,0,0,0,0,0,0 "); if( pszDst != NULL) { char* pszSrc = pszDst + strlen("+towgs84=0,0,0,0,0,0,0 "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } else memcpy(strstr(pszDstProj4Defn, "+datum=WGS84"), "+ellps", 6); pszDst = strstr(pszSrcProj4Defn, "+nadgrids=@null "); char* pszSrc = pszDst + strlen("+nadgrids=@null "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); pszDst = strstr(pszSrcProj4Defn, "+wktext "); if( pszDst ) { pszSrc = pszDst + strlen("+wktext "); memmove(pszDst, pszSrc, strlen(pszSrc)+1); } bWebMercatorToWGS84 = strcmp(pszDstProj4Defn, "+proj=longlat +ellps=WGS84 +no_defs") == 0 && strcmp(pszSrcProj4Defn, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 " "+x_0=0.0 +y_0=0 +k=1.0 +units=m +no_defs") == 0; } /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for source if projection. */ /* -------------------------------------------------------------------- */ if( !bWebMercatorToWGS84 ) { if (pjctx) psPJSource = pfn_pj_init_plus_ctx( pjctx, pszSrcProj4Defn ); else psPJSource = pfn_pj_init_plus( pszSrcProj4Defn ); if( psPJSource == NULL ) { if( pjctx != NULL) { int l_pj_errno = pfn_pj_ctx_get_errno(pjctx); /* pfn_pj_strerrno not yet thread-safe in PROJ 4.8.0 */ CPLMutexHolderD(&hPROJMutex); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(l_pj_errno) ); } else if( pfn_pj_get_errno_ref != NULL && pfn_pj_strerrno != NULL ) { int *p_pj_errno = pfn_pj_get_errno_ref(); CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n%s", pszSrcProj4Defn, pfn_pj_strerrno(*p_pj_errno) ); } else { CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.\n", pszSrcProj4Defn ); } } } if( nDebugReportCount < 10 ) CPLDebug( "OGRCT", "Source: %s", pszSrcProj4Defn ); if( !bWebMercatorToWGS84 && psPJSource == NULL ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } /* -------------------------------------------------------------------- */ /* Establish PROJ.4 handle for target if projection. */ /* -------------------------------------------------------------------- */ if( !bWebMercatorToWGS84 ) { if (pjctx) psPJTarget = pfn_pj_init_plus_ctx( pjctx, pszDstProj4Defn ); else psPJTarget = pfn_pj_init_plus( pszDstProj4Defn ); if( psPJTarget == NULL ) CPLError( CE_Failure, CPLE_NotSupported, "Failed to initialize PROJ.4 with `%s'.", pszDstProj4Defn ); } if( nDebugReportCount < 10 ) { CPLDebug( "OGRCT", "Target: %s", pszDstProj4Defn ); nDebugReportCount++; } if( !bWebMercatorToWGS84 && psPJTarget == NULL ) { CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return FALSE; } /* Determine if we really have a transformation to do */ bIdentityTransform = strcmp(pszSrcProj4Defn, pszDstProj4Defn) == 0; #if 0 /* In case of identity transform, under the following conditions, */ /* we can also avoid transforming from degrees <--> radians. */ if( bIdentityTransform && bSourceLatLong && !bSourceWrap && bTargetLatLong && !bTargetWrap && fabs(dfSourceToRadians * dfTargetFromRadians - 1.0) < 1e-10 ) { // bSourceLatLong = false; // bTargetLatLong = false; } #endif CPLFree( pszSrcProj4Defn ); CPLFree( pszDstProj4Defn ); return TRUE; }
OGRDataSource *FGdbDriver::Open( const char* pszFilename, int bUpdate ) { // First check if we have to do any work. int nLen = strlen(pszFilename); if(! ((nLen >= 4 && EQUAL(pszFilename + nLen - 4, ".gdb")) || (nLen >= 5 && EQUAL(pszFilename + nLen - 5, ".gdb/"))) ) return NULL; long hr; /* Check that the filename is really a directory, to avoid confusion with */ /* Garmin MapSource - gdb format which can be a problem when the FileGDB */ /* driver is loaded as a plugin, and loaded before the GPSBabel driver */ /* (http://trac.osgeo.org/osgeo4w/ticket/245) */ VSIStatBuf stat; if( CPLStat( pszFilename, &stat ) != 0 || !VSI_ISDIR(stat.st_mode) ) { return NULL; } CPLMutexHolderD(&hMutex); Geodatabase* pGeoDatabase = NULL; FGdbDatabaseConnection* pConnection = oMapConnections[pszFilename]; if( pConnection != NULL ) { pGeoDatabase = pConnection->m_pGeodatabase; pConnection->m_nRefCount ++; CPLDebug("FileGDB", "ref_count of %s = %d now", pszFilename, pConnection->m_nRefCount); } else { pGeoDatabase = new Geodatabase; hr = ::OpenGeodatabase(StringToWString(pszFilename), *pGeoDatabase); if (FAILED(hr) || pGeoDatabase == NULL) { delete pGeoDatabase; GDBErr(hr, "Failed to open Geodatabase"); return NULL; } CPLDebug("FileGDB", "Really opening %s", pszFilename); oMapConnections[pszFilename] = new FGdbDatabaseConnection(pGeoDatabase); } FGdbDataSource* pDS; pDS = new FGdbDataSource(this); if(!pDS->Open( pGeoDatabase, pszFilename, bUpdate ) ) { delete pDS; return NULL; } else return new OGRMutexedDataSource(pDS, TRUE, hMutex); }
OGRDataSource* FGdbDriver::CreateDataSource( const char * conn, char **papszOptions) { long hr; Geodatabase *pGeodatabase; std::wstring wconn = StringToWString(conn); int bUpdate = TRUE; // If we're creating, we must be writing. VSIStatBuf stat; CPLMutexHolderD(&hMutex); /* We don't support options yet, so warn if they send us some */ if ( papszOptions ) { /* TODO: warning, ignoring options */ } /* Only accept names of form "filename.gdb" and */ /* also .gdb.zip to be able to return FGDB with MapServer OGR output (#4199) */ const char* pszExt = CPLGetExtension(conn); if ( !(EQUAL(pszExt,"gdb") || EQUAL(pszExt, "zip")) ) { CPLError( CE_Failure, CPLE_AppDefined, "FGDB data source name must use 'gdb' extension.\n" ); return NULL; } /* Don't try to create on top of something already there */ if( CPLStat( conn, &stat ) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "%s already exists.\n", conn ); return NULL; } /* Try to create the geodatabase */ pGeodatabase = new Geodatabase; // Create on heap so we can store it in the Datasource hr = CreateGeodatabase(wconn, *pGeodatabase); /* Handle creation errors */ if ( S_OK != hr ) { const char *errstr = "Error creating geodatabase (%s).\n"; if ( hr == -2147220653 ) errstr = "File already exists (%s).\n"; delete pGeodatabase; CPLError( CE_Failure, CPLE_AppDefined, errstr, conn ); return NULL; } oMapConnections[conn] = new FGdbDatabaseConnection(pGeodatabase); /* Ready to embed the Geodatabase in an OGR Datasource */ FGdbDataSource* pDS = new FGdbDataSource(this); if ( ! pDS->Open(pGeodatabase, conn, bUpdate) ) { delete pDS; return NULL; } else return new OGRMutexedDataSource(pDS, TRUE, hMutex); }
void * VSIRealloc( void * pData, size_t nNewSize ) { #ifdef DEBUG_VSIMALLOC if (pData == NULL) return VSIMalloc(nNewSize); char* ptr = ((char*)pData) - 2 * sizeof(void*); VSICheckMarkerBegin(ptr); size_t nOldSize; memcpy(&nOldSize, ptr + sizeof(void*), sizeof(void*)); VSICheckMarkerEnd(ptr, 2 * sizeof(void*) + nOldSize); ptr[2 * sizeof(void*) + nOldSize + 0] = 'I'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'E'; if (nMaxPeakAllocSize < 0) { char* pszMaxPeakAllocSize = getenv("CPL_MAX_PEAK_ALLOC_SIZE"); nMaxPeakAllocSize = (pszMaxPeakAllocSize) ? atoi(pszMaxPeakAllocSize) : 0; } if (nMaxPeakAllocSize > 0 && (GIntBig)nNewSize > nMaxPeakAllocSize) return NULL; #ifdef DEBUG_VSIMALLOC_STATS if (nMaxCumulAllocSize > 0 && (GIntBig)nCurrentTotalAllocs + (GIntBig)nNewSize - (GIntBig)nOldSize > nMaxCumulAllocSize) return NULL; #endif #ifdef DEBUG_VSIMALLOC_MPROTECT char* newptr = NULL; size_t nPageSize = getpagesize(); posix_memalign((void**)&newptr, nPageSize, (nNewSize + 3 * sizeof(void*) + nPageSize - 1) & ~(nPageSize - 1)); if (newptr == NULL) { ptr[2 * sizeof(void*) + nOldSize + 0] = 'E'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'I'; return NULL; } memcpy(newptr + 2 * sizeof(void*), pData, nOldSize); ptr[0] = 'M'; ptr[1] = 'I'; ptr[2] = 'S'; ptr[3] = 'V'; free(ptr); newptr[0] = 'V'; newptr[1] = 'S'; newptr[2] = 'I'; newptr[3] = 'M'; #else void* newptr = realloc(ptr, nNewSize + 3 * sizeof(void*)); if (newptr == NULL) { ptr[2 * sizeof(void*) + nOldSize + 0] = 'E'; ptr[2 * sizeof(void*) + nOldSize + 1] = 'V'; ptr[2 * sizeof(void*) + nOldSize + 2] = 'S'; ptr[2 * sizeof(void*) + nOldSize + 3] = 'I'; return NULL; } #endif ptr = (char*) newptr; memcpy(ptr + sizeof(void*), &nNewSize, sizeof(void*)); ptr[2 * sizeof(void*) + nNewSize + 0] = 'E'; ptr[2 * sizeof(void*) + nNewSize + 1] = 'V'; ptr[2 * sizeof(void*) + nNewSize + 2] = 'S'; ptr[2 * sizeof(void*) + nNewSize + 3] = 'I'; #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE) { CPLMutexHolderD(&hMemStatMutex); #ifdef DEBUG_VSIMALLOC_VERBOSE fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n", (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 2 * sizeof(void*)); #endif #ifdef DEBUG_VSIMALLOC_STATS nVSIReallocs ++; nCurrentTotalAllocs -= nOldSize; nCurrentTotalAllocs += nNewSize; if (nCurrentTotalAllocs > nMaxTotalAllocs) nMaxTotalAllocs = nCurrentTotalAllocs; #endif } #endif return ptr + 2 * sizeof(void*); #else return( realloc( pData, nNewSize ) ); #endif }
const char *PamAllocateProxy( const char *pszOriginal ) { InitProxyDB(); if( poProxyDB == NULL ) return NULL; CPLMutexHolderD( &hProxyDBLock ); poProxyDB->CheckLoadDB(); /* -------------------------------------------------------------------- */ /* Form the proxy filename based on the original path if */ /* possible, but dummy out any questionable characters, path */ /* delimiters and such. This is intended to make the proxy */ /* name be identifiable by folks digging around in the proxy */ /* database directory. */ /* */ /* We also need to be careful about length. */ /* -------------------------------------------------------------------- */ CPLString osRevProxyFile; int i; i = strlen(pszOriginal) - 1; while( i >= 0 && osRevProxyFile.size() < 220 ) { if( i > 6 && EQUALN(pszOriginal+i-5,":::OVR",6) ) i -= 6; // make some effort to break long names at path delimiters. if( (pszOriginal[i] == '/' || pszOriginal[i] == '\\') && osRevProxyFile.size() > 200 ) break; if( (pszOriginal[i] >= 'A' && pszOriginal[i] <= 'Z') || (pszOriginal[i] >= 'a' && pszOriginal[i] <= 'z') || (pszOriginal[i] >= '0' && pszOriginal[i] <= '9') || pszOriginal[i] == '.' ) osRevProxyFile += pszOriginal[i]; else osRevProxyFile += '_'; i--; } CPLString osOriginal = pszOriginal; CPLString osProxy; CPLString osCounter; osProxy = poProxyDB->osProxyDBDir + "/"; osCounter.Printf( "%06d_", poProxyDB->nUpdateCounter++ ); osProxy += osCounter; for( i = osRevProxyFile.size()-1; i >= 0; i-- ) osProxy += osRevProxyFile[i]; if( osOriginal.find(":::OVR") != CPLString::npos ) osProxy += ".ovr"; else osProxy += ".aux.xml"; /* -------------------------------------------------------------------- */ /* Add the proxy and the original to the proxy list and resave */ /* the database. */ /* -------------------------------------------------------------------- */ poProxyDB->aosOriginalFiles.push_back( osOriginal ); poProxyDB->aosProxyFiles.push_back( osProxy ); poProxyDB->SaveDB(); return PamGetProxy( pszOriginal ); }
OGRErr OGRDataSource::ProcessSQLCreateIndex( const char *pszSQLCommand ) { char **papszTokens = CSLTokenizeString( pszSQLCommand ); /* -------------------------------------------------------------------- */ /* Do some general syntax checking. */ /* -------------------------------------------------------------------- */ if( CSLCount(papszTokens) != 6 || !EQUAL(papszTokens[0],"CREATE") || !EQUAL(papszTokens[1],"INDEX") || !EQUAL(papszTokens[2],"ON") || !EQUAL(papszTokens[4],"USING") ) { CSLDestroy( papszTokens ); CPLError( CE_Failure, CPLE_AppDefined, "Syntax error in CREATE INDEX command.\n" "Was '%s'\n" "Should be of form 'CREATE INDEX ON <table> USING <field>'", pszSQLCommand ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Find the named layer. */ /* -------------------------------------------------------------------- */ int i; OGRLayer *poLayer = NULL; { CPLMutexHolderD( &m_hMutex ); for( i = 0; i < GetLayerCount(); i++ ) { poLayer = GetLayer(i); if( EQUAL(poLayer->GetLayerDefn()->GetName(),papszTokens[3]) ) break; } if( i >= GetLayerCount() ) { CPLError( CE_Failure, CPLE_AppDefined, "CREATE INDEX ON failed, no such layer as `%s'.", papszTokens[3] ); CSLDestroy( papszTokens ); return OGRERR_FAILURE; } } /* -------------------------------------------------------------------- */ /* Does this layer even support attribute indexes? */ /* -------------------------------------------------------------------- */ if( poLayer->GetIndex() == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "CREATE INDEX ON not supported by this driver." ); CSLDestroy( papszTokens ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Find the named field. */ /* -------------------------------------------------------------------- */ for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ ) { if( EQUAL(papszTokens[5], poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) ) break; } CSLDestroy( papszTokens ); if( i >= poLayer->GetLayerDefn()->GetFieldCount() ) { CPLError( CE_Failure, CPLE_AppDefined, "`%s' failed, field not found.", pszSQLCommand ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Attempt to create the index. */ /* -------------------------------------------------------------------- */ OGRErr eErr; eErr = poLayer->GetIndex()->CreateIndex( i ); if( eErr == OGRERR_NONE ) eErr = poLayer->GetIndex()->IndexAllFeatures( i ); return eErr; }
void CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args ) { CPLErrorContext *psCtx = CPLGetErrorContext(); if (psCtx->nFailureIntoWarning > 0 && eErrClass == CE_Failure) eErrClass = CE_Warning; /* -------------------------------------------------------------------- */ /* Expand the error message */ /* -------------------------------------------------------------------- */ #if defined(HAVE_VSNPRINTF) { int nPR; va_list wrk_args; #ifdef va_copy va_copy( wrk_args, args ); #else wrk_args = args; #endif /* -------------------------------------------------------------------- */ /* If CPL_ACCUM_ERROR_MSG=ON accumulate the error messages, */ /* rather than just replacing the last error message. */ /* -------------------------------------------------------------------- */ int nPreviousSize = 0; if ( psCtx->psHandlerStack != NULL && EQUAL(CPLGetConfigOption( "CPL_ACCUM_ERROR_MSG", "" ), "ON")) { nPreviousSize = strlen(psCtx->szLastErrMsg); if (nPreviousSize) { if (nPreviousSize + 1 + 1 >= psCtx->nLastErrMsgMax) { psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } psCtx->szLastErrMsg[nPreviousSize] = '\n'; psCtx->szLastErrMsg[nPreviousSize+1] = '0'; nPreviousSize ++; } } while( ((nPR = CPLvsnprintf( psCtx->szLastErrMsg+nPreviousSize, psCtx->nLastErrMsgMax-nPreviousSize, fmt, wrk_args )) == -1 || nPR >= psCtx->nLastErrMsgMax-nPreviousSize-1) && psCtx->nLastErrMsgMax < 1000000 ) { #ifdef va_copy va_end( wrk_args ); va_copy( wrk_args, args ); #else wrk_args = args; #endif psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } va_end( wrk_args ); } #else // !HAVE_VSNPRINTF CPLvsnprintf( psCtx->szLastErrMsg, psCtx->nLastErrMsgMax, fmt, args); #endif /* -------------------------------------------------------------------- */ /* Obfuscate any password in error message */ /* -------------------------------------------------------------------- */ char* pszPassword = strstr(psCtx->szLastErrMsg, "password="******"password="******"CPL_LOG_ERRORS",NULL) != NULL ) CPLDebug( "CPLError", "%s", psCtx->szLastErrMsg ); /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler(eErrClass, err_no, psCtx->szLastErrMsg); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler(eErrClass, err_no, psCtx->szLastErrMsg); } if( eErrClass == CE_Fatal ) abort(); }
OGRErr OGRDataSource::ProcessSQLDropIndex( const char *pszSQLCommand ) { char **papszTokens = CSLTokenizeString( pszSQLCommand ); /* -------------------------------------------------------------------- */ /* Do some general syntax checking. */ /* -------------------------------------------------------------------- */ if( (CSLCount(papszTokens) != 4 && CSLCount(papszTokens) != 6) || !EQUAL(papszTokens[0],"DROP") || !EQUAL(papszTokens[1],"INDEX") || !EQUAL(papszTokens[2],"ON") || (CSLCount(papszTokens) == 6 && !EQUAL(papszTokens[4],"USING")) ) { CSLDestroy( papszTokens ); CPLError( CE_Failure, CPLE_AppDefined, "Syntax error in DROP INDEX command.\n" "Was '%s'\n" "Should be of form 'DROP INDEX ON <table> [USING <field>]'", pszSQLCommand ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Find the named layer. */ /* -------------------------------------------------------------------- */ int i; OGRLayer *poLayer=NULL; { CPLMutexHolderD( &m_hMutex ); for( i = 0; i < GetLayerCount(); i++ ) { poLayer = GetLayer(i); if( EQUAL(poLayer->GetLayerDefn()->GetName(),papszTokens[3]) ) break; } if( i >= GetLayerCount() ) { CPLError( CE_Failure, CPLE_AppDefined, "CREATE INDEX ON failed, no such layer as `%s'.", papszTokens[3] ); CSLDestroy( papszTokens ); return OGRERR_FAILURE; } } /* -------------------------------------------------------------------- */ /* Does this layer even support attribute indexes? */ /* -------------------------------------------------------------------- */ if( poLayer->GetIndex() == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Indexes not supported by this driver." ); CSLDestroy( papszTokens ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* If we weren't given a field name, drop all indexes. */ /* -------------------------------------------------------------------- */ OGRErr eErr; if( CSLCount(papszTokens) == 4 ) { for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ ) { OGRAttrIndex *poAttrIndex; poAttrIndex = poLayer->GetIndex()->GetFieldIndex(i); if( poAttrIndex != NULL ) { eErr = poLayer->GetIndex()->DropIndex( i ); if( eErr != OGRERR_NONE ) return eErr; } } CSLDestroy(papszTokens); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Find the named field. */ /* -------------------------------------------------------------------- */ for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ ) { if( EQUAL(papszTokens[5], poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) ) break; } CSLDestroy( papszTokens ); if( i >= poLayer->GetLayerDefn()->GetFieldCount() ) { CPLError( CE_Failure, CPLE_AppDefined, "`%s' failed, field not found.", pszSQLCommand ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Attempt to drop the index. */ /* -------------------------------------------------------------------- */ eErr = poLayer->GetIndex()->DropIndex( i ); return eErr; }
GDALDataset *GRIBDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify(poOpenInfo) ) return NULL; /* -------------------------------------------------------------------- */ /* A fast "probe" on the header that is partially read in memory. */ /* -------------------------------------------------------------------- */ char *buff = NULL; uInt4 buffLen = 0; sInt4 sect0[SECT0LEN_WORD]; uInt4 gribLen; int version; // grib is not thread safe, make sure not to cause problems // for other thread safe formats static void *mutex = 0; CPLMutexHolderD(&mutex); MemoryDataSource mds (poOpenInfo->pabyHeader, poOpenInfo->nHeaderBytes); if (ReadSECT0 (mds, &buff, &buffLen, -1, sect0, &gribLen, &version) < 0) { free (buff); char * errMsg = errSprintf(NULL); if( errMsg != NULL && strstr(errMsg,"Ran out of file") == NULL ) CPLDebug( "GRIB", "%s", errMsg ); free(errMsg); return NULL; } free(buff); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The GRIB driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GRIBDataset *poDS; poDS = new GRIBDataset(); poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r" ); /* Check the return values */ if (!poDS->fp) { // we have no FP, so we don't have anywhere to read from char * errMsg = errSprintf(NULL); if( errMsg != NULL ) CPLDebug( "GRIB", "%s", errMsg ); free(errMsg); CPLError( CE_Failure, CPLE_OpenFailed, "Error (%d) opening file %s", errno, poOpenInfo->pszFilename); delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Read the header. */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Make an inventory of the GRIB file. */ /* The inventory does not contain all the information needed for */ /* creating the RasterBands (especially the x and y size), therefore */ /* the first GRIB band is also read for some additional metadata. */ /* The band-data that is read is stored into the first RasterBand, */ /* simply so that the same portion of the file is not read twice. */ /* -------------------------------------------------------------------- */ VSIFSeekL( poDS->fp, 0, SEEK_SET ); FileDataSource grib_fp (poDS->fp); inventoryType *Inv = NULL; /* Contains an GRIB2 message inventory of the file */ uInt4 LenInv = 0; /* size of Inv (also # of GRIB2 messages) */ int msgNum =0; /* The messageNumber during the inventory. */ if (GRIB2Inventory (grib_fp, &Inv, &LenInv, 0, &msgNum) <= 0 ) { char * errMsg = errSprintf(NULL); if( errMsg != NULL ) CPLDebug( "GRIB", "%s", errMsg ); free(errMsg); CPLError( CE_Failure, CPLE_OpenFailed, "%s is a grib file, but no raster dataset was successfully identified.", poOpenInfo->pszFilename ); delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band objects. */ /* -------------------------------------------------------------------- */ for (uInt4 i = 0; i < LenInv; ++i) { uInt4 bandNr = i+1; if (bandNr == 1) { // important: set DataSet extents before creating first RasterBand in it double * data = NULL; grib_MetaData* metaData; GRIBRasterBand::ReadGribData(grib_fp, 0, Inv[i].subgNum, &data, &metaData); if (data == 0 || metaData->gds.Nx < 1 || metaData->gds.Ny < 1) { CPLError( CE_Failure, CPLE_OpenFailed, "%s is a grib file, but no raster dataset was successfully identified.", poOpenInfo->pszFilename ); delete poDS; return NULL; } poDS->SetGribMetaData(metaData); // set the DataSet's x,y size, georeference and projection from the first GRIB band GRIBRasterBand* gribBand = new GRIBRasterBand( poDS, bandNr, Inv+i); if( Inv->GribVersion == 2 ) gribBand->FindPDSTemplate(); gribBand->m_Grib_Data = data; gribBand->m_Grib_MetaData = metaData; poDS->SetBand( bandNr, gribBand); } else poDS->SetBand( bandNr, new GRIBRasterBand( poDS, bandNr, Inv+i )); GRIB2InventoryFree (Inv + i); } free (Inv); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); return( poDS ); }
int NASReader::SetupParser() { { CPLMutexHolderD(&hMutex); static int bXercesInitialized = -1; if( bXercesInitialized < 0) { try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { CPLError( CE_Warning, CPLE_AppDefined, "Exception initializing Xerces based GML reader.\n%s", tr_strdup(toCatch.getMessage()) ); bXercesInitialized = FALSE; return FALSE; } bXercesInitialized = TRUE; } if( !bXercesInitialized ) return FALSE; } // Cleanup any old parser. if( m_poSAXReader != NULL ) CleanupParser(); // Create and initialize parser. XMLCh* xmlUriValid = NULL; XMLCh* xmlUriNS = NULL; try{ m_poSAXReader = XMLReaderFactory::createXMLReader(); m_poNASHandler = new NASHandler( this ); m_poSAXReader->setContentHandler( m_poNASHandler ); m_poSAXReader->setErrorHandler( m_poNASHandler ); m_poSAXReader->setLexicalHandler( m_poNASHandler ); m_poSAXReader->setEntityResolver( m_poNASHandler ); m_poSAXReader->setDTDHandler( m_poNASHandler ); xmlUriValid = XMLString::transcode("http://xml.org/sax/features/validation"); xmlUriNS = XMLString::transcode("http://xml.org/sax/features/namespaces"); #if (OGR_GML_VALIDATION) m_poSAXReader->setFeature( xmlUriValid, true); m_poSAXReader->setFeature( xmlUriNS, true); m_poSAXReader->setFeature( XMLUni::fgSAX2CoreNameSpaces, true ); m_poSAXReader->setFeature( XMLUni::fgXercesSchema, true ); // m_poSAXReader->setDoSchema(true); // m_poSAXReader->setValidationSchemaFullChecking(true); #else m_poSAXReader->setFeature( XMLUni::fgSAX2CoreValidation, false); #if XERCES_VERSION_MAJOR >= 3 m_poSAXReader->setFeature( XMLUni::fgXercesSchema, false); #else m_poSAXReader->setFeature( XMLUni::fgSAX2CoreNameSpaces, false); #endif #endif XMLString::release( &xmlUriValid ); XMLString::release( &xmlUriNS ); } catch (...) { XMLString::release( &xmlUriValid ); XMLString::release( &xmlUriNS ); CPLError( CE_Warning, CPLE_AppDefined, "Exception initializing Xerces based GML reader.\n" ); return FALSE; } m_bReadStarted = FALSE; // Push an empty state. PushState( new GMLReadState() ); return TRUE; }