OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDdffield.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copied from "gdal" project. See licence below.
3  *
4  * Project: ISO 8211 Access
5  * Purpose: Implements the DDFField class.
6  * Author: Frank Warmerdam, warmerda@home.com
7  *
8  ******************************************************************************
9  * Copyright (c) 1999, Frank Warmerdam
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ******************************************************************************
29  * $Id: ossimDdffield.cpp 17170 2010-04-20 13:51:55Z gpotts $
30  */
31 
34 #include <ossim/base/ossimCommon.h>
35 
36 // #include "cpl_conv.h"
37 
38 // CPL_CVSID("$Id: ossimDdffield.cpp 17170 2010-04-20 13:51:55Z gpotts $");
39 
40 // Note, we implement no constructor for this class to make instantiation
41 // cheaper. It is required that the Initialize() be called before anything
42 // else.
43 
44 /************************************************************************/
45 /* Initialize() */
46 /************************************************************************/
47 
48 void ossimDDFField::Initialize( ossimDDFFieldDefn *poDefnIn, const char * pachDataIn,
49  int nDataSizeIn )
50 
51 {
52  pachData = pachDataIn;
53  nDataSize = nDataSizeIn;
54  poDefn = poDefnIn;
55 }
56 
57 /************************************************************************/
58 /* Dump() */
59 /************************************************************************/
60 
71 void ossimDDFField::Dump( FILE * fp )
72 
73 {
74  int nMaxRepeat = 8;
75 
76  if( getenv("DDF_MAXDUMP") != NULL )
77  nMaxRepeat = atoi(getenv("DDF_MAXDUMP"));
78 
79  fprintf( fp, " DDFField:\n" );
80  fprintf( fp, " Tag = `%s'\n", poDefn->GetName() );
81  fprintf( fp, " DataSize = %d\n", nDataSize );
82 
83  fprintf( fp, " Data = `" );
84  for( int i = 0; i < std::min(nDataSize,40); i++ )
85  {
86  if( pachData[i] < 32 || pachData[i] > 126 )
87  fprintf( fp, "\\%02X", ((unsigned char *) pachData)[i] );
88  else
89  fprintf( fp, "%c", pachData[i] );
90  }
91 
92  if( nDataSize > 40 )
93  fprintf( fp, "..." );
94  fprintf( fp, "'\n" );
95 
96 /* -------------------------------------------------------------------- */
97 /* dump the data of the subfields. */
98 /* -------------------------------------------------------------------- */
99  int iOffset = 0, nLoopCount;
100 
101  for( nLoopCount = 0; nLoopCount < GetRepeatCount(); nLoopCount++ )
102  {
103  if( nLoopCount > nMaxRepeat )
104  {
105  fprintf( fp, " ...\n" );
106  break;
107  }
108 
109  for( int i = 0; i < poDefn->GetSubfieldCount(); i++ )
110  {
111  int nBytesConsumed;
112 
113  poDefn->GetSubfield(i)->DumpData( pachData + iOffset,
114  nDataSize - iOffset, fp );
115 
116  poDefn->GetSubfield(i)->GetDataLength( pachData + iOffset,
117  nDataSize - iOffset,
118  &nBytesConsumed );
119 
120  iOffset += nBytesConsumed;
121  }
122  }
123 }
124 
125 /************************************************************************/
126 /* GetSubfieldData() */
127 /************************************************************************/
128 
153  int *pnMaxBytes, int iSubfieldIndex )
154 
155 {
156  int iOffset = 0;
157 
158  if( poSFDefn == NULL )
159  return NULL;
160 
161  if( iSubfieldIndex > 0 && poDefn->GetFixedWidth() > 0 )
162  {
163  iOffset = poDefn->GetFixedWidth() * iSubfieldIndex;
164  iSubfieldIndex = 0;
165  }
166 
167  while( iSubfieldIndex >= 0 )
168  {
169  for( int iSF = 0; iSF < poDefn->GetSubfieldCount(); iSF++ )
170  {
171  int nBytesConsumed;
172  ossimDDFSubfieldDefn * poThisSFDefn = poDefn->GetSubfield( iSF );
173 
174  if( poThisSFDefn == poSFDefn && iSubfieldIndex == 0 )
175  {
176  if( pnMaxBytes != NULL )
177  *pnMaxBytes = nDataSize - iOffset;
178 
179  return pachData + iOffset;
180  }
181 
182  poThisSFDefn->GetDataLength( pachData+iOffset, nDataSize - iOffset,
183  &nBytesConsumed);
184  iOffset += nBytesConsumed;
185  }
186 
187  iSubfieldIndex--;
188  }
189 
190  // We didn't find our target subfield or instance!
191  return NULL;
192 }
193 
194 /************************************************************************/
195 /* GetRepeatCount() */
196 /************************************************************************/
197 
210 
211 {
212  if( !poDefn->IsRepeating() )
213  return 1;
214 
215 /* -------------------------------------------------------------------- */
216 /* The occurance count depends on how many copies of this */
217 /* field's list of subfields can fit into the data space. */
218 /* -------------------------------------------------------------------- */
219  if( poDefn->GetFixedWidth() )
220  {
221  return nDataSize / poDefn->GetFixedWidth();
222  }
223 
224 /* -------------------------------------------------------------------- */
225 /* Note that it may be legal to have repeating variable width */
226 /* subfields, but I don't have any samples, so I ignore it for */
227 /* now. */
228 /* */
229 /* The file data/cape_royal_AZ_DEM/1183XREF.DDF has a repeating */
230 /* variable length field, but the count is one, so it isn't */
231 /* much value for testing. */
232 /* -------------------------------------------------------------------- */
233  int iOffset = 0, iRepeatCount = 1;
234 
235  while( true )
236  {
237  for( int iSF = 0; iSF < poDefn->GetSubfieldCount(); iSF++ )
238  {
239  int nBytesConsumed;
240  ossimDDFSubfieldDefn * poThisSFDefn = poDefn->GetSubfield( iSF );
241 
242  if( poThisSFDefn->GetWidth() > nDataSize - iOffset )
243  nBytesConsumed = poThisSFDefn->GetWidth();
244  else
245  poThisSFDefn->GetDataLength( pachData+iOffset,
246  nDataSize - iOffset,
247  &nBytesConsumed);
248 
249  iOffset += nBytesConsumed;
250  if( iOffset > nDataSize )
251  return iRepeatCount - 1;
252  }
253 
254  if( iOffset > nDataSize - 2 )
255  return iRepeatCount;
256 
257  iRepeatCount++;
258  }
259 }
260 
261 /************************************************************************/
262 /* GetInstanceData() */
263 /************************************************************************/
264 
280 const char *ossimDDFField::GetInstanceData( int nInstance,
281  int *pnInstanceSize )
282 
283 {
284  int nRepeatCount = GetRepeatCount();
285  const char *pachWrkData;
286 
287  if( nInstance < 0 || nInstance >= nRepeatCount )
288  return NULL;
289 
290 /* -------------------------------------------------------------------- */
291 /* Special case for fields without subfields (like "0001"). We */
292 /* don't currently handle repeating simple fields. */
293 /* -------------------------------------------------------------------- */
294  if( poDefn->GetSubfieldCount() == 0 )
295  {
296  pachWrkData = GetData();
297  if( pnInstanceSize != 0 )
298  *pnInstanceSize = GetDataSize();
299  return pachWrkData;
300  }
301 
302 /* -------------------------------------------------------------------- */
303 /* Get a pointer to the start of the existing data for this */
304 /* iteration of the field. */
305 /* -------------------------------------------------------------------- */
306  int nBytesRemaining1=0, nBytesRemaining2=0;
307  ossimDDFSubfieldDefn *poFirstSubfield;
308 
309  poFirstSubfield = poDefn->GetSubfield(0);
310 
311  pachWrkData = GetSubfieldData(poFirstSubfield, &nBytesRemaining1,
312  nInstance);
313 
314 /* -------------------------------------------------------------------- */
315 /* Figure out the size of the entire field instance, including */
316 /* unit terminators, but not any trailing field terminator. */
317 /* -------------------------------------------------------------------- */
318  if( pnInstanceSize != NULL )
319  {
320  ossimDDFSubfieldDefn *poLastSubfield;
321  int nLastSubfieldWidth;
322  const char *pachLastData;
323 
324  poLastSubfield = poDefn->GetSubfield(poDefn->GetSubfieldCount()-1);
325 
326  pachLastData = GetSubfieldData( poLastSubfield, &nBytesRemaining2,
327  nInstance );
328  poLastSubfield->GetDataLength( pachLastData, nBytesRemaining2,
329  &nLastSubfieldWidth );
330 
331  *pnInstanceSize =
332  nBytesRemaining1 - (nBytesRemaining2 - nLastSubfieldWidth);
333  }
334 
335  return pachWrkData;
336 }
void Initialize(ossimDDFFieldDefn *, const char *pszData, int nSize)
Information from the DDR defining one field.
Definition: ossimIso8211.h:179
int GetDataSize()
Return the number of bytes in the data block returned by GetData().
Definition: ossimIso8211.h:512
const char * GetName()
Fetch a pointer to the field name (tag).
Definition: ossimIso8211.h:203
const char * GetSubfieldData(ossimDDFSubfieldDefn *, int *=NULL, int=0)
Fetch raw data pointer for a particular subfield of this field.
int GetRepeatCount()
How many times do the subfields of this record repeat? This will always be one for non-repeating fie...
const char * pachData
Definition: ossimIso8211.h:524
int GetFixedWidth()
Get the width of this field.
Definition: ossimIso8211.h:223
const char * GetData()
Return the pointer to the entire data block for this record.
Definition: ossimIso8211.h:509
const char * GetInstanceData(int nInstance, int *pnSize)
Get field instance data and size.
int GetSubfieldCount()
Get the number of subfields.
Definition: ossimIso8211.h:211
void Dump(FILE *fp)
Write out field contents to debugging file.
int GetDataLength(const char *, int, int *)
Scan for the end of variable length data.
int GetWidth()
Get the subfield width (zero for variable).
Definition: ossimIso8211.h:324
void DumpData(const char *pachData, int nMaxBytes, FILE *fp)
Dump subfield value to debugging file.
int IsRepeating()
Fetch repeating flag.
Definition: ossimIso8211.h:230
ossimDDFSubfieldDefn * GetSubfield(int i)
Fetch a subfield by index.
Information from the DDR record describing one subfield of a DDFFieldDefn.
Definition: ossimIso8211.h:278
ossimDDFFieldDefn * poDefn
Definition: ossimIso8211.h:520
#define min(a, b)
Definition: auxiliary.h:75