LCOV - code coverage report
Current view: top level - Core/Debug - OOTCPStreamDecoder.c (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 17 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOTCPStreamDecoder.c
       4             : 
       5             : 
       6             : Copyright (C) 2007 Jens Ayton and contributors
       7             : 
       8             : Permission is hereby granted, free of charge, to any person obtaining a copy
       9             : of this software and associated documentation files (the "Software"), to deal
      10             : in the Software without restriction, including without limitation the rights
      11             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12             : copies of the Software, and to permit persons to whom the Software is
      13             : furnished to do so, subject to the following conditions:
      14             : 
      15             : The above copyright notice and this permission notice shall be included in all
      16             : copies or substantial portions of the Software.
      17             : 
      18             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      24             : SOFTWARE.
      25             : 
      26             : */
      27             : 
      28             : #ifndef OO_EXCLUDE_DEBUG_SUPPORT
      29             : 
      30             : 
      31             : #include "OOTCPStreamDecoder.h"
      32             : #include <stdlib.h>
      33             : #include <stdarg.h>
      34             : #include <stdint.h>
      35             : #include "OODebugTCPConsoleProtocol.h"
      36             : 
      37             : 
      38             : #ifdef OO_LOG_DEBUG_PROTOCOL_PACKETS
      39             : extern void LogOOTCPStreamDecoderPacket(OOALDictionaryRef packet);
      40             : #else
      41           0 : #define LogOOTCPStreamDecoderPacket(packet) do {} while (0)
      42             : #endif
      43             : 
      44             : 
      45           0 : struct OOTCPStreamDecoder
      46             : {
      47           0 :         uint8_t                                                         header[4];
      48           0 :         uint32_t                                                        headerSpaceUsed;
      49           0 :         OOALMutableDataRef                                      nextPacketData;
      50           0 :         uint32_t                                                        nextSize;
      51             :         
      52           0 :         OOTCPStreamDecoderPacketCallback        Packet;
      53           0 :         OOTCPStreamDecoderErrorCallback         Error;
      54           0 :         OOTCPStreamDecoderFinalizeCallback      Finalize;
      55             :         
      56           0 :         void                                                            *cbInfo;
      57             : };
      58             : 
      59             : 
      60             : static void Error(OOTCPStreamDecoderRef decoder, OOALStringRef format, ...);
      61             : static void PacketReady(OOTCPStreamDecoderRef decoder);
      62             : 
      63             : 
      64           0 : OOTCPStreamDecoderRef OOTCPStreamDecoderCreate(OOTCPStreamDecoderPacketCallback packetCB, OOTCPStreamDecoderErrorCallback errorCB, OOTCPStreamDecoderFinalizeCallback finalizeCB, void *cbInfo)
      65             : {
      66             :         OOTCPStreamDecoderRef                           decoder = NULL;
      67             :         
      68             :         if (packetCB == NULL)  return NULL;
      69             :         
      70             :         decoder = malloc(sizeof *decoder);
      71             :         if (decoder == NULL)  return NULL;
      72             :         
      73             :         decoder->headerSpaceUsed = 0;
      74             :         decoder->nextPacketData = NULL;
      75             :         decoder->nextSize = 0;
      76             :         decoder->Packet = packetCB;
      77             :         decoder->Error = errorCB;
      78             :         decoder->Finalize = finalizeCB;
      79             :         decoder->cbInfo = cbInfo;
      80             :         
      81             :         return decoder;
      82             : }
      83             : 
      84             : 
      85           0 : void OOTCPStreamDecoderDestroy(OOTCPStreamDecoderRef decoder)
      86             : {
      87             :         if (decoder == NULL)  return;
      88             :         
      89             :         if (decoder->Finalize != NULL)
      90             :         {
      91             :                 decoder->Finalize(decoder->cbInfo);
      92             :         }
      93             :         
      94             :         if (decoder->nextPacketData != NULL)
      95             :         {
      96             :                 OOALRelease(decoder->nextPacketData);
      97             :                 decoder->nextPacketData = NULL;
      98             :         }
      99             :         
     100             :         free(decoder);
     101             : }
     102             : 
     103             : 
     104           0 : void OOTCPStreamDecoderReceiveData(OOTCPStreamDecoderRef decoder, OOALDataRef data)
     105             : {
     106             :         if (decoder == NULL || data == NULL)  return;
     107             :         
     108             :         OOTCPStreamDecoderReceiveBytes(decoder, OOALDataGetBytePtr(data), OOALDataGetLength(data));
     109             : }
     110             : 
     111             : 
     112           0 : void OOTCPStreamDecoderReceiveBytes(OOTCPStreamDecoderRef decoder, const void *inBytes, size_t length)
     113             : {
     114             :         const unsigned char                             *bytes = NULL;
     115             :         size_t                                                  remaining;
     116             :         size_t                                                  bytesToAdd;
     117             :         OOALAutoreleasePoolRef                  pool = NULL;
     118             :         
     119             :         if (decoder == NULL)  return;
     120             :         
     121             :         bytes = inBytes;
     122             :         remaining = length;
     123             :         
     124             :         if (bytes == NULL && remaining != 0)
     125             :         {
     126             :                 Error(decoder, OOALSTR("Invalid data -- NULL bytes but %u byte count."), remaining);
     127             :                 return;
     128             :         }
     129             :         
     130             :         while (remaining != 0)
     131             :         {
     132             :                 if (decoder->nextPacketData != NULL)
     133             :                 {
     134             :                         // More data expected
     135             :                         bytesToAdd = remaining;
     136             :                         if (decoder->nextSize < bytesToAdd)  bytesToAdd = decoder->nextSize;
     137             :                         
     138             :                         OOALMutableDataAppendBytes(decoder->nextPacketData, bytes, bytesToAdd);
     139             :                         
     140             :                         remaining -= bytesToAdd;
     141             :                         decoder->nextSize -= bytesToAdd;
     142             :                         bytes += bytesToAdd;
     143             :                         
     144             :                         if (decoder->nextSize == 0)
     145             :                         {
     146             :                                 // Packet is ready.
     147             :                                 pool = OOALCreateAutoreleasePool();
     148             :                                 PacketReady(decoder);
     149             :                                 OOALDestroyAutoreleasePool(pool);
     150             :                                 pool = NULL;
     151             :                                 
     152             :                                 OOALRelease(decoder->nextPacketData);
     153             :                                 decoder->nextPacketData = NULL;
     154             :                         }
     155             :                 }
     156             :                 else if (decoder->headerSpaceUsed < 4)
     157             :                 {
     158             :                         // Read bytes for packet header
     159             :                         remaining--;
     160             :                         decoder->header[decoder->headerSpaceUsed++] = *bytes++;
     161             :                 }
     162             :                 else if (decoder->headerSpaceUsed == 4)
     163             :                 {
     164             :                         // We've read a header, start on a packet.
     165             :                         decoder->nextSize = (decoder->header[0] << 24) |
     166             :                                                                 (decoder->header[1] << 16) |
     167             :                                                                 (decoder->header[2] << 8) |
     168             :                                                                 (decoder->header[3] << 0);
     169             :                         
     170             :                         decoder->headerSpaceUsed = 0;
     171             :                         if (decoder->nextSize != 0)
     172             :                         {
     173             :                                 decoder->nextPacketData = OOALDataCreateMutable(decoder->nextSize);
     174             :                         }
     175             :                 }
     176             :                 else
     177             :                 {
     178             :                         Error(decoder, OOALSTR("OOTCPStreamDecoder internal error: reached unreachable state. nextSize = %lu, bufferUsed = %lu, nextPacketData = %@."), (unsigned long)decoder->nextSize, (unsigned long)decoder->headerSpaceUsed, decoder->nextPacketData);
     179             :                 }
     180             :         }
     181             : }
     182             : 
     183             : 
     184           0 : static void PacketReady(OOTCPStreamDecoderRef decoder)
     185             : {
     186             :         OOALDictionaryRef                                       packet = NULL;
     187             :         OOALStringRef                                           errorString = NULL;
     188             :         OOALStringRef                                           packetType = NULL;
     189             :         
     190             :         packet = OOALPropertyListFromData(decoder->nextPacketData, &errorString);
     191             :         
     192             :         // Ensure that it's a property list.
     193             :         if (packet == NULL)
     194             :         {
     195             :                 Error(decoder, OOALSTR("Protocol error: packet is not property list (property list error: %@)."), errorString);
     196             :                 OOALRelease(errorString);
     197             :                 return;
     198             :         }
     199             :         
     200             :         // Ensure that it's a dictionary.
     201             :         if (!OOALIsDictionary(packet))
     202             :         {
     203             :                 Error(decoder, OOALSTR("Protocol error: packet is a %@, not a dictionary."), OOTypeDescription(packet));
     204             :                 return;
     205             :         }
     206             :         
     207             :         LogOOTCPStreamDecoderPacket(packet);
     208             :         
     209             :         // Get packet type (and ensure that there is one).
     210             :         packetType = OOALDictionaryGetValue(packet, kOOTCPPacketType);
     211             :         if (packetType == NULL)
     212             :         {
     213             :                 Error(decoder, OOALSTR("Protocol error: packet contains no packet type."));
     214             :                 return;
     215             :         }
     216             :         
     217             :         if (!OOALIsString(packetType))
     218             :         {
     219             :                 Error(decoder, OOALSTR("Protocol error: packet type is a %@, not a string."), OOTypeDescription(packetType));
     220             :                 return;
     221             :         }
     222             :         
     223             :         decoder->Packet(decoder->cbInfo, packetType, packet);
     224             : }
     225             : 
     226             : 
     227           0 : static void Error(OOTCPStreamDecoderRef decoder, OOALStringRef format, ...)
     228             : {
     229             :         va_list                                                 args;
     230             :         OOALStringRef                                   string = NULL;
     231             :         
     232             :         if (decoder == NULL || decoder->Error == NULL || format == NULL)  return;
     233             :         
     234             :         va_start(args, format);
     235             :         string = OOALStringCreateWithFormatAndArguments(format, args);
     236             :         va_end(args);
     237             :         
     238             :         if (string != NULL)
     239             :         {
     240             :                 decoder->Error(decoder->cbInfo, string);
     241             :                 OOALRelease(string);
     242             :         }
     243             : }
     244             : 
     245             : #endif /* OO_EXCLUDE_DEBUG_SUPPORT */

Generated by: LCOV version 1.14