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

Generated by: LCOV version 1.14