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 61239 : int OGRS101DriverIdentify(GDALOpenInfo *poOpenInfo) 25 : { 26 61239 : constexpr int DDR_LEADER_SIZE = 24; 27 61239 : if (poOpenInfo->nHeaderBytes < DDR_LEADER_SIZE) 28 53788 : return false; 29 7451 : const char *pachLeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader); 30 : // Per S-100 10a-4.8.2.1 The DDR Leader 31 7451 : constexpr char DIGIT_ZERO = '0'; 32 7451 : if (pachLeader[5] != '3' || // Interchange level 33 1002 : pachLeader[6] != 'L' || // Leader identifier 34 1002 : pachLeader[7] != 'E' || // In line code extension indicator 35 1002 : pachLeader[8] != '1' || // Version number 36 1002 : pachLeader[9] != ' ' || // Application indicator 37 1002 : pachLeader[10] != DIGIT_ZERO || // Field control length 38 1002 : pachLeader[11] != '9' || // Field control length (c'ted) 39 1002 : pachLeader[17] != ' ' || // Extended character set indicator 40 1002 : pachLeader[18] != '!' || // Extended character set indicator(c'ted) 41 1002 : pachLeader[19] != ' ') // Extended character set indicator(c'ted) 42 : { 43 6449 : return false; 44 : } 45 : // Test for S-101 DSID field structure 46 2004 : return strstr(pachLeader, "DSID") != nullptr && 47 1002 : strstr(pachLeader, 48 : "RCNM!RCID!ENSP!ENED!PRSP!PRED!PROF!DSNM!DSTL!DSRD!DSLG!" 49 1002 : "DSAB!DSED\\\\*DSTC") != nullptr; 50 : } 51 : 52 : /************************************************************************/ 53 : /* OGRS101DriverSetCommonMetadata() */ 54 : /************************************************************************/ 55 : 56 1863 : void OGRS101DriverSetCommonMetadata(GDALDriver *poDriver) 57 : { 58 1863 : poDriver->SetDescription(DRIVER_NAME); 59 : 60 1863 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 61 1863 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "IHO S-101 (ENC)"); 62 1863 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "000"); 63 1863 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/s101.html"); 64 1863 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 65 : 66 1863 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 67 1863 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 68 1863 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 69 : 70 1863 : 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 : " <Option name='UPDATES' type='string-select' " 79 : "description='Should update files be " 80 : "incorporated into the base data on the fly' default='APPLY'>" 81 : " <Value>APPLY</Value>" 82 : " <Value>IGNORE</Value>" 83 : " </Option>" 84 1863 : "</OpenOptionList>"); 85 : 86 1863 : poDriver->pfnIdentify = OGRS101DriverIdentify; 87 1863 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 88 1863 : } 89 : 90 : /************************************************************************/ 91 : /* DeclareDeferredOGRS101Plugin() */ 92 : /************************************************************************/ 93 : 94 : #ifdef PLUGIN_FILENAME 95 : void DeclareDeferredOGRS101Plugin() 96 : { 97 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 98 : { 99 : return; 100 : } 101 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 102 : #ifdef PLUGIN_INSTALLATION_MESSAGE 103 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 104 : PLUGIN_INSTALLATION_MESSAGE); 105 : #endif 106 : OGRS101DriverSetCommonMetadata(poDriver); 107 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 108 : } 109 : #endif