Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOTCPStreamDecoder.c File Reference
#include "OOTCPStreamDecoder.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include "OODebugTCPConsoleProtocol.h"
+ Include dependency graph for OOTCPStreamDecoder.c:

Go to the source code of this file.

Classes

struct  OOTCPStreamDecoder
 

Macros

#define LogOOTCPStreamDecoderPacket(packet)
 

Functions

static void Error (OOTCPStreamDecoderRef decoder, OOALStringRef format,...)
 
static void PacketReady (OOTCPStreamDecoderRef decoder)
 
OOTCPStreamDecoderRef OOTCPStreamDecoderCreate (OOTCPStreamDecoderPacketCallback packetCB, OOTCPStreamDecoderErrorCallback errorCB, OOTCPStreamDecoderFinalizeCallback finalizeCB, void *cbInfo)
 
void OOTCPStreamDecoderDestroy (OOTCPStreamDecoderRef decoder)
 
void OOTCPStreamDecoderReceiveData (OOTCPStreamDecoderRef decoder, OOALDataRef data)
 
void OOTCPStreamDecoderReceiveBytes (OOTCPStreamDecoderRef decoder, const void *inBytes, size_t length)
 

Macro Definition Documentation

◆ LogOOTCPStreamDecoderPacket

#define LogOOTCPStreamDecoderPacket ( packet)
Value:
do {} while (0)

Definition at line 41 of file OOTCPStreamDecoder.c.

Referenced by PacketReady().

Function Documentation

◆ Error()

static void Error ( OOTCPStreamDecoderRef decoder,
OOALStringRef format,
... )
static

Definition at line 227 of file OOTCPStreamDecoder.c.

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}
OOALStringRef OOALStringCreateWithFormatAndArguments(OOALStringRef format, va_list args)
const struct NSString * OOALStringRef
void OOALRelease(OOALObjectRef object)
OOTCPStreamDecoderErrorCallback Error

References OOTCPStreamDecoder::cbInfo, OOTCPStreamDecoder::Error, OOALRelease(), and OOALStringCreateWithFormatAndArguments().

Referenced by OOTCPStreamDecoderReceiveBytes(), and PacketReady().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ OOTCPStreamDecoderCreate()

OOTCPStreamDecoderRef OOTCPStreamDecoderCreate ( OOTCPStreamDecoderPacketCallback packetCB,
OOTCPStreamDecoderErrorCallback errorCB,
OOTCPStreamDecoderFinalizeCallback finalizeCB,
void * cbInfo )

Definition at line 64 of file OOTCPStreamDecoder.c.

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}
OOTCPStreamDecoderFinalizeCallback Finalize
OOALMutableDataRef nextPacketData
OOTCPStreamDecoderPacketCallback Packet

References OOTCPStreamDecoder::cbInfo, OOTCPStreamDecoder::Error, OOTCPStreamDecoder::Finalize, OOTCPStreamDecoder::headerSpaceUsed, OOTCPStreamDecoder::nextPacketData, OOTCPStreamDecoder::nextSize, and OOTCPStreamDecoder::Packet.

◆ OOTCPStreamDecoderDestroy()

void OOTCPStreamDecoderDestroy ( OOTCPStreamDecoderRef decoder)

Definition at line 85 of file OOTCPStreamDecoder.c.

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 {
97 decoder->nextPacketData = NULL;
98 }
99
100 free(decoder);
101}

References OOTCPStreamDecoder::cbInfo, OOTCPStreamDecoder::Finalize, OOTCPStreamDecoder::nextPacketData, and OOALRelease().

+ Here is the call graph for this function:

◆ OOTCPStreamDecoderReceiveBytes()

void OOTCPStreamDecoderReceiveBytes ( OOTCPStreamDecoderRef decoder,
const void * inBytes,
size_t length )

Definition at line 112 of file OOTCPStreamDecoder.c.

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.
148 PacketReady(decoder);
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}
#define OOALSTR(x)
const struct NSAutoreleasePool * OOALAutoreleasePoolRef
void OOALMutableDataAppendBytes(OOALMutableDataRef data, const void *bytes, size_t length)
#define OOALDestroyAutoreleasePool(pool)
OOALAutoreleasePoolRef OOALCreateAutoreleasePool(void)
OOALMutableDataRef OOALDataCreateMutable(size_t capacity)
static void PacketReady(OOTCPStreamDecoderRef decoder)
static void Error(OOTCPStreamDecoderRef decoder, OOALStringRef format,...)

References Error(), OOTCPStreamDecoder::header, OOTCPStreamDecoder::headerSpaceUsed, OOTCPStreamDecoder::nextPacketData, OOTCPStreamDecoder::nextSize, OOALCreateAutoreleasePool(), OOALDataCreateMutable(), OOALDestroyAutoreleasePool, OOALMutableDataAppendBytes(), OOALRelease(), OOALSTR, and PacketReady().

Referenced by OOTCPStreamDecoderReceiveData().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ OOTCPStreamDecoderReceiveData()

void OOTCPStreamDecoderReceiveData ( OOTCPStreamDecoderRef decoder,
OOALDataRef data )

Definition at line 104 of file OOTCPStreamDecoder.c.

105{
106 if (decoder == NULL || data == NULL) return;
107
109}
const void * OOALDataGetBytePtr(OOALDataRef data)
size_t OOALDataGetLength(OOALDataRef data)
void OOTCPStreamDecoderReceiveBytes(OOTCPStreamDecoderRef decoder, const void *inBytes, size_t length)

References OOALDataGetBytePtr(), OOALDataGetLength(), and OOTCPStreamDecoderReceiveBytes().

+ Here is the call graph for this function:

◆ PacketReady()

static void PacketReady ( OOTCPStreamDecoderRef decoder)
static

Definition at line 184 of file OOTCPStreamDecoder.c.

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
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}
#define kOOTCPPacketType
OOALStringRef OOTypeDescription(OOALObjectRef object)
bool OOALIsDictionary(OOALObjectRef object)
OOALObjectRef OOALDictionaryGetValue(OOALDictionaryRef dictionary, OOALObjectRef key)
const struct NSDictionary * OOALDictionaryRef
bool OOALIsString(OOALObjectRef object)
OOALObjectRef OOALPropertyListFromData(OOALMutableDataRef data, OOALStringRef *errStr)
#define LogOOTCPStreamDecoderPacket(packet)

References OOTCPStreamDecoder::cbInfo, Error(), kOOTCPPacketType, LogOOTCPStreamDecoderPacket, OOTCPStreamDecoder::nextPacketData, OOALDictionaryGetValue(), OOALIsDictionary(), OOALIsString(), OOALPropertyListFromData(), OOALRelease(), OOALSTR, OOTypeDescription(), and OOTCPStreamDecoder::Packet.

Referenced by OOTCPStreamDecoderReceiveBytes().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: