Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: S-101 driver 4 : * Purpose: Implements OGRS101Driver 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdal_frmts.h" 14 : #include "gdalplugindriverproxy.h" 15 : 16 : #include "ogrsf_frmts.h" 17 : 18 : #include "ogrs101drivercore.h" 19 : 20 : /************************************************************************/ 21 : /* OGRS101DriverIdentify() */ 22 : /************************************************************************/ 23 : 24 59931 : int OGRS101DriverIdentify(GDALOpenInfo *poOpenInfo) 25 : { 26 59931 : constexpr int DDR_LEADER_SIZE = 24; 27 59931 : if (poOpenInfo->nHeaderBytes < DDR_LEADER_SIZE) 28 52799 : return false; 29 7132 : const char *pachLeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader); 30 : // Per S-100 10a-4.8.2.1 The DDR Leader 31 7132 : constexpr char DIGIT_ZERO = '0'; 32 7132 : if (pachLeader[5] != '3' || // Interchange level 33 710 : pachLeader[6] != 'L' || // Leader identifier 34 710 : pachLeader[7] != 'E' || // In line code extension indicator 35 710 : pachLeader[8] != '1' || // Version number 36 710 : pachLeader[9] != ' ' || // Application indicator 37 710 : pachLeader[10] != DIGIT_ZERO || // Field control length 38 710 : pachLeader[11] != '9' || // Field control length (c'ted) 39 710 : pachLeader[17] != ' ' || // Extended character set indicator 40 710 : pachLeader[18] != '!' || // Extended character set indicator(c'ted) 41 710 : pachLeader[19] != ' ') // Extended character set indicator(c'ted) 42 : { 43 6422 : return false; 44 : } 45 : // Test for S-101 DSID field structure 46 1420 : return strstr(pachLeader, "DSID") != nullptr && 47 710 : strstr(pachLeader, 48 : "RCNM!RCID!ENSP!ENED!PRSP!PRED!PROF!DSNM!DSTL!DSRD!DSLG!" 49 710 : "DSAB!DSED\\\\*DSTC") != nullptr; 50 : } 51 : 52 : /************************************************************************/ 53 : /* OGRS101DriverSetCommonMetadata() */ 54 : /************************************************************************/ 55 : 56 1805 : void OGRS101DriverSetCommonMetadata(GDALDriver *poDriver) 57 : { 58 1805 : poDriver->SetDescription(DRIVER_NAME); 59 : 60 1805 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 61 1805 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "IHO S-101 (ENC)"); 62 1805 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "000"); 63 1805 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/s101.html"); 64 1805 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 65 : 66 1805 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 67 1805 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 68 1805 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 69 : 70 1805 : poDriver->SetMetadataItem( 71 : GDAL_DMD_OPENOPTIONLIST, 72 : "<OpenOptionList>" 73 : " <Option name='STRICT' type='boolean' default='YES' " 74 : "description='Whether the driver should error out as soon as a " 75 : "non-conformity with respect to the S-101 standard is detected. " 76 : "In non-strict mode, warnings will be emitted but processing will " 77 : "continue if the non-conformity is not fatal.'/>" 78 1805 : "</OpenOptionList>"); 79 : 80 1805 : poDriver->pfnIdentify = OGRS101DriverIdentify; 81 1805 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 82 1805 : } 83 : 84 : /************************************************************************/ 85 : /* DeclareDeferredOGRS101Plugin() */ 86 : /************************************************************************/ 87 : 88 : #ifdef PLUGIN_FILENAME 89 : void DeclareDeferredOGRS101Plugin() 90 : { 91 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 92 : { 93 : return; 94 : } 95 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 96 : #ifdef PLUGIN_INSTALLATION_MESSAGE 97 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 98 : PLUGIN_INSTALLATION_MESSAGE); 99 : #endif 100 : OGRS101DriverSetCommonMetadata(poDriver); 101 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 102 : } 103 : #endif