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 : }
|