/src/gdal/frmts/iso8211/iso8211.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: ISO 8211 Access |
4 | | * Purpose: Main declarations for ISO 8211. |
5 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef ISO8211_H_INCLUDED |
14 | | #define ISO8211_H_INCLUDED |
15 | | |
16 | | #include "cpl_port.h" |
17 | | #include "cpl_vsi.h" |
18 | | |
19 | | /** |
20 | | General data type |
21 | | */ |
22 | | typedef enum |
23 | | { |
24 | | DDFInt, |
25 | | DDFFloat, |
26 | | DDFString, |
27 | | DDFBinaryString |
28 | | } DDFDataType; |
29 | | |
30 | | /************************************************************************/ |
31 | | /* These should really be private to the library ... they are */ |
32 | | /* mostly conveniences. */ |
33 | | /************************************************************************/ |
34 | | |
35 | | int CPL_ODLL DDFScanInt(const char *pszString, int nMaxChars); |
36 | | int CPL_ODLL DDFScanVariable(const char *pszString, int nMaxChars, |
37 | | int nDelimChar); |
38 | | char CPL_ODLL *DDFFetchVariable(const char *pszString, int nMaxChars, |
39 | | int nDelimChar1, int nDelimChar2, |
40 | | int *pnConsumedChars); |
41 | | |
42 | 48.6M | #define DDF_FIELD_TERMINATOR 30 |
43 | 2.00M | #define DDF_UNIT_TERMINATOR 31 |
44 | | |
45 | | /************************************************************************/ |
46 | | /* Predeclarations */ |
47 | | /************************************************************************/ |
48 | | |
49 | | class DDFFieldDefn; |
50 | | class DDFSubfieldDefn; |
51 | | class DDFRecord; |
52 | | class DDFField; |
53 | | |
54 | | /************************************************************************/ |
55 | | /* DDFModule */ |
56 | | /************************************************************************/ |
57 | | |
58 | | /** |
59 | | The primary class for reading ISO 8211 files. This class contains all |
60 | | the information read from the DDR record, and is used to read records |
61 | | from the file. |
62 | | */ |
63 | | |
64 | | class CPL_ODLL DDFModule |
65 | | { |
66 | | public: |
67 | | DDFModule(); |
68 | | ~DDFModule(); |
69 | | |
70 | | int Open(const char *pszFilename, int bFailQuietly = FALSE); |
71 | | int Create(const char *pszFilename); |
72 | | void Close(); |
73 | | |
74 | | int Initialize(char chInterchangeLevel = '3', char chLeaderIden = 'L', |
75 | | char chCodeExtensionIndicator = 'E', |
76 | | char chVersionNumber = '1', char chAppIndicator = ' ', |
77 | | const char *pszExtendedCharSet = " ! ", |
78 | | int nSizeFieldLength = 3, int nSizeFieldPos = 4, |
79 | | int nSizeFieldTag = 4); |
80 | | |
81 | | void Dump(FILE *fp); |
82 | | |
83 | | DDFRecord *ReadRecord(); |
84 | | void Rewind(long nOffset = -1); |
85 | | |
86 | | const DDFFieldDefn *FindFieldDefn(const char *) const; |
87 | | |
88 | | DDFFieldDefn *FindFieldDefn(const char *name) |
89 | 284k | { |
90 | 284k | return const_cast<DDFFieldDefn *>( |
91 | 284k | const_cast<const DDFModule *>(this)->FindFieldDefn(name)); |
92 | 284k | } |
93 | | |
94 | | /** Fetch the number of defined fields. */ |
95 | | |
96 | | int GetFieldCount() const |
97 | 0 | { |
98 | 0 | return nFieldDefnCount; |
99 | 0 | } |
100 | | |
101 | | DDFFieldDefn *GetField(int); |
102 | | void AddField(DDFFieldDefn *poNewFDefn); |
103 | | |
104 | | // This is really just for internal use. |
105 | | int GetFieldControlLength() const |
106 | 296k | { |
107 | 296k | return _fieldControlLength; |
108 | 296k | } |
109 | | |
110 | | void AddCloneRecord(DDFRecord *); |
111 | | void RemoveCloneRecord(DDFRecord *); |
112 | | |
113 | | // This is just for DDFRecord. |
114 | | VSILFILE *GetFP() |
115 | 12.0M | { |
116 | 12.0M | return fpDDF; |
117 | 12.0M | } |
118 | | |
119 | | int GetSizeFieldTag() const |
120 | 574k | { |
121 | 574k | return (int)_sizeFieldTag; |
122 | 574k | } |
123 | | |
124 | | // Advanced uses for 8211dump/8211createfromxml |
125 | | int GetSizeFieldPos() const |
126 | 0 | { |
127 | 0 | return _sizeFieldPos; |
128 | 0 | } |
129 | | |
130 | | int GetSizeFieldLength() const |
131 | 0 | { |
132 | 0 | return _sizeFieldLength; |
133 | 0 | } |
134 | | |
135 | | char GetInterchangeLevel() const |
136 | 0 | { |
137 | 0 | return _interchangeLevel; |
138 | 0 | } |
139 | | |
140 | | char GetLeaderIden() const |
141 | 0 | { |
142 | 0 | return _leaderIden; |
143 | 0 | } |
144 | | |
145 | | char GetCodeExtensionIndicator() const |
146 | 0 | { |
147 | 0 | return _inlineCodeExtensionIndicator; |
148 | 0 | } |
149 | | |
150 | | char GetVersionNumber() const |
151 | 0 | { |
152 | 0 | return _versionNumber; |
153 | 0 | } |
154 | | |
155 | | char GetAppIndicator() const |
156 | 0 | { |
157 | 0 | return _appIndicator; |
158 | 0 | } |
159 | | |
160 | | const char *GetExtendedCharSet() const |
161 | 0 | { |
162 | 0 | return _extendedCharSet; |
163 | 0 | } |
164 | | |
165 | | void SetFieldControlLength(int nVal) |
166 | 0 | { |
167 | 0 | _fieldControlLength = nVal; |
168 | 0 | } |
169 | | |
170 | | private: |
171 | | VSILFILE *fpDDF; |
172 | | int bReadOnly; |
173 | | long nFirstRecordOffset; |
174 | | |
175 | | char _interchangeLevel; |
176 | | char _inlineCodeExtensionIndicator; |
177 | | char _versionNumber; |
178 | | char _appIndicator; |
179 | | int _fieldControlLength; |
180 | | char _extendedCharSet[4]; |
181 | | |
182 | | int _recLength; |
183 | | char _leaderIden; |
184 | | int _fieldAreaStart; |
185 | | int _sizeFieldLength; |
186 | | int _sizeFieldPos; |
187 | | int _sizeFieldTag; |
188 | | |
189 | | // One DirEntry per field. |
190 | | int nFieldDefnCount; |
191 | | DDFFieldDefn **papoFieldDefns; |
192 | | |
193 | | DDFRecord *poRecord; |
194 | | |
195 | | int nCloneCount; |
196 | | int nMaxCloneCount; |
197 | | DDFRecord **papoClones; |
198 | | }; |
199 | | |
200 | | /************************************************************************/ |
201 | | /* DDFFieldDefn */ |
202 | | /************************************************************************/ |
203 | | |
204 | | typedef enum |
205 | | { |
206 | | dsc_elementary, |
207 | | dsc_vector, |
208 | | dsc_array, |
209 | | dsc_concatenated |
210 | | } DDF_data_struct_code; |
211 | | |
212 | | typedef enum |
213 | | { |
214 | | dtc_char_string, |
215 | | dtc_implicit_point, |
216 | | dtc_explicit_point, |
217 | | dtc_explicit_point_scaled, |
218 | | dtc_char_bit_string, |
219 | | dtc_bit_string, |
220 | | dtc_mixed_data_type |
221 | | } DDF_data_type_code; |
222 | | |
223 | | /** |
224 | | * Information from the DDR defining one field. Note that just because |
225 | | * a field is defined for a DDFModule doesn't mean that it actually occurs |
226 | | * on any records in the module. DDFFieldDefns are normally just significant |
227 | | * as containers of the DDFSubfieldDefns. |
228 | | */ |
229 | | |
230 | | class CPL_ODLL DDFFieldDefn |
231 | | { |
232 | | public: |
233 | | DDFFieldDefn(); |
234 | | ~DDFFieldDefn(); |
235 | | |
236 | | int Create(const char *pszTag, const char *pszFieldName, |
237 | | const char *pszDescription, DDF_data_struct_code eDataStructCode, |
238 | | DDF_data_type_code eDataTypeCode, |
239 | | const char *pszFormat = nullptr); |
240 | | void AddSubfield(DDFSubfieldDefn *poNewSFDefn, |
241 | | int bDontAddToFormat = FALSE); |
242 | | void AddSubfield(const char *pszName, const char *pszFormat); |
243 | | int GenerateDDREntry(DDFModule *poModule, char **ppachData, int *pnLength); |
244 | | |
245 | | int Initialize(DDFModule *poModule, const char *pszTag, int nSize, |
246 | | const char *pachRecord); |
247 | | |
248 | | void Dump(FILE *fp); |
249 | | |
250 | | /** Fetch a pointer to the field name (tag). |
251 | | * @return this is an internal copy and should not be freed. |
252 | | */ |
253 | | const char *GetName() const |
254 | 12.6M | { |
255 | 12.6M | return pszTag; |
256 | 12.6M | } |
257 | | |
258 | | /** Fetch a longer description of this field. |
259 | | * @return this is an internal copy and should not be freed. |
260 | | */ |
261 | | const char *GetDescription() const |
262 | 0 | { |
263 | 0 | return _fieldName; |
264 | 0 | } |
265 | | |
266 | | /** Get the number of subfields. */ |
267 | | int GetSubfieldCount() const |
268 | 7.52M | { |
269 | 7.52M | return nSubfieldCount; |
270 | 7.52M | } |
271 | | |
272 | | const DDFSubfieldDefn *GetSubfield(int i) const; |
273 | | const DDFSubfieldDefn *FindSubfieldDefn(const char *) const; |
274 | | |
275 | | /** |
276 | | * Get the width of this field. This function isn't normally used |
277 | | * by applications. |
278 | | * |
279 | | * @return The width of the field in bytes, or zero if the field is not |
280 | | * apparently of a fixed width. |
281 | | */ |
282 | | int GetFixedWidth() const |
283 | 219k | { |
284 | 219k | return nFixedWidth; |
285 | 219k | } |
286 | | |
287 | | /** |
288 | | * Fetch repeating flag. |
289 | | * @see DDFField::GetRepeatCount() |
290 | | * @return TRUE if the field is marked as repeating. |
291 | | */ |
292 | | int IsRepeating() const |
293 | 159k | { |
294 | 159k | return bRepeatingSubfields; |
295 | 159k | } |
296 | | |
297 | | static char *ExpandFormat(const char *); |
298 | | |
299 | | /** this is just for an S-57 hack for swedish data */ |
300 | | void SetRepeatingFlag(int n) |
301 | 156 | { |
302 | 156 | bRepeatingSubfields = n; |
303 | 156 | } |
304 | | |
305 | | char *GetDefaultValue(int *pnSize); |
306 | | |
307 | | const char *GetArrayDescr() const |
308 | 0 | { |
309 | 0 | return _arrayDescr; |
310 | 0 | } |
311 | | |
312 | | const char *GetFormatControls() const |
313 | 0 | { |
314 | 0 | return _formatControls; |
315 | 0 | } |
316 | | |
317 | | DDF_data_struct_code GetDataStructCode() const |
318 | 0 | { |
319 | 0 | return _data_struct_code; |
320 | 0 | } |
321 | | |
322 | | DDF_data_type_code GetDataTypeCode() const |
323 | 0 | { |
324 | 0 | return _data_type_code; |
325 | 0 | } |
326 | | |
327 | | void SetFormatControls(const char *pszVal); |
328 | | |
329 | | private: |
330 | | static char *ExtractSubstring(const char *); |
331 | | |
332 | | DDFModule *poModule; |
333 | | char *pszTag; |
334 | | |
335 | | char *_fieldName; |
336 | | char *_arrayDescr; |
337 | | char *_formatControls; |
338 | | |
339 | | int bRepeatingSubfields; |
340 | | int nFixedWidth; // zero if variable. |
341 | | |
342 | | void BuildSubfields(); |
343 | | int ApplyFormats(); |
344 | | |
345 | | DDF_data_struct_code _data_struct_code; |
346 | | |
347 | | DDF_data_type_code _data_type_code; |
348 | | |
349 | | int nSubfieldCount; |
350 | | DDFSubfieldDefn **papoSubfields; |
351 | | |
352 | | CPL_DISALLOW_COPY_ASSIGN(DDFFieldDefn) |
353 | | }; |
354 | | |
355 | | /************************************************************************/ |
356 | | /* DDFSubfieldDefn */ |
357 | | /* */ |
358 | | /* Information from the DDR record for one subfield of a */ |
359 | | /* particular field. */ |
360 | | /************************************************************************/ |
361 | | |
362 | | /** |
363 | | * Information from the DDR record describing one subfield of a DDFFieldDefn. |
364 | | * All subfields of a field will occur in each occurrence of that field |
365 | | * (as a DDFField) in a DDFRecord. Subfield's actually contain formatted |
366 | | * data (as instances within a record). |
367 | | */ |
368 | | |
369 | | class CPL_ODLL DDFSubfieldDefn |
370 | | { |
371 | | public: |
372 | | DDFSubfieldDefn(); |
373 | | ~DDFSubfieldDefn(); |
374 | | |
375 | | void SetName(const char *pszName); |
376 | | |
377 | | /** Get pointer to subfield name. */ |
378 | | const char *GetName() const |
379 | 9.68M | { |
380 | 9.68M | return pszName; |
381 | 9.68M | } |
382 | | |
383 | | /** Get pointer to subfield format string */ |
384 | | const char *GetFormat() const |
385 | 9.20k | { |
386 | 9.20k | return pszFormatString; |
387 | 9.20k | } |
388 | | |
389 | | int SetFormat(const char *pszFormat); |
390 | | |
391 | | /** |
392 | | * Get the general type of the subfield. This can be used to |
393 | | * determine which of ExtractFloatData(), ExtractIntData() or |
394 | | * ExtractStringData() should be used. |
395 | | * @return The subfield type. One of DDFInt, DDFFloat, DDFString or |
396 | | * DDFBinaryString. |
397 | | */ |
398 | | |
399 | | DDFDataType GetType() const |
400 | 0 | { |
401 | 0 | return eType; |
402 | 0 | } |
403 | | |
404 | | double ExtractFloatData(const char *pachData, int nMaxBytes, |
405 | | int *pnConsumedBytes) const; |
406 | | int ExtractIntData(const char *pachData, int nMaxBytes, |
407 | | int *pnConsumedBytes) const; |
408 | | const char *ExtractStringData(const char *pachData, int nMaxBytes, |
409 | | int *pnConsumedBytes) const; |
410 | | int GetDataLength(const char *, int, int *) const; |
411 | | void DumpData(const char *pachData, int nMaxBytes, FILE *fp) const; |
412 | | |
413 | | int FormatStringValue(char *pachData, int nBytesAvailable, int *pnBytesUsed, |
414 | | const char *pszValue, int nValueLength = -1) const; |
415 | | |
416 | | int FormatIntValue(char *pachData, int nBytesAvailable, int *pnBytesUsed, |
417 | | int nNewValue) const; |
418 | | |
419 | | int FormatFloatValue(char *pachData, int nBytesAvailable, int *pnBytesUsed, |
420 | | double dfNewValue) const; |
421 | | |
422 | | /** Get the subfield width (zero for variable). */ |
423 | | int GetWidth() const |
424 | 2.46M | { |
425 | 2.46M | return nFormatWidth; |
426 | 2.46M | } // zero for variable. |
427 | | |
428 | | int GetDefaultValue(char *pachData, int nBytesAvailable, |
429 | | int *pnBytesUsed) const; |
430 | | |
431 | | void Dump(FILE *fp); |
432 | | |
433 | | /** |
434 | | Binary format: this is the digit immediately following the B or b for |
435 | | binary formats. |
436 | | */ |
437 | | typedef enum |
438 | | { |
439 | | NotBinary = 0, |
440 | | UInt = 1, |
441 | | SInt = 2, |
442 | | FPReal = 3, |
443 | | FloatReal = 4, |
444 | | FloatComplex = 5 |
445 | | } DDFBinaryFormat; |
446 | | |
447 | | DDFBinaryFormat GetBinaryFormat() const |
448 | 0 | { |
449 | 0 | return eBinaryFormat; |
450 | 0 | } |
451 | | |
452 | | private: |
453 | | char *pszName; // a.k.a. subfield mnemonic |
454 | | char *pszFormatString; |
455 | | |
456 | | DDFDataType eType; |
457 | | DDFBinaryFormat eBinaryFormat; |
458 | | |
459 | | /* -------------------------------------------------------------------- */ |
460 | | /* bIsVariable determines whether we using the */ |
461 | | /* chFormatDelimiter (TRUE), or the fixed width (FALSE). */ |
462 | | /* -------------------------------------------------------------------- */ |
463 | | int bIsVariable; |
464 | | |
465 | | char chFormatDelimiter; |
466 | | int nFormatWidth; |
467 | | |
468 | | /* -------------------------------------------------------------------- */ |
469 | | /* Fetched string cache. This is where we hold the values */ |
470 | | /* returned from ExtractStringData(). */ |
471 | | /* -------------------------------------------------------------------- */ |
472 | | mutable int nMaxBufChars; |
473 | | mutable char *pachBuffer; |
474 | | }; |
475 | | |
476 | | /************************************************************************/ |
477 | | /* DDFRecord */ |
478 | | /* */ |
479 | | /* Class that contains one DR record from a file. We read into */ |
480 | | /* the same record object repeatedly to ensure that repeated */ |
481 | | /* leaders can be easily preserved. */ |
482 | | /************************************************************************/ |
483 | | |
484 | | /** |
485 | | * Contains instance data from one data record (DR). The data is contained |
486 | | * as a list of DDFField instances partitioning the raw data into fields. |
487 | | */ |
488 | | |
489 | | class CPL_ODLL DDFRecord |
490 | | { |
491 | | public: |
492 | | explicit DDFRecord(DDFModule *); |
493 | | ~DDFRecord(); |
494 | | |
495 | | DDFRecord *Clone(); |
496 | | DDFRecord *CloneOn(DDFModule *); |
497 | | |
498 | | void Dump(FILE *); |
499 | | |
500 | | /** Get the number of DDFFields on this record. */ |
501 | | int GetFieldCount() const |
502 | 192k | { |
503 | 192k | return nFieldCount; |
504 | 192k | } |
505 | | |
506 | | const DDFField *FindField(const char *, int = 0) const; |
507 | | |
508 | | DDFField *FindField(const char *name, int i = 0) |
509 | 1.96M | { |
510 | 1.96M | return const_cast<DDFField *>( |
511 | 1.96M | const_cast<const DDFRecord *>(this)->FindField(name, i)); |
512 | 1.96M | } |
513 | | |
514 | | const DDFField *GetField(int) const; |
515 | | |
516 | | DDFField *GetField(int i) |
517 | 799k | { |
518 | 799k | return const_cast<DDFField *>( |
519 | 799k | const_cast<const DDFRecord *>(this)->GetField(i)); |
520 | 799k | } |
521 | | |
522 | | int GetIntSubfield(const char *, int, const char *, int, |
523 | | int * = nullptr) const; |
524 | | double GetFloatSubfield(const char *, int, const char *, int, |
525 | | int * = nullptr); |
526 | | const char *GetStringSubfield(const char *, int, const char *, int, |
527 | | int * = nullptr); |
528 | | |
529 | | int SetIntSubfield(const char *pszField, int iFieldIndex, |
530 | | const char *pszSubfield, int iSubfieldIndex, int nValue); |
531 | | int SetStringSubfield(const char *pszField, int iFieldIndex, |
532 | | const char *pszSubfield, int iSubfieldIndex, |
533 | | const char *pszValue, int nValueLength = -1); |
534 | | int SetFloatSubfield(const char *pszField, int iFieldIndex, |
535 | | const char *pszSubfield, int iSubfieldIndex, |
536 | | double dfNewValue); |
537 | | |
538 | | /** Fetch size of records raw data (GetData()) in bytes. */ |
539 | | int GetDataSize() const |
540 | 0 | { |
541 | 0 | return nDataSize; |
542 | 0 | } |
543 | | |
544 | | /** |
545 | | * Fetch the raw data for this record. The returned pointer is effectively |
546 | | * to the data for the first field of the record, and is of size |
547 | | * GetDataSize(). |
548 | | */ |
549 | | const char *GetData() const |
550 | 0 | { |
551 | 0 | return pachData; |
552 | 0 | } |
553 | | |
554 | | /** |
555 | | * Fetch the DDFModule with which this record is associated. |
556 | | */ |
557 | | |
558 | | DDFModule *GetModule() |
559 | 0 | { |
560 | 0 | return poModule; |
561 | 0 | } |
562 | | |
563 | | int ResizeField(DDFField *poField, int nNewDataSize); |
564 | | int DeleteField(DDFField *poField); |
565 | | DDFField *AddField(DDFFieldDefn *); |
566 | | |
567 | | int CreateDefaultFieldInstance(DDFField *poField, int iIndexWithinField); |
568 | | |
569 | | int SetFieldRaw(DDFField *poField, int iIndexWithinField, |
570 | | const char *pachRawData, int nRawDataSize); |
571 | | int UpdateFieldRaw(DDFField *poField, int iIndexWithinField, |
572 | | int nStartOffset, int nOldSize, const char *pachRawData, |
573 | | int nRawDataSize); |
574 | | |
575 | | int Write(); |
576 | | |
577 | | // Advanced uses for 8211dump/8211createfromxml |
578 | | int GetReuseHeader() const |
579 | 0 | { |
580 | 0 | return nReuseHeader; |
581 | 0 | } |
582 | | |
583 | | int GetSizeFieldTag() const |
584 | 0 | { |
585 | 0 | return _sizeFieldTag; |
586 | 0 | } |
587 | | |
588 | | int GetSizeFieldPos() const |
589 | 0 | { |
590 | 0 | return _sizeFieldPos; |
591 | 0 | } |
592 | | |
593 | | int GetSizeFieldLength() const |
594 | 0 | { |
595 | 0 | return _sizeFieldLength; |
596 | 0 | } |
597 | | |
598 | | // void SetReuseHeader(int bFlag) { nReuseHeader = bFlag; } |
599 | | void SetSizeFieldTag(int nVal) |
600 | 0 | { |
601 | 0 | _sizeFieldTag = nVal; |
602 | 0 | } |
603 | | |
604 | | void SetSizeFieldPos(int nVal) |
605 | 0 | { |
606 | 0 | _sizeFieldPos = nVal; |
607 | 0 | } |
608 | | |
609 | | void SetSizeFieldLength(int nVal) |
610 | 0 | { |
611 | 0 | _sizeFieldLength = nVal; |
612 | 0 | } |
613 | | |
614 | | // This is really just for the DDFModule class. |
615 | | int Read(); |
616 | | void Clear(); |
617 | | void ResetDirectory(); |
618 | | |
619 | | void RemoveIsCloneFlag() |
620 | 484k | { |
621 | 484k | bIsClone = FALSE; |
622 | 484k | } |
623 | | |
624 | | private: |
625 | | int ReadHeader(); |
626 | | |
627 | | DDFModule *poModule; |
628 | | |
629 | | int nReuseHeader; |
630 | | |
631 | | int nFieldOffset; // field data area, not dir entries. |
632 | | |
633 | | int _sizeFieldTag; |
634 | | int _sizeFieldPos; |
635 | | int _sizeFieldLength; |
636 | | |
637 | | int nDataSize; // Whole record except leader with header |
638 | | char *pachData; |
639 | | |
640 | | int nFieldCount; |
641 | | DDFField *paoFields; |
642 | | |
643 | | int bIsClone; |
644 | | }; |
645 | | |
646 | | /************************************************************************/ |
647 | | /* DDFField */ |
648 | | /* */ |
649 | | /* This object represents one field in a DDFRecord. */ |
650 | | /************************************************************************/ |
651 | | |
652 | | /** |
653 | | * This object represents one field in a DDFRecord. This |
654 | | * models an instance of the fields data, rather than its data definition, |
655 | | * which is handled by the DDFFieldDefn class. Note that a DDFField |
656 | | * doesn't have DDFSubfield children as you would expect. To extract |
657 | | * subfield values use GetSubfieldData() to find the right data pointer and |
658 | | * then use ExtractIntData(), ExtractFloatData() or ExtractStringData(). |
659 | | */ |
660 | | |
661 | | class CPL_ODLL DDFField |
662 | | { |
663 | | public: |
664 | 2.06M | DDFField() : poDefn(nullptr), nDataSize(0), pachData(nullptr) |
665 | 2.06M | { |
666 | 2.06M | } |
667 | | |
668 | | void Initialize(DDFFieldDefn *, const char *pszData, int nSize); |
669 | | |
670 | | void Dump(FILE *fp); |
671 | | |
672 | | const char *GetSubfieldData(const DDFSubfieldDefn *, int * = nullptr, |
673 | | int = 0) const; |
674 | | |
675 | | const char *GetInstanceData(int nInstance, int *pnSize); |
676 | | |
677 | | /** |
678 | | * Return the pointer to the entire data block for this record. This |
679 | | * is an internal copy, and should not be freed by the application. |
680 | | */ |
681 | | const char *GetData() const |
682 | 1.16M | { |
683 | 1.16M | return pachData; |
684 | 1.16M | } |
685 | | |
686 | | /** Return the number of bytes in the data block returned by GetData(). */ |
687 | | int GetDataSize() const |
688 | 1.16M | { |
689 | 1.16M | return nDataSize; |
690 | 1.16M | } |
691 | | |
692 | | int GetRepeatCount() const; |
693 | | |
694 | | /** Fetch the corresponding DDFFieldDefn. */ |
695 | | DDFFieldDefn *GetFieldDefn() |
696 | 11.8M | { |
697 | 11.8M | return poDefn; |
698 | 11.8M | } |
699 | | |
700 | | /** Fetch the corresponding DDFFieldDefn. */ |
701 | | const DDFFieldDefn *GetFieldDefn() const |
702 | 2.95M | { |
703 | 2.95M | return poDefn; |
704 | 2.95M | } |
705 | | |
706 | | private: |
707 | | DDFFieldDefn *poDefn; |
708 | | |
709 | | int nDataSize; |
710 | | |
711 | | const char *pachData; |
712 | | }; |
713 | | |
714 | | #endif /* ndef ISO8211_H_INCLUDED */ |