1 : /******************************************************************************
2 : * $Id: sdtslib.cpp 17213 2009-06-07 11:55:50Z rouault $
3 : *
4 : * Project: SDTS Translator
5 : * Purpose: Various utility functions that apply to all SDTS profiles.
6 : * SDTSModId, and SDTSFeature methods.
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 1999, Frank Warmerdam
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "sdts_al.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: sdtslib.cpp 17213 2009-06-07 11:55:50Z rouault $");
35 :
36 : /************************************************************************/
37 : /* SDTSFeature() */
38 : /************************************************************************/
39 :
40 572 : SDTSFeature::SDTSFeature()
41 :
42 : {
43 572 : nAttributes = 0;
44 572 : paoATID = NULL;
45 572 : }
46 :
47 : /************************************************************************/
48 : /* SDTSFeature::ApplyATID() */
49 : /************************************************************************/
50 :
51 12 : void SDTSFeature::ApplyATID( DDFField * poField )
52 :
53 : {
54 12 : int nRepeatCount = poField->GetRepeatCount();
55 : int bUsualFormat;
56 : DDFSubfieldDefn *poMODN;
57 :
58 12 : poMODN = poField->GetFieldDefn()->FindSubfieldDefn( "MODN" );
59 12 : if( poMODN == NULL )
60 : {
61 : CPLAssert( FALSE );
62 0 : return;
63 : }
64 :
65 12 : bUsualFormat = poMODN->GetWidth() == 4;
66 24 : for( int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++ )
67 : {
68 : paoATID = (SDTSModId *) CPLRealloc(paoATID,
69 12 : sizeof(SDTSModId)*(nAttributes+1));
70 :
71 : const char * pabyData;
72 12 : SDTSModId *poModId = paoATID + nAttributes;
73 :
74 12 : if( bUsualFormat )
75 : {
76 12 : pabyData = poField->GetSubfieldData( poMODN, NULL, iRepeat );
77 :
78 12 : memcpy( poModId->szModule, pabyData, 4 );
79 12 : poModId->szModule[4] = '\0';
80 12 : poModId->nRecord = atoi(pabyData + 4);
81 12 : poModId->szOBRP[0] = '\0';
82 : }
83 : else
84 : {
85 0 : poModId->Set( poField );
86 : }
87 :
88 12 : nAttributes++;
89 : }
90 : }
91 :
92 : /************************************************************************/
93 : /* ~SDTSFeature() */
94 : /************************************************************************/
95 :
96 572 : SDTSFeature::~SDTSFeature()
97 :
98 : {
99 572 : CPLFree( paoATID );
100 572 : paoATID = NULL;
101 572 : }
102 :
103 : /************************************************************************/
104 : /* SDTSModId::Set() */
105 : /* */
106 : /* Set a module from a field. We depend on our pre-knowledge */
107 : /* of the data layout to fetch more efficiently. */
108 : /************************************************************************/
109 :
110 827 : int SDTSModId::Set( DDFField *poField )
111 :
112 : {
113 827 : const char *pachData = poField->GetData();
114 827 : DDFFieldDefn *poDefn = poField->GetFieldDefn();
115 :
116 827 : if( poDefn->GetSubfieldCount() >= 2
117 : && poDefn->GetSubfield(0)->GetWidth() == 4 )
118 : {
119 825 : memcpy( szModule, pachData, 4 );
120 825 : szModule[4] = '\0';
121 :
122 825 : nRecord = atoi( pachData + 4 );
123 : }
124 : else
125 : {
126 : DDFSubfieldDefn *poSF;
127 : int nBytesRemaining;
128 : const char *pachData;
129 :
130 2 : poSF = poField->GetFieldDefn()->FindSubfieldDefn( "MODN" );
131 2 : pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
132 : strncpy( szModule,
133 : poSF->ExtractStringData( pachData, nBytesRemaining, NULL),
134 2 : sizeof(szModule) );
135 2 : szModule[sizeof(szModule)-1] = '\0';
136 :
137 2 : poSF = poField->GetFieldDefn()->FindSubfieldDefn( "RCID" );
138 2 : pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
139 2 : nRecord = poSF->ExtractIntData( pachData, nBytesRemaining, NULL);
140 : }
141 :
142 827 : if( poDefn->GetSubfieldCount() == 3 )
143 : {
144 : DDFSubfieldDefn *poSF;
145 :
146 219 : poSF = poField->GetFieldDefn()->FindSubfieldDefn( "OBRP" );
147 219 : if( poSF != NULL )
148 : {
149 : int nBytesRemaining;
150 : const char *pachData;
151 :
152 219 : pachData = poField->GetSubfieldData(poSF, &nBytesRemaining);
153 : strncpy( szOBRP,
154 : poSF->ExtractStringData( pachData, nBytesRemaining, NULL),
155 219 : sizeof(szOBRP) );
156 :
157 219 : szOBRP[sizeof(szOBRP)-1] = '\0';
158 : }
159 : }
160 :
161 827 : return FALSE;
162 : }
163 :
164 : /************************************************************************/
165 : /* SDTSModId::GetName() */
166 : /************************************************************************/
167 :
168 0 : const char * SDTSModId::GetName()
169 :
170 : {
171 : static char szName[20];
172 :
173 0 : sprintf( szName, "%s:%ld", szModule, nRecord );
174 :
175 0 : return szName;
176 : }
177 :
178 : /************************************************************************/
179 : /* SDTSScanModuleReferences() */
180 : /* */
181 : /* Find all modules references by records in this module based */
182 : /* on a particular field name. That field must be in module */
183 : /* reference form (contain MODN/RCID subfields). */
184 : /************************************************************************/
185 :
186 5 : char **SDTSScanModuleReferences( DDFModule * poModule, const char * pszFName )
187 :
188 : {
189 : /* -------------------------------------------------------------------- */
190 : /* Identify the field, and subfield we are interested in. */
191 : /* -------------------------------------------------------------------- */
192 : DDFFieldDefn *poIDField;
193 : DDFSubfieldDefn *poMODN;
194 :
195 5 : poIDField = poModule->FindFieldDefn( pszFName );
196 :
197 5 : if( poIDField == NULL )
198 2 : return NULL;
199 :
200 3 : poMODN = poIDField->FindSubfieldDefn( "MODN" );
201 3 : if( poMODN == NULL )
202 0 : return NULL;
203 :
204 : /* -------------------------------------------------------------------- */
205 : /* Scan the file. */
206 : /* -------------------------------------------------------------------- */
207 : DDFRecord *poRecord;
208 3 : char **papszModnList = NULL;
209 :
210 3 : poModule->Rewind();
211 156 : while( (poRecord = poModule->ReadRecord()) != NULL )
212 : {
213 : int iField;
214 :
215 679 : for( iField = 0; iField < poRecord->GetFieldCount(); iField++ )
216 : {
217 529 : DDFField *poField = poRecord->GetField( iField );
218 :
219 529 : if( poField->GetFieldDefn() == poIDField )
220 : {
221 : const char *pszModName;
222 : int i;
223 :
224 12 : for( i = 0; i < poField->GetRepeatCount(); i++ )
225 : {
226 : char szName[5];
227 :
228 6 : pszModName = poField->GetSubfieldData(poMODN,NULL,i);
229 :
230 6 : strncpy( szName, pszModName, 4 );
231 6 : szName[4] = '\0';
232 :
233 6 : if( CSLFindString( papszModnList, szName ) == -1 )
234 1 : papszModnList = CSLAddString( papszModnList, szName );
235 : }
236 : }
237 : }
238 : }
239 :
240 3 : poModule->Rewind();
241 :
242 3 : return papszModnList;
243 : }
244 :
245 :
|