1 : /******************************************************************************
2 : * $Id: hfadictionary.cpp 21184 2010-12-01 03:11:03Z warmerdam $
3 : *
4 : * Project: Erdas Imagine (.img) Translator
5 : * Purpose: Implementation of the HFADictionary class for managing the
6 : * dictionary read from the HFA file. Most work done by the
7 : * HFAType, and HFAField classes.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Intergraph Corporation
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "hfa_p.h"
33 : #include "cpl_conv.h"
34 :
35 : CPL_CVSID("$Id: hfadictionary.cpp 21184 2010-12-01 03:11:03Z warmerdam $");
36 :
37 : static const char *apszDefDefn[] = {
38 :
39 : "Edsc_Table",
40 : "{1:lnumrows,}Edsc_Table",
41 :
42 : "Edsc_Column",
43 : "{1:lnumRows,1:LcolumnDataPtr,1:e4:integer,real,complex,string,dataType,1:lmaxNumChars,}Edsc_Column",
44 :
45 : "Eprj_Size",
46 : "{1:dwidth,1:dheight,}Eprj_Size",
47 :
48 : "Eprj_Coordinate",
49 : "{1:dx,1:dy,}Eprj_Coordinate",
50 :
51 : "Eprj_MapInfo",
52 : "{0:pcproName,1:*oEprj_Coordinate,upperLeftCenter,1:*oEprj_Coordinate,lowerRightCenter,1:*oEprj_Size,pixelSize,0:pcunits,}Eprj_MapInfo",
53 :
54 : "Eimg_StatisticsParameters830",
55 : "{0:poEmif_String,LayerNames,1:*bExcludedValues,1:oEmif_String,AOIname,1:lSkipFactorX,1:lSkipFactorY,1:*oEdsc_BinFunction,BinFunction,}Eimg_StatisticsParameters830",
56 :
57 : "Esta_Statistics",
58 : "{1:dminimum,1:dmaximum,1:dmean,1:dmedian,1:dmode,1:dstddev,}Esta_Statistics",
59 :
60 : "Edsc_BinFunction",
61 : "{1:lnumBins,1:e4:direct,linear,logarithmic,explicit,binFunctionType,1:dminLimit,1:dmaxLimit,1:*bbinLimits,}Edsc_BinFunction",
62 :
63 : "Eimg_NonInitializedValue",
64 : "{1:*bvalueBD,}Eimg_NonInitializedValue",
65 :
66 : "Eprj_MapProjection842",
67 : "{1:x{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,MIFDictionary,0:pCMIFObject,}Emif_MIFObject,projection,1:x{0:pcstring,}Emif_String,title,}Eprj_MapProjection842",
68 :
69 : "Emif_MIFObject",
70 : "{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,MIFDictionary,0:pCMIFObject,}Emif_MIFObject",
71 :
72 : "Eprj_ProParameters",
73 : "{1:e2:EPRJ_INTERNAL,EPRJ_EXTERNAL,proType,1:lproNumber,0:pcproExeName,0:pcproName,1:lproZone,0:pdproParams,1:*oEprj_Spheroid,proSpheroid,}Eprj_ProParameters",
74 :
75 : "Eprj_Datum",
76 : "{0:pcdatumname,1:e3:EPRJ_DATUM_PARAMETRIC,EPRJ_DATUM_GRID,EPRJ_DATUM_REGRESSION,type,0:pdparams,0:pcgridname,}Eprj_Datum",
77 :
78 : "Eprj_Spheroid",
79 : "{0:pcsphereName,1:da,1:db,1:deSquared,1:dradius,}Eprj_Spheroid",
80 :
81 : NULL,
82 : NULL };
83 :
84 :
85 :
86 : /************************************************************************/
87 : /* ==================================================================== */
88 : /* HFADictionary */
89 : /* ==================================================================== */
90 : /************************************************************************/
91 :
92 :
93 : /************************************************************************/
94 : /* HFADictionary() */
95 : /************************************************************************/
96 :
97 550 : HFADictionary::HFADictionary( const char * pszString )
98 :
99 : {
100 : int i;
101 :
102 550 : nTypes = 0;
103 550 : nTypesMax = 0;
104 550 : papoTypes = NULL;
105 :
106 550 : osDictionaryText = pszString;
107 550 : bDictionaryTextDirty = FALSE;
108 :
109 : /* -------------------------------------------------------------------- */
110 : /* Read all the types. */
111 : /* -------------------------------------------------------------------- */
112 20372 : while( pszString != NULL && *pszString != '.' )
113 : {
114 : HFAType *poNewType;
115 :
116 19272 : poNewType = new HFAType();
117 38544 : pszString = poNewType->Initialize( pszString );
118 :
119 19272 : if( pszString != NULL )
120 19272 : AddType( poNewType );
121 : else
122 0 : delete poNewType;
123 : }
124 :
125 : /* -------------------------------------------------------------------- */
126 : /* Complete the definitions. */
127 : /* -------------------------------------------------------------------- */
128 19822 : for( i = 0; i < nTypes; i++ )
129 : {
130 19272 : papoTypes[i]->CompleteDefn( this );
131 : }
132 550 : }
133 :
134 : /************************************************************************/
135 : /* ~HFADictionary() */
136 : /************************************************************************/
137 :
138 550 : HFADictionary::~HFADictionary()
139 :
140 : {
141 : int i;
142 :
143 19825 : for( i = 0; i < nTypes; i++ )
144 19275 : delete papoTypes[i];
145 :
146 550 : CPLFree( papoTypes );
147 550 : }
148 :
149 : /************************************************************************/
150 : /* AddType() */
151 : /************************************************************************/
152 :
153 19275 : void HFADictionary::AddType( HFAType *poType )
154 :
155 : {
156 19275 : if( nTypes == nTypesMax )
157 : {
158 1588 : nTypesMax = nTypes * 2 + 10;
159 : papoTypes = (HFAType **) CPLRealloc( papoTypes,
160 1588 : sizeof(void*) * nTypesMax );
161 : }
162 :
163 19275 : papoTypes[nTypes++] = poType;
164 19275 : }
165 :
166 : /************************************************************************/
167 : /* FindType() */
168 : /************************************************************************/
169 :
170 13928 : HFAType * HFADictionary::FindType( const char * pszName )
171 :
172 : {
173 : int i;
174 :
175 230958 : for( i = 0; i < nTypes; i++ )
176 : {
177 461907 : if( papoTypes[i]->pszTypeName != NULL &&
178 230952 : strcmp(pszName,papoTypes[i]->pszTypeName) == 0 )
179 13925 : return( papoTypes[i] );
180 : }
181 :
182 : /* -------------------------------------------------------------------- */
183 : /* Check if this is a type have other knowledge of. If so, add */
184 : /* it to the dictionary now. I'm not sure how some files end */
185 : /* up being distributed using types not in the dictionary. */
186 : /* -------------------------------------------------------------------- */
187 3 : for( i = 0; apszDefDefn[i] != NULL; i += 2 )
188 : {
189 3 : if( strcmp( pszName, apszDefDefn[i] ) == 0 )
190 : {
191 3 : HFAType *poNewType = new HFAType();
192 :
193 3 : poNewType->Initialize( apszDefDefn[i+1] );
194 3 : AddType( poNewType );
195 3 : poNewType->CompleteDefn( this );
196 :
197 3 : if( osDictionaryText.size() > 0 )
198 3 : osDictionaryText.erase( osDictionaryText.size() - 1, 1 );
199 3 : osDictionaryText += apszDefDefn[i+1];
200 3 : osDictionaryText += ",.";
201 :
202 3 : bDictionaryTextDirty = TRUE;
203 :
204 3 : return poNewType;
205 : }
206 : }
207 :
208 0 : return NULL;
209 : }
210 :
211 : /************************************************************************/
212 : /* GetItemSize() */
213 : /* */
214 : /* Get the size of a basic (atomic) item. */
215 : /************************************************************************/
216 :
217 74837 : int HFADictionary::GetItemSize( char chType )
218 :
219 : {
220 74837 : switch( chType )
221 : {
222 : case '1':
223 : case '2':
224 : case '4':
225 : case 'c':
226 : case 'C':
227 21036 : return 1;
228 :
229 : case 'e':
230 : case 's':
231 : case 'S':
232 10880 : return 2;
233 :
234 : case 't':
235 : case 'l':
236 : case 'L':
237 : case 'f':
238 29543 : return 4;
239 :
240 : case 'd':
241 : case 'm':
242 10500 : return 8;
243 :
244 : case 'M':
245 0 : return 16;
246 :
247 : case 'b':
248 2878 : return -1;
249 :
250 : case 'o':
251 : case 'x':
252 0 : return 0;
253 :
254 : default:
255 0 : CPLAssert( FALSE );
256 : }
257 :
258 0 : return 0;
259 : }
260 :
261 : /************************************************************************/
262 : /* Dump() */
263 : /************************************************************************/
264 :
265 0 : void HFADictionary::Dump( FILE * fp )
266 :
267 : {
268 : int i;
269 :
270 0 : VSIFPrintf( fp, "\nHFADictionary:\n" );
271 :
272 0 : for( i = 0; i < nTypes; i++ )
273 : {
274 0 : papoTypes[i]->Dump( fp );
275 : }
276 0 : }
|