LCOV - code coverage report
Current view: top level - frmts/ceos2 - ceos.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 65 183 35.5 %
Date: 2024-11-21 22:18:42 Functions: 7 17 41.2 %

          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

Generated by: LCOV version 1.14