int VSISubFileFilesystemHandler::DecomposePath( const char *pszPath, CPLString &osFilename, vsi_l_offset &nSubFileOffset, vsi_l_offset &nSubFileSize ) { int i; osFilename = ""; nSubFileOffset = 0; nSubFileSize = 0; if( strncmp(pszPath,"/vsisubfile/",12) != 0 ) return FALSE; nSubFileOffset = CPLScanUIntBig(pszPath+12, strlen(pszPath + 12)); for( i = 12; pszPath[i] != '\0'; i++ ) { if( pszPath[i] == '_' && nSubFileSize == 0 ) nSubFileSize = CPLScanUIntBig(pszPath + i + 1, strlen(pszPath + i + 1)); else if( pszPath[i] == ',' ) { osFilename = pszPath + i + 1; return TRUE; } else if( pszPath[i] == '/' ) { // missing comma! return FALSE; } } return FALSE; }
GIntBig CPL_STDCALL GDALGetCacheMax64() { if( !bCacheMaxInitialized ) { { INITIALIZE_LOCK; } const char* pszCacheMax = CPLGetConfigOption("GDAL_CACHEMAX",NULL); bCacheMaxInitialized = TRUE; if( pszCacheMax != NULL ) { GIntBig nNewCacheMax = (GIntBig)CPLScanUIntBig(pszCacheMax, strlen(pszCacheMax)); if( nNewCacheMax < 100000 ) { if (nNewCacheMax < 0) { CPLError(CE_Failure, CPLE_NotSupported, "Invalid value for GDAL_CACHEMAX. Using default value."); return nCacheMax; } nNewCacheMax *= 1024 * 1024; } nCacheMax = nNewCacheMax; } } return nCacheMax; }
int VSISubFileFilesystemHandler::DecomposePath( const char *pszPath, CPLString &osFilename, vsi_l_offset &nSubFileOffset, vsi_l_offset &nSubFileSize ) { if( !STARTS_WITH(pszPath, "/vsisubfile/") ) return FALSE; osFilename = ""; nSubFileOffset = 0; nSubFileSize = 0; nSubFileOffset = CPLScanUIntBig(pszPath+12, static_cast<int>(strlen(pszPath + 12))); for( int i = 12; pszPath[i] != '\0'; i++ ) { if( pszPath[i] == '_' && nSubFileSize == 0 ) { // -1 is sometimes passed to mean that we don't know the file size // for example when creating a JPEG2000 datastream in a NITF file // Transform it into 0 for correct behaviour of Read(), Write() and // Eof(). if( pszPath[i + 1] == '-' ) nSubFileSize = 0; else nSubFileSize = CPLScanUIntBig(pszPath + i + 1, static_cast<int>(strlen(pszPath + i + 1))); } else if( pszPath[i] == ',' ) { osFilename = pszPath + i + 1; return TRUE; } else if( pszPath[i] == '/' ) { // Missing comma! return FALSE; } } return FALSE; }
VSICachedFile::VSICachedFile( VSIVirtualHandle *poBaseHandle ) { poBase = poBaseHandle; nCacheUsed = 0; nCacheMax = CPLScanUIntBig( CPLGetConfigOption( "VSI_CACHE_SIZE", "25000000" ), 40 ); poLRUStart = NULL; poLRUEnd = NULL; poBase->Seek( 0, SEEK_END ); nFileSize = poBase->Tell(); nOffset = 0; }
VSICachedFile::VSICachedFile( VSIVirtualHandle *poBaseHandle, size_t nChunkSize, size_t nCacheSize ) { poBase = poBaseHandle; this->nChunkSize = nChunkSize; nCacheUsed = 0; if ( nCacheSize == 0 ) nCacheMax = CPLScanUIntBig( CPLGetConfigOption( "VSI_CACHE_SIZE", "25000000" ), 40 ); else nCacheMax = nCacheSize; poLRUStart = NULL; poLRUEnd = NULL; poBase->Seek( 0, SEEK_END ); nFileSize = poBase->Tell(); nOffset = 0; bEOF = FALSE; }
GDALDataset *PAuxDataset::Open( GDALOpenInfo * poOpenInfo ) { if( poOpenInfo->nHeaderBytes < 1 ) return NULL; /* -------------------------------------------------------------------- */ /* If this is an .aux file, fetch out and form the name of the */ /* file it references. */ /* -------------------------------------------------------------------- */ CPLString osTarget = poOpenInfo->pszFilename; if( EQUAL(CPLGetExtension( poOpenInfo->pszFilename ),"aux") && STARTS_WITH_CI((const char *) poOpenInfo->pabyHeader, "AuxilaryTarget: ")) { char szAuxTarget[1024]; const char *pszSrc = reinterpret_cast<const char *>( poOpenInfo->pabyHeader+16 ); int i = 0; for( ; pszSrc[i] != 10 && pszSrc[i] != 13 && pszSrc[i] != '\0' && i < static_cast<int>( sizeof(szAuxTarget) ) - 1; i++ ) { szAuxTarget[i] = pszSrc[i]; } szAuxTarget[i] = '\0'; char *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); osTarget = CPLFormFilename(pszPath, szAuxTarget, NULL); CPLFree(pszPath); } /* -------------------------------------------------------------------- */ /* Now we need to tear apart the filename to form a .aux */ /* filename. */ /* -------------------------------------------------------------------- */ CPLString osAuxFilename = CPLResetExtension(osTarget,"aux"); /* -------------------------------------------------------------------- */ /* Do we have a .aux file? */ /* -------------------------------------------------------------------- */ char** papszSiblingFiles = poOpenInfo->GetSiblingFiles(); if( papszSiblingFiles != NULL && CSLFindString( papszSiblingFiles, CPLGetFilename(osAuxFilename) ) == -1 ) { return NULL; } VSILFILE *fp = VSIFOpenL( osAuxFilename, "r" ); if( fp == NULL ) { osAuxFilename = CPLResetExtension(osTarget,"AUX"); fp = VSIFOpenL( osAuxFilename, "r" ); } if( fp == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Is this file a PCI .aux file? Check the first line for the */ /* telltale AuxilaryTarget keyword. */ /* */ /* At this point we should be verifying that it refers to our */ /* binary file, but that is a pretty involved test. */ /* -------------------------------------------------------------------- */ const char *pszLine = CPLReadLineL( fp ); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); if( pszLine == NULL || (!STARTS_WITH_CI(pszLine, "AuxilaryTarget") && !STARTS_WITH_CI(pszLine, "AuxiliaryTarget")) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ PAuxDataset *poDS = new PAuxDataset(); /* -------------------------------------------------------------------- */ /* Load the .aux file into a string list suitable to be */ /* searched with CSLFetchNameValue(). */ /* -------------------------------------------------------------------- */ poDS->papszAuxLines = CSLLoad( osAuxFilename ); poDS->pszAuxFilename = CPLStrdup(osAuxFilename); /* -------------------------------------------------------------------- */ /* Find the RawDefinition line to establish overall parameters. */ /* -------------------------------------------------------------------- */ pszLine = CSLFetchNameValue(poDS->papszAuxLines, "RawDefinition"); // It seems PCI now writes out .aux files without RawDefinition in // some cases. See bug 947. if( pszLine == NULL ) { delete poDS; return NULL; } char **papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 3 ) { CPLError( CE_Failure, CPLE_AppDefined, "RawDefinition missing or corrupt in %s.", poOpenInfo->pszFilename ); delete poDS; CSLDestroy( papszTokens ); return NULL; } poDS->nRasterXSize = atoi(papszTokens[0]); poDS->nRasterYSize = atoi(papszTokens[1]); poDS->nBands = atoi(papszTokens[2]); poDS->eAccess = poOpenInfo->eAccess; CSLDestroy( papszTokens ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(poDS->nBands, FALSE)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( osTarget, "rb+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or read-only, check permissions.", osTarget.c_str() ); delete poDS; return NULL; } } else { poDS->fpImage = VSIFOpenL( osTarget, "rb" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or unreadable.", osTarget.c_str() ); delete poDS; return NULL; } } /* -------------------------------------------------------------------- */ /* Collect raw definitions of each channel and create */ /* corresponding bands. */ /* -------------------------------------------------------------------- */ int iBand = 0; for( int i = 0; i < poDS->nBands; i++ ) { char szDefnName[32]; snprintf( szDefnName, sizeof(szDefnName), "ChanDefinition-%d", i+1 ); pszLine = CSLFetchNameValue(poDS->papszAuxLines, szDefnName); if (pszLine == NULL) { continue; } papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 4 ) { // Skip the band with broken description CSLDestroy( papszTokens ); continue; } GDALDataType eType; if( EQUAL(papszTokens[0],"16U") ) eType = GDT_UInt16; else if( EQUAL(papszTokens[0],"16S") ) eType = GDT_Int16; else if( EQUAL(papszTokens[0],"32R") ) eType = GDT_Float32; else eType = GDT_Byte; int bNative = TRUE; if( CSLCount(papszTokens) > 4 ) { #ifdef CPL_LSB bNative = EQUAL(papszTokens[4],"Swapped"); #else bNative = EQUAL(papszTokens[4],"Unswapped"); #endif } const vsi_l_offset nBandOffset = CPLScanUIntBig(papszTokens[1], static_cast<int>(strlen(papszTokens[1]))); const int nPixelOffset = atoi(papszTokens[2]); const int nLineOffset = atoi(papszTokens[3]); if (nPixelOffset <= 0 || nLineOffset <= 0) { // Skip the band with broken offsets CSLDestroy( papszTokens ); continue; } poDS->SetBand( iBand+1, new PAuxRasterBand( poDS, iBand+1, poDS->fpImage, nBandOffset, nPixelOffset, nLineOffset, eType, bNative ) ); iBand++; CSLDestroy( papszTokens ); } poDS->nBands = iBand; /* -------------------------------------------------------------------- */ /* Get the projection. */ /* -------------------------------------------------------------------- */ const char *pszMapUnits = CSLFetchNameValue( poDS->papszAuxLines, "MapUnits" ); const char *pszProjParms = CSLFetchNameValue( poDS->papszAuxLines, "ProjParms" ); if( pszMapUnits != NULL ) poDS->pszProjection = poDS->PCI2WKT( pszMapUnits, pszProjParms ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osTarget ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osTarget ); poDS->ScanForGCPs(); poDS->bAuxUpdated = FALSE; return( poDS ); }
VSIVirtualHandle * VSISparseFileFilesystemHandler::Open( const char *pszFilename, const char *pszAccess ) { CPLAssert( EQUALN(pszFilename,"/vsisparse/", 11) ); if( !EQUAL(pszAccess,"r") && !EQUAL(pszAccess,"rb") ) { errno = EACCES; return NULL; } /* Arbitrary number */ if( GetRecCounter() == 32 ) return NULL; CPLString osSparseFilePath = pszFilename + 11; /* -------------------------------------------------------------------- */ /* Does this file even exist? */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osSparseFilePath, "r" ); if( fp == NULL ) return NULL; VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Read the XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXMLRoot = CPLParseXMLFile( osSparseFilePath ); if( psXMLRoot == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Setup the file handle on this file. */ /* -------------------------------------------------------------------- */ VSISparseFileHandle *poHandle = new VSISparseFileHandle(this); /* -------------------------------------------------------------------- */ /* Translate the desired fields out of the XML tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRegion; for( psRegion = psXMLRoot->psChild; psRegion != NULL; psRegion = psRegion->psNext ) { if( psRegion->eType != CXT_Element ) continue; if( !EQUAL(psRegion->pszValue,"SubfileRegion") && !EQUAL(psRegion->pszValue,"ConstantRegion") ) continue; SFRegion oRegion; oRegion.osFilename = CPLGetXMLValue( psRegion, "Filename", "" ); if( atoi(CPLGetXMLValue( psRegion, "Filename.relative", "0" )) != 0 ) { CPLString osSFPath = CPLGetPath(osSparseFilePath); oRegion.osFilename = CPLFormFilename( osSFPath, oRegion.osFilename, NULL ); } oRegion.nDstOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"DestinationOffset","0" ), 32 ); oRegion.nSrcOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"SourceOffset","0" ), 32); oRegion.nLength = CPLScanUIntBig( CPLGetXMLValue(psRegion,"RegionLength","0" ), 32); oRegion.byValue = (GByte) atoi(CPLGetXMLValue(psRegion,"Value","0" )); poHandle->aoRegions.push_back( oRegion ); } /* -------------------------------------------------------------------- */ /* Get sparse file length, use maximum bound of regions if not */ /* explicit in file. */ /* -------------------------------------------------------------------- */ poHandle->nOverallLength = CPLScanUIntBig( CPLGetXMLValue(psXMLRoot,"Length","0" ), 32); if( poHandle->nOverallLength == 0 ) { for( unsigned int i = 0; i < poHandle->aoRegions.size(); i++ ) { poHandle->nOverallLength = MAX(poHandle->nOverallLength, poHandle->aoRegions[i].nDstOffset + poHandle->aoRegions[i].nLength); } } CPLDestroyXMLNode( psXMLRoot ); return poHandle; }
GDALDataset *MEMDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Do we have the special filename signature for MEM format */ /* description strings? */ /* -------------------------------------------------------------------- */ if( !STARTS_WITH_CI(poOpenInfo->pszFilename, "MEM:::") || poOpenInfo->fpL != NULL ) return NULL; char **papszOptions = CSLTokenizeStringComplex(poOpenInfo->pszFilename+6, ",", TRUE, FALSE ); /* -------------------------------------------------------------------- */ /* Verify we have all required fields */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue( papszOptions, "PIXELS" ) == NULL || CSLFetchNameValue( papszOptions, "LINES" ) == NULL || CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing required field (one of PIXELS, LINES or DATAPOINTER). " "Unable to access in-memory array." ); CSLDestroy( papszOptions ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the new MEMDataset object. */ /* -------------------------------------------------------------------- */ MEMDataset *poDS = new MEMDataset(); poDS->nRasterXSize = atoi(CSLFetchNameValue(papszOptions,"PIXELS")); poDS->nRasterYSize = atoi(CSLFetchNameValue(papszOptions,"LINES")); poDS->eAccess = GA_Update; /* -------------------------------------------------------------------- */ /* Extract other information. */ /* -------------------------------------------------------------------- */ const char *pszOption = CSLFetchNameValue(papszOptions,"BANDS"); int nBands = 1; if( pszOption != NULL ) { nBands = atoi(pszOption); } if( !GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBands, TRUE)) { CSLDestroy( papszOptions ); delete poDS; return NULL; } pszOption = CSLFetchNameValue(papszOptions,"DATATYPE"); GDALDataType eType = GDT_Byte; if( pszOption != NULL ) { if( atoi(pszOption) > 0 && atoi(pszOption) < GDT_TypeCount ) eType = static_cast<GDALDataType>( atoi(pszOption) ); else { eType = GDT_Unknown; for( int iType = 0; iType < GDT_TypeCount; iType++ ) { if( EQUAL(GDALGetDataTypeName((GDALDataType) iType), pszOption) ) { eType = static_cast<GDALDataType>( iType ); break; } } if( eType == GDT_Unknown ) { CPLError( CE_Failure, CPLE_AppDefined, "DATATYPE=%s not recognised.", pszOption ); CSLDestroy( papszOptions ); delete poDS; return NULL; } } } pszOption = CSLFetchNameValue(papszOptions, "PIXELOFFSET"); GSpacing nPixelOffset; if( pszOption == NULL ) nPixelOffset = GDALGetDataTypeSizeBytes(eType); else nPixelOffset = CPLScanUIntBig(pszOption, static_cast<int>(strlen(pszOption))); pszOption = CSLFetchNameValue(papszOptions, "LINEOFFSET"); GSpacing nLineOffset = 0; if( pszOption == NULL ) nLineOffset = poDS->nRasterXSize * static_cast<size_t>( nPixelOffset ); else nLineOffset = CPLScanUIntBig(pszOption, static_cast<int>(strlen(pszOption))); pszOption = CSLFetchNameValue(papszOptions, "BANDOFFSET"); GSpacing nBandOffset = 0; if( pszOption == NULL ) nBandOffset = nLineOffset * static_cast<size_t>( poDS->nRasterYSize ); else nBandOffset = CPLScanUIntBig(pszOption, static_cast<int>(strlen(pszOption))); const char *pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER"); GByte *pabyData = reinterpret_cast<GByte *>( CPLScanPointer( pszDataPointer, static_cast<int>(strlen(pszDataPointer)) ) ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBands; iBand++ ) { poDS->SetBand( iBand+1, new MEMRasterBand( poDS, iBand+1, pabyData + iBand * nBandOffset, eType, nPixelOffset, nLineOffset, FALSE ) ); } /* -------------------------------------------------------------------- */ /* Try to return a regular handle on the file. */ /* -------------------------------------------------------------------- */ CSLDestroy( papszOptions ); return poDS; }
int VSICurlStreamingHandle::ReceivedBytesHeader(GByte *buffer, size_t count, size_t nmemb) { size_t nSize = count * nmemb; if (ENABLE_DEBUG) CPLDebug("VSICURL", "Receiving %d bytes for header...", (int)nSize); /* Reset buffer if we have followed link after a redirect */ if (nSize >=9 && (nHTTPCode == 301 || nHTTPCode == 302) && (EQUALN((const char*)buffer, "HTTP/1.0 ", 9) || EQUALN((const char*)buffer, "HTTP/1.1 ", 9))) { nHeaderSize = 0; nHTTPCode = 0; } if (nHeaderSize < HEADER_SIZE) { size_t nSz = MIN(nSize, HEADER_SIZE - nHeaderSize); memcpy(pabyHeaderData + nHeaderSize, buffer, nSz); pabyHeaderData[nHeaderSize + nSz] = '\0'; nHeaderSize += nSz; //CPLDebug("VSICURL", "Header : %s", pabyHeaderData); AcquireMutex(); if (eExists == EXIST_UNKNOWN && nHTTPCode == 0 && strchr((const char*)pabyHeaderData, '\n') != NULL && (EQUALN((const char*)pabyHeaderData, "HTTP/1.0 ", 9) || EQUALN((const char*)pabyHeaderData, "HTTP/1.1 ", 9))) { nHTTPCode = atoi((const char*)pabyHeaderData + 9); if (ENABLE_DEBUG) CPLDebug("VSICURL", "HTTP code = %d", nHTTPCode); /* If moved permanently/temporarily, go on */ if( !(nHTTPCode == 301 || nHTTPCode == 302) ) { poFS->AcquireMutex(); CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL); cachedFileProp->eExists = eExists = (nHTTPCode == 200) ? EXIST_YES : EXIST_NO; poFS->ReleaseMutex(); } } if ( !(nHTTPCode == 301 || nHTTPCode == 302) && !bHastComputedFileSize) { /* Caution: when gzip compression is enabled, the content-length is the compressed */ /* size, which we are not interested in, so we must not take it into account. */ const char* pszContentLength = strstr((const char*)pabyHeaderData, "Content-Length: "); const char* pszEndOfLine = pszContentLength ? strchr(pszContentLength, '\n') : NULL; if( bCanTrustCandidateFileSize && pszEndOfLine != NULL ) { const char* pszVal = pszContentLength + strlen("Content-Length: "); bHasCandidateFileSize = TRUE; nCandidateFileSize = CPLScanUIntBig(pszVal, pszEndOfLine - pszVal); if (ENABLE_DEBUG) CPLDebug("VSICURL", "Has found candidate file size = " CPL_FRMT_GUIB, nCandidateFileSize); } const char* pszContentEncoding = strstr((const char*)pabyHeaderData, "Content-Encoding: "); pszEndOfLine = pszContentEncoding ? strchr(pszContentEncoding, '\n') : NULL; if( bHasCandidateFileSize && pszEndOfLine != NULL ) { const char* pszVal = pszContentEncoding + strlen("Content-Encoding: "); if( strncmp(pszVal, "gzip", 4) == 0 ) { if (ENABLE_DEBUG) CPLDebug("VSICURL", "GZip compression enabled --> cannot trust candidate file size"); bCanTrustCandidateFileSize = FALSE; } } } ReleaseMutex(); } return nmemb; }
vsi_l_offset VSICurlStreamingHandle::GetFileSize() { WriteFuncStruct sWriteFuncData; WriteFuncStruct sWriteFuncHeaderData; AcquireMutex(); if (bHastComputedFileSize) { vsi_l_offset nRet = fileSize; ReleaseMutex(); return nRet; } ReleaseMutex(); #if LIBCURL_VERSION_NUM < 0x070B00 /* Curl 7.10.X doesn't manage to unset the CURLOPT_RANGE that would have been */ /* previously set, so we have to reinit the connection handle */ if (hCurlHandle) { curl_easy_cleanup(hCurlHandle); hCurlHandle = curl_easy_init(); } #endif CURL* hLocalHandle = curl_easy_init(); VSICurlSetOptions(hLocalHandle, pszURL); VSICURLStreamingInitWriteFuncStruct(&sWriteFuncHeaderData); /* HACK for mbtiles driver: proper fix would be to auto-detect servers that don't accept HEAD */ /* http://a.tiles.mapbox.com/v3/ doesn't accept HEAD, so let's start a GET */ /* and interrupt is as soon as the header is found */ if (strstr(pszURL, ".tiles.mapbox.com/") != NULL) { curl_easy_setopt(hLocalHandle, CURLOPT_HEADERDATA, &sWriteFuncHeaderData); curl_easy_setopt(hLocalHandle, CURLOPT_HEADERFUNCTION, VSICurlStreamingHandleWriteFuncForHeader); sWriteFuncHeaderData.bIsHTTP = strncmp(pszURL, "http", 4) == 0; sWriteFuncHeaderData.bDownloadHeaderOnly = TRUE; } else { curl_easy_setopt(hLocalHandle, CURLOPT_NOBODY, 1); curl_easy_setopt(hLocalHandle, CURLOPT_HTTPGET, 0); curl_easy_setopt(hLocalHandle, CURLOPT_HEADER, 1); } /* We need that otherwise OSGEO4W's libcurl issue a dummy range request */ /* when doing a HEAD when recycling connections */ curl_easy_setopt(hLocalHandle, CURLOPT_RANGE, NULL); /* Bug with older curl versions (<=7.16.4) and FTP. See http://curl.haxx.se/mail/lib-2007-08/0312.html */ VSICURLStreamingInitWriteFuncStruct(&sWriteFuncData); curl_easy_setopt(hLocalHandle, CURLOPT_WRITEDATA, &sWriteFuncData); curl_easy_setopt(hLocalHandle, CURLOPT_WRITEFUNCTION, VSICurlStreamingHandleWriteFuncForHeader); char szCurlErrBuf[CURL_ERROR_SIZE+1]; szCurlErrBuf[0] = '\0'; curl_easy_setopt(hLocalHandle, CURLOPT_ERRORBUFFER, szCurlErrBuf ); double dfSize = 0; curl_easy_perform(hLocalHandle); AcquireMutex(); eExists = EXIST_UNKNOWN; bHastComputedFileSize = TRUE; if (strncmp(pszURL, "ftp", 3) == 0) { if (sWriteFuncData.pBuffer != NULL && strncmp(sWriteFuncData.pBuffer, "Content-Length: ", strlen( "Content-Length: ")) == 0) { const char* pszBuffer = sWriteFuncData.pBuffer + strlen("Content-Length: "); eExists = EXIST_YES; fileSize = CPLScanUIntBig(pszBuffer, sWriteFuncData.nSize - strlen("Content-Length: ")); if (ENABLE_DEBUG) CPLDebug("VSICURL", "GetFileSize(%s)=" CPL_FRMT_GUIB, pszURL, fileSize); } } if (eExists != EXIST_YES) { CURLcode code = curl_easy_getinfo(hLocalHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dfSize ); if (code == 0) { eExists = EXIST_YES; if (dfSize < 0) fileSize = 0; else fileSize = (GUIntBig)dfSize; } else { eExists = EXIST_NO; fileSize = 0; CPLError(CE_Failure, CPLE_AppDefined, "VSICurlStreamingHandle::GetFileSize failed"); } long response_code = 0; curl_easy_getinfo(hLocalHandle, CURLINFO_HTTP_CODE, &response_code); if (response_code != 200) { eExists = EXIST_NO; fileSize = 0; } /* Try to guess if this is a directory. Generally if this is a directory, */ /* curl will retry with an URL with slash added */ char *pszEffectiveURL = NULL; curl_easy_getinfo(hLocalHandle, CURLINFO_EFFECTIVE_URL, &pszEffectiveURL); if (pszEffectiveURL != NULL && strncmp(pszURL, pszEffectiveURL, strlen(pszURL)) == 0 && pszEffectiveURL[strlen(pszURL)] == '/') { eExists = EXIST_YES; fileSize = 0; bIsDirectory = TRUE; } if (ENABLE_DEBUG) CPLDebug("VSICURL", "GetFileSize(%s)=" CPL_FRMT_GUIB " response_code=%d", pszURL, fileSize, (int)response_code); } CPLFree(sWriteFuncData.pBuffer); CPLFree(sWriteFuncHeaderData.pBuffer); poFS->AcquireMutex(); CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL); cachedFileProp->bHastComputedFileSize = TRUE; #ifdef notdef cachedFileProp->nChecksumOfFirst1024Bytes = nRecomputedChecksumOfFirst1024Bytes; #endif cachedFileProp->fileSize = fileSize; cachedFileProp->eExists = eExists; cachedFileProp->bIsDirectory = bIsDirectory; poFS->ReleaseMutex(); vsi_l_offset nRet = fileSize; ReleaseMutex(); if (hCurlHandle == NULL) hCurlHandle = hLocalHandle; else curl_easy_cleanup(hLocalHandle); return nRet; }
CPLErr VRTRawRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath ) { const CPLErr eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath ); if( eErr != CE_None ) return eErr; /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == NULL || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue, "VRTRasterBand") || !EQUAL(CPLGetXMLValue(psTree,"subClass",""), "VRTRawRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRawRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ const char *pszFilename = CPLGetXMLValue(psTree, "SourceFilename", NULL); if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in VRTRasterBand." ); return CE_Failure; } // TODO(schwehr): Should this be a bool? const int l_bRelativeToVRT = atoi(CPLGetXMLValue( psTree, "SourceFilename.relativeToVRT", "1" ) ); /* -------------------------------------------------------------------- */ /* Collect layout information. */ /* -------------------------------------------------------------------- */ int nWordDataSize = GDALGetDataTypeSizeBytes( GetRasterDataType() ); const char* pszImageOffset = CPLGetXMLValue( psTree, "ImageOffset", "0"); const vsi_l_offset nImageOffset = CPLScanUIntBig( pszImageOffset, static_cast<int>(strlen(pszImageOffset)) ); int nPixelOffset = nWordDataSize; if( CPLGetXMLValue( psTree, "PixelOffset", NULL ) != NULL ) { nPixelOffset = atoi(CPLGetXMLValue( psTree, "PixelOffset", "0") ); } if (nPixelOffset <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid value for <PixelOffset> element : %d", nPixelOffset ); return CE_Failure; } int nLineOffset = 0; if( CPLGetXMLValue( psTree, "LineOffset", NULL ) == NULL ) nLineOffset = nWordDataSize * GetXSize(); else nLineOffset = atoi(CPLGetXMLValue( psTree, "LineOffset", "0") ); const char *pszByteOrder = CPLGetXMLValue( psTree, "ByteOrder", NULL ); /* -------------------------------------------------------------------- */ /* Open the file, and setup the raw layer access to the data. */ /* -------------------------------------------------------------------- */ return SetRawLink( pszFilename, pszVRTPath, l_bRelativeToVRT, nImageOffset, nPixelOffset, nLineOffset, pszByteOrder ); }
CPLErr VRTRawRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath, void* pUniqueHandle, std::map<CPLString, GDALDataset*>& oMapSharedSources ) { const CPLErr eErr = VRTRasterBand::XMLInit( psTree, pszVRTPath, pUniqueHandle, oMapSharedSources ); if( eErr != CE_None ) return eErr; /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == nullptr || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue, "VRTRasterBand") || !EQUAL(CPLGetXMLValue(psTree,"subClass",""), "VRTRawRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRawRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ const char *pszFilename = CPLGetXMLValue(psTree, "SourceFilename", nullptr); if( pszFilename == nullptr ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in VRTRasterBand." ); return CE_Failure; } const bool l_bRelativeToVRT = CPLTestBool( CPLGetXMLValue( psTree, "SourceFilename.relativeToVRT", "1" )); /* -------------------------------------------------------------------- */ /* Collect layout information. */ /* -------------------------------------------------------------------- */ int nWordDataSize = GDALGetDataTypeSizeBytes( GetRasterDataType() ); const char* pszImageOffset = CPLGetXMLValue( psTree, "ImageOffset", "0"); const vsi_l_offset nImageOffset = CPLScanUIntBig( pszImageOffset, static_cast<int>(strlen(pszImageOffset)) ); int nPixelOffset = nWordDataSize; const char* pszPixelOffset = CPLGetXMLValue( psTree, "PixelOffset", nullptr ); if( pszPixelOffset != nullptr ) { nPixelOffset = atoi(pszPixelOffset); } if (nPixelOffset <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid value for <PixelOffset> element : %d", nPixelOffset ); return CE_Failure; } int nLineOffset = 0; const char* pszLineOffset = CPLGetXMLValue( psTree, "LineOffset", nullptr ); if( pszLineOffset == nullptr ) { if( nPixelOffset > INT_MAX / GetXSize() ) { CPLError( CE_Failure, CPLE_AppDefined, "Int overflow"); return CE_Failure; } nLineOffset = nPixelOffset * GetXSize(); } else nLineOffset = atoi(pszLineOffset); const char *pszByteOrder = CPLGetXMLValue( psTree, "ByteOrder", nullptr ); /* -------------------------------------------------------------------- */ /* Open the file, and setup the raw layer access to the data. */ /* -------------------------------------------------------------------- */ return SetRawLink( pszFilename, pszVRTPath, l_bRelativeToVRT, nImageOffset, nPixelOffset, nLineOffset, pszByteOrder ); }