OGRDataSource *OGRVRTDriver::Open( const char * pszFilename, int bUpdate ) { OGRVRTDataSource *poDS; char *pszXML = NULL; /* -------------------------------------------------------------------- */ /* Are we being passed the XML definition directly? */ /* Skip any leading spaces/blanks. */ /* -------------------------------------------------------------------- */ const char *pszTestXML = pszFilename; while( *pszTestXML != '\0' && isspace( (unsigned char)*pszTestXML ) ) pszTestXML++; if( EQUALN(pszTestXML,"<OGRVRTDataSource>",18) ) { pszXML = CPLStrdup(pszTestXML); } /* -------------------------------------------------------------------- */ /* Open file and check if it contains appropriate XML. */ /* -------------------------------------------------------------------- */ else { VSILFILE *fp; char achHeader[512]; fp = VSIFOpenL( pszFilename, "rb" ); if( fp == NULL ) return NULL; memset( achHeader, 0, sizeof(achHeader) ); VSIFReadL( achHeader, 1, sizeof(achHeader)-1, fp ); if( strstr(achHeader,"<OGRVRTDataSource") == NULL ) { VSIFCloseL( fp ); return NULL; } VSIStatBufL sStatBuf; if ( VSIStatL( pszFilename, &sStatBuf ) != 0 || sStatBuf.st_size > 1024 * 1024 ) { CPLDebug( "VRT", "Unreasonable long file, not likely really VRT" ); VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* It is the right file, now load the full XML definition. */ /* -------------------------------------------------------------------- */ int nLen = (int) sStatBuf.st_size; VSIFSeekL( fp, 0, SEEK_SET ); pszXML = (char *) VSIMalloc(nLen+1); if (pszXML == NULL) { VSIFCloseL( fp ); return NULL; } pszXML[nLen] = '\0'; if( ((int) VSIFReadL( pszXML, 1, nLen, fp )) != nLen ) { CPLFree( pszXML ); VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); } /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psTree = CPLParseXMLString( pszXML ); if( psTree == NULL ) { CPLFree( pszXML ); return NULL; } /* -------------------------------------------------------------------- */ /* XML Validation. */ /* -------------------------------------------------------------------- */ if( CSLTestBoolean(CPLGetConfigOption("GDAL_XML_VALIDATION", "YES")) ) { const char* pszXSD = CPLFindFile( "gdal", "ogrvrt.xsd" ); if( pszXSD != NULL ) { std::vector<CPLString> aosErrors; CPLPushErrorHandlerEx(OGRVRTErrorHandler, &aosErrors); int bRet = CPLValidateXML(pszXML, pszXSD, NULL); CPLPopErrorHandler(); if( !bRet ) { if( aosErrors.size() > 0 && strstr(aosErrors[0].c_str(), "missing libxml2 support") == NULL ) { for(size_t i = 0; i < aosErrors.size(); i++) { CPLError(CE_Warning, CPLE_AppDefined, "%s", aosErrors[i].c_str()); } } } CPLErrorReset(); } } CPLFree( pszXML ); /* -------------------------------------------------------------------- */ /* Create a virtual datasource configured based on this XML input. */ /* -------------------------------------------------------------------- */ poDS = new OGRVRTDataSource(); poDS->SetDriver(this); /* psTree is owned by poDS */ if( !poDS->Initialize( psTree, pszFilename, bUpdate ) ) { delete poDS; return NULL; } return poDS; }
OGRDataSource *OGRVRTDriver::Open( const char * pszFilename, int bUpdate ) { OGRVRTDataSource *poDS; char *pszXML = NULL; /* -------------------------------------------------------------------- */ /* Are we being passed the XML definition directly? */ /* Skip any leading spaces/blanks. */ /* -------------------------------------------------------------------- */ const char *pszTestXML = pszFilename; while( *pszTestXML != '\0' && isspace( (unsigned char)*pszTestXML ) ) pszTestXML++; if( EQUALN(pszTestXML,"<OGRVRTDataSource>",18) ) { pszXML = CPLStrdup(pszTestXML); } /* -------------------------------------------------------------------- */ /* Open file and check if it contains appropriate XML. */ /* -------------------------------------------------------------------- */ else { FILE *fp; char achHeader[18]; fp = VSIFOpenL( pszFilename, "rb" ); if( fp == NULL ) return NULL; if( VSIFReadL( achHeader, sizeof(achHeader), 1, fp ) != 1 ) { VSIFCloseL( fp ); return NULL; } if( !EQUALN(achHeader,"<OGRVRTDataSource>",18) ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* It is the right file, now load the full XML definition. */ /* -------------------------------------------------------------------- */ int nLen; VSIFSeekL( fp, 0, SEEK_END ); nLen = (int) VSIFTellL( fp ); VSIFSeekL( fp, 0, SEEK_SET ); pszXML = (char *) VSIMalloc(nLen+1); if (pszXML == NULL) { VSIFCloseL( fp ); return NULL; } pszXML[nLen] = '\0'; if( ((int) VSIFReadL( pszXML, 1, nLen, fp )) != nLen ) { CPLFree( pszXML ); VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); } /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psTree = CPLParseXMLString( pszXML ); CPLFree( pszXML ); if( psTree == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create a virtual datasource configured based on this XML input. */ /* -------------------------------------------------------------------- */ poDS = new OGRVRTDataSource(); if( !poDS->Initialize( psTree, pszFilename, bUpdate ) ) { CPLDestroyXMLNode( psTree ); delete poDS; return NULL; } CPLDestroyXMLNode( psTree ); return poDS; }