1 : /******************************************************************************
2 : * $Id: ceos.c 12600 2007-11-01 14:09:01Z dron $
3 : *
4 : * Project: ASI CEOS Translator
5 : * Purpose: Core CEOS functions.
6 : * Author: Paul Lahaie, pjlahaie@atlsci.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2000, Atlantis Scientific Inc
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 :
30 : #include "ceos.h"
31 :
32 : CPL_CVSID("$Id: ceos.c 12600 2007-11-01 14:09:01Z dron $");
33 :
34 : /* Function implementations of functions described in ceos.h */
35 :
36 : void CeosUpdateHeaderFromBuffer(CeosRecord_t *record);
37 :
38 : void InitEmptyCeosRecord(CeosRecord_t *record, int32 sequence, CeosTypeCode_t typecode, int32 length)
39 0 : {
40 0 : if(record)
41 : {
42 0 : if((record->Buffer = HMalloc(length)) == NULL)
43 : {
44 0 : return;
45 : }
46 : /* First we zero fill the buffer */
47 0 : memset(record->Buffer,0,length);
48 :
49 : /* Setup values inside the CeosRecord_t header */
50 0 : record->Sequence = sequence;
51 0 : record->Flavour = 0;
52 0 : record->FileId = 0;
53 0 : record->TypeCode = typecode;
54 0 : record->Subsequence = 0;
55 0 : record->Length = length;
56 :
57 : /* Now we fill in the buffer portion as well */
58 0 : NativeToCeos( record->Buffer+__SEQUENCE_OFF, &(record->Sequence), sizeof(record->Sequence), sizeof( record->Sequence ) );
59 0 : memcpy(record->Buffer+__TYPE_OFF, &( record->TypeCode.Int32Code ), sizeof( record->TypeCode.Int32Code ) );
60 0 : NativeToCeos( record->Buffer+__LENGTH_OFF, &length, sizeof( length ), sizeof( length ) );
61 : }
62 : }
63 :
64 : void InitCeosRecord(CeosRecord_t *record, uchar *buffer)
65 0 : {
66 0 : if(record && buffer)
67 : {
68 0 : InitCeosRecordWithHeader(record, buffer, buffer+__CEOS_HEADER_LENGTH);
69 : }
70 0 : }
71 :
72 : void InitCeosRecordWithHeader(CeosRecord_t *record, uchar *header, uchar *buffer)
73 21 : {
74 21 : if(record && buffer && header)
75 : {
76 21 : if( record->Length != 0 )
77 21 : record->Length = DetermineCeosRecordBodyLength( header );
78 :
79 21 : if((record->Buffer = HMalloc(record->Length)) == NULL)
80 : {
81 0 : record->Length = 0;
82 0 : return;
83 : }
84 :
85 : /* First copy the header then the buffer */
86 21 : memcpy(record->Buffer,header,__CEOS_HEADER_LENGTH);
87 : /* Now we copy the rest */
88 21 : memcpy(record->Buffer+__CEOS_HEADER_LENGTH,buffer,record->Length-__CEOS_HEADER_LENGTH);
89 :
90 : /* Now we fill in the rest of the structure! */
91 21 : memcpy(&(record->TypeCode.Int32Code),header+__TYPE_OFF,sizeof(record->TypeCode.Int32Code));
92 21 : CeosToNative(&(record->Sequence),header+__SEQUENCE_OFF,sizeof(record->Sequence), sizeof( record->Sequence ) );
93 : }
94 : }
95 :
96 : int DetermineCeosRecordBodyLength(const uchar *header)
97 42 : {
98 : int i;
99 :
100 42 : if(header)
101 : {
102 42 : CeosToNative(&i,header+__LENGTH_OFF,sizeof( i ), sizeof( i ) );
103 :
104 42 : return i;
105 : }
106 :
107 0 : return -1;
108 : }
109 :
110 : void DeleteCeosRecord(CeosRecord_t *record)
111 21 : {
112 21 : if(record)
113 : {
114 21 : if(record->Buffer)
115 : {
116 21 : HFree(record->Buffer);
117 21 : record->Buffer = NULL;
118 : }
119 21 : HFree( record );
120 : }
121 21 : }
122 :
123 : void GetCeosRecordStruct(const CeosRecord_t *record,void *struct_ptr)
124 0 : {
125 0 : if(record && struct_ptr && record->Buffer)
126 : {
127 0 : memcpy(record->Buffer,struct_ptr,record->Length);
128 : }
129 0 : }
130 :
131 : void PutCeosRecordStruct(CeosRecord_t *record,const void *struct_ptr)
132 0 : {
133 : int Length;
134 :
135 0 : if(record && struct_ptr)
136 : {
137 0 : CeosToNative( &Length, struct_ptr, sizeof( Length ), sizeof( Length ) );
138 0 : memcpy(record->Buffer,struct_ptr,Length);
139 0 : CeosUpdateHeaderFromBuffer(record);
140 : }
141 0 : }
142 :
143 : void GetCeosField(CeosRecord_t *record, int32 start_byte,
144 : const char *format, void *value)
145 59 : {
146 : int field_size;
147 : char *d_ptr;
148 59 : char *mod_buf = NULL;
149 :
150 59 : field_size = atoi(format+1);
151 :
152 59 : if(field_size < 1)
153 : {
154 0 : return;
155 : }
156 :
157 : /* Check for out of bounds */
158 59 : if(start_byte + field_size - 1 > record->Length)
159 : {
160 0 : return;
161 : }
162 :
163 59 : if((mod_buf = (char *) HMalloc(field_size + 1)) == NULL)
164 : {
165 0 : return;
166 : }
167 :
168 59 : memcpy(mod_buf,record->Buffer+(start_byte-1), field_size);
169 59 : mod_buf[field_size] = '\0';
170 :
171 : /* Switch on format type */
172 59 : switch(format[0])
173 : {
174 : case 'b':
175 : case 'B':
176 : /* Binary data type */
177 3 : if(field_size > 1)
178 : {
179 3 : CeosToNative( value, mod_buf, field_size, field_size );
180 : } else {
181 0 : memcpy( value, mod_buf, field_size );
182 : }
183 3 : break;
184 :
185 : case 'i':
186 : case 'I':
187 : /* Integer type */
188 8 : *( (int *)value) = atoi(mod_buf);
189 8 : break;
190 :
191 : case 'f':
192 : case 'F':
193 : case 'e':
194 : case 'E':
195 : /* Double precision float data type */
196 :
197 : /* Change the 'D' exponent separators to 'e' */
198 0 : if( ( d_ptr = strchr(mod_buf, 'd') ) != NULL)
199 : {
200 0 : *d_ptr = 'e';
201 : }
202 0 : if( ( d_ptr = strchr(mod_buf, 'D') ) != NULL)
203 : {
204 0 : *d_ptr = 'e';
205 : }
206 :
207 0 : *( (double *)value) = strtod(mod_buf,NULL);
208 0 : break;
209 : case 'a':
210 : case 'A':
211 : /* ASCII.. We just easily extract it */
212 48 : ( (char *)value)[field_size] = '\0';
213 48 : memcpy( value, mod_buf, field_size );
214 48 : break;
215 :
216 : default:
217 : /* Unknown format */
218 0 : return;
219 : }
220 :
221 59 : HFree(mod_buf);
222 :
223 : }
224 :
225 : void SetCeosField(CeosRecord_t *record, int32 start_byte, char *format, void *value)
226 0 : {
227 : int field_size;
228 0 : char * temp_buf = NULL;
229 : char printf_format[ 20 ];
230 :
231 0 : field_size = 0;
232 0 : sscanf(&format[1], "%d", &field_size);
233 0 : if(field_size < 1)
234 : {
235 0 : return;
236 : }
237 :
238 : /* Check for bounds */
239 0 : if(start_byte + field_size - 1 > record->Length)
240 : {
241 0 : return;
242 : }
243 :
244 : /* Make a local buffer to print into */
245 0 : if((temp_buf = (char *) HMalloc(field_size+1)) == NULL)
246 : {
247 0 : return;
248 : }
249 0 : switch(format[0])
250 : {
251 : case 'b':
252 : case 'B':
253 : /* Binary data type */
254 0 : if(field_size > 1)
255 : {
256 0 : NativeToCeos( value, temp_buf, field_size, field_size );
257 : } else {
258 0 : memcpy(value,temp_buf,field_size);
259 : }
260 0 : break;
261 :
262 : case 'i':
263 : case 'I':
264 : /* Integer data type */
265 0 : sprintf( printf_format,"%%%s%c",format+1, 'd');
266 0 : sprintf( temp_buf, printf_format, *(int *) value);
267 0 : break;
268 :
269 : case 'f':
270 : case 'F':
271 : /* Double precision floating point data type */
272 0 : sprintf(printf_format, "%%%s%c", format+1, 'g');
273 0 : sprintf(temp_buf, printf_format, *(double *)value);
274 0 : break;
275 :
276 : case 'e':
277 : case 'E':
278 : /* Double precision floating point data type (forced exponent) */
279 0 : sprintf(printf_format,"%%%s%c", format+1, 'e');
280 0 : sprintf(temp_buf, printf_format, *(double *)value);
281 0 : break;
282 :
283 : case 'a':
284 : case 'A':
285 0 : strncpy(temp_buf,value,field_size+1);
286 0 : temp_buf[field_size] = '0';
287 0 : break;
288 :
289 : default:
290 : /* Unknown format */
291 0 : return;
292 : }
293 :
294 0 : memcpy(record->Buffer + start_byte -1, temp_buf, field_size);
295 :
296 0 : HFree(temp_buf);
297 : }
298 :
299 : void SetIntCeosField(CeosRecord_t *record, int32 start_byte, int32 length, int32 value)
300 0 : {
301 0 : int integer_value = value;
302 : char total_len[12]; /* 12 because 2^32 -> 4294967296 + I + null */
303 :
304 0 : sprintf(total_len,"I%d",length);
305 0 : SetCeosField(record,start_byte,total_len,&integer_value);
306 0 : }
307 :
308 : CeosRecord_t *FindCeosRecord(Link_t *record_list, CeosTypeCode_t typecode, int32 fileid, int32 flavour, int32 subsequence)
309 37 : {
310 : Link_t *Link;
311 : CeosRecord_t *record;
312 :
313 725 : for( Link = record_list; Link != NULL; Link = Link->next )
314 : {
315 708 : record = (CeosRecord_t *)Link->object;
316 :
317 708 : if( (record->TypeCode.Int32Code == typecode.Int32Code)
318 : && ( ( fileid == -1 ) || ( record->FileId == fileid ) )
319 : && ( ( flavour == -1 ) || ( record->Flavour == flavour ) )
320 : && ( ( subsequence == -1 ) || ( record->Subsequence == subsequence ) ) )
321 20 : return record;
322 : }
323 :
324 17 : return NULL;
325 : }
326 :
327 : void SerializeCeosRecordsToFile(Link_t *record_list, FILE *fp)
328 0 : {
329 : Link_t *list;
330 : CeosRecord_t crec;
331 : unsigned char *Buffer;
332 :
333 0 : list = record_list;
334 :
335 0 : while(list != NULL)
336 : {
337 0 : memcpy(&crec,list->object,sizeof(CeosRecord_t));
338 0 : Buffer = crec.Buffer;
339 0 : crec.Buffer = NULL;
340 0 : fwrite(&crec,sizeof(CeosRecord_t),1,fp);
341 0 : fwrite(Buffer,crec.Length,1,fp);
342 : }
343 0 : }
344 :
345 : void SerializeCeosRecordsFromFile(Link_t *record_list, FILE *fp)
346 0 : {
347 : CeosRecord_t *crec;
348 : Link_t *Link;
349 :
350 0 : while(!feof(fp))
351 : {
352 0 : crec = HMalloc(sizeof(CeosRecord_t));
353 0 : fread(crec,sizeof(CeosRecord_t),1,fp);
354 0 : crec->Buffer = HMalloc(crec->Length * sizeof(char) );
355 0 : fread(crec->Buffer,sizeof(char),crec->Length,fp);
356 0 : Link = ceos2CreateLink(crec);
357 0 : AddLink(record_list,Link);
358 : }
359 0 : }
360 :
361 : void CeosUpdateHeaderFromBuffer(CeosRecord_t *record)
362 0 : {
363 0 : if(record && record->Buffer)
364 : {
365 0 : CeosToNative( &( record->Length ), record->Buffer+__LENGTH_OFF, sizeof(record->Length ), sizeof( record->Length ) );
366 0 : memcpy(&(record->TypeCode.Int32Code),record->Buffer+__TYPE_OFF,sizeof(record->TypeCode.Int32Code));
367 0 : CeosToNative(&(record->Sequence),record->Buffer+__SEQUENCE_OFF,sizeof(record->Sequence ), sizeof( record->Sequence ) );
368 : }
369 0 : record->Subsequence = 0;
370 0 : }
371 :
372 : #ifdef CPL_LSB
373 :
374 : void swapbyte(void *dst,void *src,int toswap)
375 66 : {
376 : int i,e;
377 66 : unsigned char *in = (unsigned char *) src;
378 66 : unsigned char *out = (unsigned char *) dst;
379 :
380 330 : for(i = 0,e=toswap;i < toswap;i++,e--)
381 : {
382 264 : out[i] = in[e-1];
383 : }
384 66 : }
385 :
386 : void NativeToCeos( void *dst, const void *src, const size_t len, const size_t swapunit)
387 66 : {
388 : int i;
389 : int remainder;
390 : int units;
391 :
392 :
393 66 : remainder = len % swapunit;
394 :
395 66 : units = len - remainder;
396 :
397 132 : for(i = 0;i < units; i += swapunit )
398 : {
399 66 : swapbyte( ( unsigned char *) dst + i, ( unsigned char * ) src + i, swapunit);
400 : }
401 :
402 66 : if(remainder)
403 : {
404 0 : memcpy( ( unsigned char * ) dst + i, ( unsigned char * ) src + i, remainder );
405 : }
406 66 : }
407 :
408 : #endif
|