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: 2025-01-18 12:42:00 Functions: 7 17 41.2 %

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

Generated by: LCOV version 1.14