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