LCOV - code coverage report
Current view: top level - frmts/iso8211 - 8211dump.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 151 191 79.1 %
Date: 2026-05-29 23:25:07 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SDTS Translator
       4             :  * Purpose:  Dump 8211 file in verbose form - just a junk program.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include <stdio.h>
      15             : #include "iso8211.h"
      16             : #include "cpl_vsi.h"
      17             : #include "cpl_string.h"
      18             : 
      19         576 : static void DumpFieldAsXML(const DDFField *poField,
      20             :                            bool bEmitDDFFieldTag = true)
      21             : {
      22         576 :     const DDFFieldDefn *poDefn = poField->GetFieldDefn();
      23         576 :     const char *pszFieldName = poDefn->GetName();
      24         576 :     if (bEmitDDFFieldTag)
      25         570 :         printf("  <DDFField name=\"%s\"", pszFieldName);
      26             : 
      27         576 :     if (!poField->GetParts().empty())
      28             :     {
      29           3 :         if (bEmitDDFFieldTag)
      30           3 :             printf(">\n");
      31           9 :         for (const auto &poPart : poField->GetParts())
      32             :         {
      33           6 :             DumpFieldAsXML(poPart.get(), false);
      34             :         }
      35             :     }
      36             :     else
      37             :     {
      38         573 :         const int nRepeatCount = poField->GetRepeatCount();
      39         573 :         if (bEmitDDFFieldTag && nRepeatCount > 1)
      40         104 :             printf(" repeatCount=\"%d\"", nRepeatCount);
      41         573 :         int iOffset = 0, nLoopCount;
      42         573 :         const char *pachData = poField->GetData();
      43         573 :         int nDataSize = poField->GetDataSize();
      44        1036 :         if (bEmitDDFFieldTag && nRepeatCount == 1 &&
      45         463 :             poDefn->GetSubfieldCount() == 0)
      46             :         {
      47         140 :             printf(" value=\"0x");
      48         420 :             for (int i = 0; i < nDataSize - 1; i++)
      49         280 :                 printf("%02X", pachData[i]);
      50         140 :             printf("\">\n");
      51             :         }
      52         433 :         else if (bEmitDDFFieldTag)
      53         427 :             printf(">\n");
      54        1452 :         for (nLoopCount = 0; nLoopCount < nRepeatCount; nLoopCount++)
      55             :         {
      56        3529 :             for (const auto &poSubFieldDefn : poDefn->GetSubfields())
      57             :             {
      58             :                 int nBytesConsumed;
      59        2650 :                 const char *pszSubFieldName = poSubFieldDefn->GetName();
      60        2650 :                 printf("    <DDFSubfield name=\"%s\" ", pszSubFieldName);
      61        2650 :                 DDFDataType eType = poSubFieldDefn->GetType();
      62        2650 :                 const char *pachSubdata = pachData + iOffset;
      63        2650 :                 int nMaxBytes = nDataSize - iOffset;
      64        2650 :                 if (eType == DDFFloat)
      65           6 :                     printf("type=\"float\">%f",
      66             :                            poSubFieldDefn->ExtractFloatData(
      67             :                                pachSubdata, nMaxBytes, nullptr));
      68        2644 :                 else if (eType == DDFInt)
      69        2251 :                     printf("type=\"integer\">%d",
      70             :                            poSubFieldDefn->ExtractIntData(pachSubdata,
      71             :                                                           nMaxBytes, nullptr));
      72         393 :                 else if (eType == DDFBinaryString)
      73             :                 {
      74             :                     int nBytes, i;
      75             :                     GByte *pabyBString =
      76         270 :                         (GByte *)poSubFieldDefn->ExtractStringData(
      77             :                             pachSubdata, nMaxBytes, &nBytes);
      78             : 
      79         270 :                     printf("type=\"binary\">0x");
      80        1620 :                     for (i = 0; i < nBytes; i++)
      81        1350 :                         printf("%02X", pabyBString[i]);
      82             :                 }
      83             :                 else
      84             :                 {
      85             :                     GByte *pabyString =
      86         123 :                         (GByte *)poSubFieldDefn->ExtractStringData(
      87             :                             pachSubdata, nMaxBytes, nullptr);
      88         123 :                     int bBinary = FALSE;
      89             :                     int i;
      90         332 :                     for (i = 0; pabyString[i] != '\0'; i++)
      91             :                     {
      92         209 :                         if (pabyString[i] < 32 || pabyString[i] > 127)
      93             :                         {
      94           0 :                             bBinary = TRUE;
      95           0 :                             break;
      96             :                         }
      97             :                     }
      98         123 :                     if (bBinary)
      99             :                     {
     100           0 :                         printf("type=\"binary\">0x");
     101           0 :                         for (i = 0; pabyString[i] != '\0'; i++)
     102           0 :                             printf("%02X", pabyString[i]);
     103             :                     }
     104             :                     else
     105             :                     {
     106         123 :                         char *pszEscaped = CPLEscapeString(
     107             :                             (const char *)pabyString, -1, CPLES_XML);
     108         123 :                         printf("type=\"string\">%s", pszEscaped);
     109         123 :                         CPLFree(pszEscaped);
     110             :                     }
     111             :                 }
     112        2650 :                 printf("</DDFSubfield>\n");
     113             : 
     114        2650 :                 poSubFieldDefn->GetDataLength(pachSubdata, nMaxBytes,
     115             :                                               &nBytesConsumed);
     116             : 
     117        2650 :                 iOffset += nBytesConsumed;
     118             :             }
     119             :         }
     120             :     }
     121         576 :     if (bEmitDDFFieldTag)
     122         570 :         printf("  </DDFField>\n");
     123         576 : }
     124             : 
     125           4 : int main(int nArgc, char **papszArgv)
     126             : 
     127             : {
     128           8 :     DDFModule oModule;
     129           4 :     const char *pszFilename = nullptr;
     130           4 :     bool bFSPTHack = false;
     131           4 :     bool bXML = false;
     132           4 :     bool bAllDetails = false;
     133             : 
     134             :     /* -------------------------------------------------------------------- */
     135             :     /*      Check arguments.                                                */
     136             :     /* -------------------------------------------------------------------- */
     137          12 :     for (int iArg = 1; iArg < nArgc; iArg++)
     138             :     {
     139           8 :         if (EQUAL(papszArgv[iArg], "-fspt_repeating"))
     140             :         {
     141           0 :             bFSPTHack = true;
     142             :         }
     143           8 :         else if (EQUAL(papszArgv[iArg], "-xml"))
     144             :         {
     145           0 :             bXML = true;
     146             :         }
     147           8 :         else if (EQUAL(papszArgv[iArg], "-xml_all_details"))
     148             :         {
     149           4 :             bXML = TRUE;
     150           4 :             bAllDetails = true;
     151             :         }
     152             :         else
     153             :         {
     154           4 :             pszFilename = papszArgv[iArg];
     155             :         }
     156             :     }
     157             : 
     158           4 :     if (pszFilename == nullptr)
     159             :     {
     160           0 :         printf("Usage: 8211dump [-xml|-xml_all_details] "
     161             :                "[-fspt_repeating] filename\n");
     162           0 :         exit(1);
     163             :     }
     164             : 
     165             :     /* -------------------------------------------------------------------- */
     166             :     /*      Open file.                                                      */
     167             :     /* -------------------------------------------------------------------- */
     168           4 :     if (!oModule.Open(pszFilename))
     169           0 :         exit(1);
     170             : 
     171             :     /* -------------------------------------------------------------------- */
     172             :     /*      Apply FSPT hack if required.                                    */
     173             :     /* -------------------------------------------------------------------- */
     174           4 :     if (bFSPTHack)
     175             :     {
     176           0 :         DDFFieldDefn *poFSPT = oModule.FindFieldDefn("FSPT");
     177             : 
     178           0 :         if (poFSPT == nullptr)
     179           0 :             fprintf(stderr,
     180             :                     "unable to find FSPT field to set repeating flag.\n");
     181             :         else
     182           0 :             poFSPT->SetRepeatingFlag(TRUE);
     183             :     }
     184             : 
     185             :     /* -------------------------------------------------------------------- */
     186             :     /*      Dump header, and all records.                                   */
     187             :     /* -------------------------------------------------------------------- */
     188           4 :     if (bXML)
     189             :     {
     190           4 :         printf("<DDFModule");
     191           4 :         if (bAllDetails)
     192             :         {
     193           4 :             printf(" _interchangeLevel=\"%c\"", oModule.GetInterchangeLevel());
     194           4 :             printf(" _leaderIden=\"%c\"", oModule.GetLeaderIden());
     195           4 :             printf(" _inlineCodeExtensionIndicator=\"%c\"",
     196           4 :                    oModule.GetCodeExtensionIndicator());
     197           4 :             printf(" _versionNumber=\"%c\"", oModule.GetVersionNumber());
     198           4 :             printf(" _appIndicator=\"%c\"", oModule.GetAppIndicator());
     199           4 :             printf(" _extendedCharSet=\"%c%c%c\"",
     200           4 :                    oModule.GetExtendedCharSet()[0],
     201           4 :                    oModule.GetExtendedCharSet()[1],
     202           4 :                    oModule.GetExtendedCharSet()[2]);
     203           4 :             printf(" _fieldControlLength=\"%d\"",
     204             :                    oModule.GetFieldControlLength());
     205           4 :             printf(" _sizeFieldLength=\"%d\"", oModule.GetSizeFieldLength());
     206           4 :             printf(" _sizeFieldPos=\"%d\"", oModule.GetSizeFieldPos());
     207           4 :             printf(" _sizeFieldTag=\"%d\"", oModule.GetSizeFieldTag());
     208             :         }
     209           4 :         printf(">\n");
     210             : 
     211           4 :         int nFieldDefnCount = oModule.GetFieldCount();
     212          46 :         for (int i = 0; i < nFieldDefnCount; i++)
     213             :         {
     214          42 :             DDFFieldDefn *poFieldDefn = oModule.GetField(i);
     215          42 :             const char *pszDataStructCode = nullptr;
     216          42 :             switch (poFieldDefn->GetDataStructCode())
     217             :             {
     218           4 :                 case dsc_elementary:
     219           4 :                     pszDataStructCode = "elementary";
     220           4 :                     break;
     221             : 
     222          21 :                 case dsc_vector:
     223          21 :                     pszDataStructCode = "vector";
     224          21 :                     break;
     225             : 
     226          16 :                 case dsc_array:
     227          16 :                     pszDataStructCode = "array";
     228          16 :                     break;
     229             : 
     230           1 :                 case dsc_concatenated:
     231           1 :                     pszDataStructCode = "concatenated";
     232           1 :                     break;
     233             : 
     234           0 :                 default:
     235           0 :                     pszDataStructCode = "(unknown)";
     236           0 :                     break;
     237             :             }
     238             : 
     239          42 :             const char *pszDataTypeCode = nullptr;
     240          42 :             switch (poFieldDefn->GetDataTypeCode())
     241             :             {
     242           2 :                 case dtc_char_string:
     243           2 :                     pszDataTypeCode = "char_string";
     244           2 :                     break;
     245             : 
     246           0 :                 case dtc_implicit_point:
     247           0 :                     pszDataTypeCode = "implicit_point";
     248           0 :                     break;
     249             : 
     250           0 :                 case dtc_explicit_point:
     251           0 :                     pszDataTypeCode = "explicit_point";
     252           0 :                     break;
     253             : 
     254           0 :                 case dtc_explicit_point_scaled:
     255           0 :                     pszDataTypeCode = "explicit_point_scaled";
     256           0 :                     break;
     257             : 
     258           0 :                 case dtc_char_bit_string:
     259           0 :                     pszDataTypeCode = "char_bit_string";
     260           0 :                     break;
     261             : 
     262           6 :                 case dtc_bit_string:
     263           6 :                     pszDataTypeCode = "bit_string";
     264           6 :                     break;
     265             : 
     266          34 :                 case dtc_mixed_data_type:
     267          34 :                     pszDataTypeCode = "mixed_data_type";
     268          34 :                     break;
     269             : 
     270           0 :                 default:
     271           0 :                     pszDataTypeCode = "(unknown)";
     272           0 :                     break;
     273             :             }
     274             : 
     275          42 :             printf("<DDFFieldDefn tag=\"%s\" fieldName=\"%s\""
     276             :                    " dataStructCode=\"%s\" dataTypeCode=\"%s\"",
     277             :                    poFieldDefn->GetName(), poFieldDefn->GetDescription(),
     278             :                    pszDataStructCode, pszDataTypeCode);
     279          42 :             int nSubfieldCount = poFieldDefn->GetSubfieldCount();
     280          42 :             if (bAllDetails || nSubfieldCount == 0)
     281             :             {
     282          42 :                 printf(" arrayDescr=\"%s\"", poFieldDefn->GetArrayDescr());
     283          42 :                 printf(" formatControls=\"%s\"",
     284             :                        poFieldDefn->GetFormatControls());
     285             :             }
     286          42 :             if (bAllDetails)
     287             :             {
     288          42 :                 char *pszEscaped = CPLEscapeString(
     289          42 :                     poFieldDefn->GetEscapeSequence().c_str(), -1, CPLES_XML);
     290          42 :                 printf(" escapeSequence=\"%s\"", pszEscaped);
     291          42 :                 CPLFree(pszEscaped);
     292             :             }
     293          42 :             printf(">\n");
     294          44 :             for (const auto &poPart : poFieldDefn->GetParts())
     295             :             {
     296           6 :                 for (const auto &poSubFieldDefn : poPart->GetSubfields())
     297             :                 {
     298           4 :                     printf("  <DDFSubfieldDefn name=\"%s\" format=\"%s\"/>\n",
     299             :                            poSubFieldDefn->GetName(),
     300             :                            poSubFieldDefn->GetFormat());
     301             :                 }
     302             :             }
     303         224 :             for (const auto &poSubFieldDefn : poFieldDefn->GetSubfields())
     304             :             {
     305         182 :                 printf("  <DDFSubfieldDefn name=\"%s\" format=\"%s\"/>\n",
     306             :                        poSubFieldDefn->GetName(), poSubFieldDefn->GetFormat());
     307             :             }
     308          42 :             printf("</DDFFieldDefn>\n");
     309             :         }
     310             : 
     311             :         // DDFRecord       *poRecord;
     312         147 :         for (DDFRecord *poRecord = oModule.ReadRecord(); poRecord != nullptr;
     313         143 :              poRecord = oModule.ReadRecord())
     314             :         {
     315         143 :             printf("<DDFRecord");
     316         143 :             if (bAllDetails)
     317             :             {
     318         143 :                 if (poRecord->GetReuseHeader())
     319           0 :                     printf(" reuseHeader=\"1\"");
     320         143 :                 printf(" dataSize=\"%d\"", poRecord->GetDataSize());
     321         143 :                 printf(" _sizeFieldTag=\"%d\"", poRecord->GetSizeFieldTag());
     322         143 :                 printf(" _sizeFieldPos=\"%d\"", poRecord->GetSizeFieldPos());
     323         143 :                 printf(" _sizeFieldLength=\"%d\"",
     324             :                        poRecord->GetSizeFieldLength());
     325             :             }
     326         143 :             printf(">\n");
     327         143 :             int nFieldCount = poRecord->GetFieldCount();
     328         713 :             for (int iField = 0; iField < nFieldCount; iField++)
     329             :             {
     330         570 :                 const DDFField *poField = poRecord->GetField(iField);
     331         570 :                 DumpFieldAsXML(poField);
     332             :             }
     333         143 :             printf("</DDFRecord>\n");
     334             :         }
     335           4 :         printf("</DDFModule>\n");
     336             :     }
     337             :     else
     338             :     {
     339           0 :         oModule.Dump(stdout);
     340             :         long nStartLoc;
     341             : 
     342           0 :         nStartLoc = VSIFTellL(oModule.GetFP());
     343           0 :         for (DDFRecord *poRecord = oModule.ReadRecord(); poRecord != nullptr;
     344           0 :              poRecord = oModule.ReadRecord())
     345             :         {
     346           0 :             printf("File Offset: %ld\n", nStartLoc);
     347           0 :             poRecord->Dump(stdout);
     348             : 
     349           0 :             nStartLoc = VSIFTellL(oModule.GetFP());
     350             :         }
     351             :     }
     352             : 
     353           4 :     oModule.Close();
     354           4 : }

Generated by: LCOV version 1.14