Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OGR 4 : * Purpose: OGRNASDriver implementation 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_conv.h" 14 : #include "cpl_multiproc.h" 15 : #include "nasreaderp.h" 16 : #include "ogr_nas.h" 17 : 18 : /************************************************************************/ 19 : /* OGRNASDriverIdentify() */ 20 : /************************************************************************/ 21 : 22 48909 : static int OGRNASDriverIdentify(GDALOpenInfo *poOpenInfo) 23 : 24 : { 25 48909 : if (poOpenInfo->fpL == nullptr) 26 44196 : return FALSE; 27 : 28 : /* -------------------------------------------------------------------- */ 29 : /* Check for a UTF-8 BOM and skip if found */ 30 : /* */ 31 : /* TODO: BOM is variable-length parameter and depends on encoding. */ 32 : /* Add BOM detection for other encodings. */ 33 : /* -------------------------------------------------------------------- */ 34 : 35 : // Used to skip to actual beginning of XML data 36 4713 : const char *pszPtr = reinterpret_cast<const char *>(poOpenInfo->pabyHeader); 37 : 38 : // Skip UTF-8 BOM 39 4713 : if (poOpenInfo->nHeaderBytes > 3 && 40 4619 : memcmp(poOpenInfo->pabyHeader, "\xEF\xBB\xBF", 3) == 0) 41 : { 42 8 : pszPtr += 3; 43 : } 44 : 45 : // Skip spaces 46 5031 : while (*pszPtr && std::isspace(static_cast<unsigned char>(*pszPtr))) 47 318 : ++pszPtr; 48 : 49 : /* -------------------------------------------------------------------- */ 50 : /* Here, we expect the opening chevrons of NAS tree root element */ 51 : /* -------------------------------------------------------------------- */ 52 4713 : if (pszPtr[0] != '<') 53 3966 : return FALSE; 54 : 55 747 : if (poOpenInfo->IsSingleAllowedDriver("NAS")) 56 2 : return TRUE; 57 : 58 : // TryToIngest() invalidates above pszPtr 59 745 : pszPtr = nullptr; 60 745 : CPL_IGNORE_RET_VAL(pszPtr); 61 745 : if (!poOpenInfo->TryToIngest(8192)) 62 0 : return FALSE; 63 745 : pszPtr = reinterpret_cast<const char *>(poOpenInfo->pabyHeader); 64 : 65 745 : if (strstr(pszPtr, "opengis.net/gml") == nullptr) 66 321 : return FALSE; 67 : 68 424 : char **papszIndicators = CSLTokenizeStringComplex( 69 : CPLGetConfigOption("NAS_INDICATOR", 70 : "NAS-Operationen;AAA-Fachschema;aaa.xsd;aaa-suite"), 71 : ";", 0, 0); 72 : 73 424 : bool bFound = false; 74 2096 : for (int i = 0; papszIndicators[i] && !bFound; i++) 75 : { 76 1672 : bFound = strstr(pszPtr, papszIndicators[i]) != nullptr; 77 : } 78 : 79 424 : CSLDestroy(papszIndicators); 80 : 81 : // Require NAS_GFS_TEMPLATE to be defined 82 424 : if (bFound && !CPLGetConfigOption("NAS_GFS_TEMPLATE", nullptr)) 83 : { 84 0 : CPLDebug("NAS", 85 : "This file could be recognized by the NAS driver. " 86 : "If this is desired, you need to define the NAS_GFS_TEMPLATE " 87 : "configuration option."); 88 0 : return FALSE; 89 : } 90 : 91 424 : return bFound; 92 : } 93 : 94 : /************************************************************************/ 95 : /* Open() */ 96 : /************************************************************************/ 97 : 98 5 : static GDALDataset *OGRNASDriverOpen(GDALOpenInfo *poOpenInfo) 99 : 100 : { 101 5 : if (poOpenInfo->eAccess == GA_Update || !OGRNASDriverIdentify(poOpenInfo)) 102 0 : return nullptr; 103 : 104 5 : VSIFCloseL(poOpenInfo->fpL); 105 5 : poOpenInfo->fpL = nullptr; 106 : 107 5 : OGRNASDataSource *poDS = new OGRNASDataSource(); 108 : 109 5 : if (!poDS->Open(poOpenInfo->pszFilename)) 110 : { 111 1 : delete poDS; 112 1 : return nullptr; 113 : } 114 : 115 4 : return poDS; 116 : } 117 : 118 : /************************************************************************/ 119 : /* RegisterOGRNAS() */ 120 : /************************************************************************/ 121 : 122 1682 : void RegisterOGRNAS() 123 : 124 : { 125 1682 : if (GDALGetDriverByName("NAS") != nullptr) 126 301 : return; 127 : 128 1381 : GDALDriver *poDriver = new GDALDriver(); 129 : 130 1381 : poDriver->SetDescription("NAS"); 131 1381 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 132 1381 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "NAS - ALKIS"); 133 1381 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "xml"); 134 1381 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/nas.html"); 135 1381 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 136 1381 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 137 : 138 1381 : poDriver->pfnOpen = OGRNASDriverOpen; 139 1381 : poDriver->pfnIdentify = OGRNASDriverIdentify; 140 : 141 1381 : GetGDALDriverManager()->RegisterDriver(poDriver); 142 : }