gwenhywfar 5.11.2beta
msg.c
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the project Gwenhywfar.
3 * Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
4 *
5 * The license for this file can be found in the file COPYING which you
6 * should have received along with this file.
7 ****************************************************************************/
8
9#ifdef HAVE_CONFIG_H
10# include <config.h>
11#endif
12
13/*#define DISABLE_DEBUGLOG*/
14
15
16#include "msgio/msg_p.h"
17
18#include <gwenhywfar/error.h>
19#include <gwenhywfar/misc.h>
20#include <gwenhywfar/debug.h>
21#include <gwenhywfar/text.h>
22
23
24#define GWEN_MSG_SIZE_STEP 4096
25#define GWEN_MSG_SIZE_MASK (~4095)
26
27
30
31
32
33GWEN_MSG *GWEN_Msg_new(uint32_t bufferSize)
34{
35 GWEN_MSG *msg;
36
38 msg->refCount=1;
41 if (bufferSize) {
42 msg->buffer=(uint8_t*) malloc(bufferSize);
43 msg->maxSize=bufferSize;
44 }
45 return msg;
46}
47
48
49
50GWEN_MSG *GWEN_Msg_fromBytes(const uint8_t *ptr, uint32_t len)
51{
52 if (ptr && len) {
53 GWEN_MSG *msg;
54
55 msg=GWEN_Msg_new(len);
56 memmove(msg->buffer, ptr, len);
57 msg->bytesInBuffer=len;
58 return msg;
59 }
60
61 return NULL;
62}
63
64
65
67{
68 if (msg && msg->refCount>0)
69 msg->refCount++;
70}
71
72
73
75{
76 if (msg && msg->refCount>0) {
77 if (msg->refCount==1) {
80 free(msg->buffer);
81 GWEN_DB_Group_free(msg->dbParsedInfo);
83 }
84 else
85 msg->refCount--;
86 }
87}
88
89
90
92{
93 if (srcMsg && srcMsg->refCount>0) {
94 GWEN_MSG *msg;
95
96 msg=GWEN_Msg_new(srcMsg->maxSize);
97 if (srcMsg->maxSize)
98 memmove(msg->buffer, srcMsg->buffer, msg->maxSize);
99 msg->bytesInBuffer=srcMsg->bytesInBuffer;
100 msg->currentPos=srcMsg->currentPos;
101 msg->groupId=srcMsg->groupId;
102 msg->parsedPayloadSize=srcMsg->parsedPayloadSize;
103 msg->parsedPayloadOffset=srcMsg->parsedPayloadOffset;
104 msg->flags=srcMsg->flags;
105 if (srcMsg->dbParsedInfo)
106 msg->dbParsedInfo=GWEN_DB_Group_dup(srcMsg->dbParsedInfo);
107
108 return msg;
109 }
110 return NULL;
111}
112
113
114
116{
117 return msg->groupId;
118}
119
120
121
122void GWEN_Msg_SetGroupId(GWEN_MSG *msg, int groupId)
123{
124 msg->groupId=groupId;
125}
126
127
128
130{
131 if (msg)
132 return msg->buffer;
133 return NULL;
134}
135
136
137
138const uint8_t *GWEN_Msg_GetConstBuffer(const GWEN_MSG *msg)
139{
140 if (msg)
141 return msg->buffer;
142 return NULL;
143}
144
145
146
148{
149 if (msg)
150 return msg->bytesInBuffer;
151 else
152 return 0;
153}
154
155
156
158{
159 if (msg && i<=msg->maxSize)
160 msg->bytesInBuffer=i;
161}
162
163
164
165uint32_t GWEN_Msg_GetMaxSize(const GWEN_MSG *msg)
166{
167 return msg?(msg->maxSize):0;
168}
169
170
171
173{
174 if (msg)
175 return msg->currentPos;
176 else
177 return 0;
178}
179
180
181
182int GWEN_Msg_AddByte(GWEN_MSG *msg, uint8_t b)
183{
184 return GWEN_Msg_AddBytes(msg, &b, 1);
185}
186
187
188
189int GWEN_Msg_AddBytes(GWEN_MSG *msg, const uint8_t *bufferPtr, uint32_t bufferLen)
190{
191 if (msg) {
192 uint32_t newPos;
193
194 newPos=msg->currentPos+bufferLen;
195 if (newPos>=msg->maxSize) {
196 uint32_t newSize;
197 uint8_t *newPtr;
198
199 newSize=((msg->currentPos+bufferLen)+GWEN_MSG_SIZE_STEP) & GWEN_MSG_SIZE_MASK;
200 DBG_INFO(GWEN_LOGDOMAIN, "Resizing buffer from %u bytes to %u bytes", msg->maxSize, newSize);
201 newPtr=realloc(msg->buffer, newSize);
202 if (newPtr==NULL) {
203 DBG_ERROR(GWEN_LOGDOMAIN, "Memory full");
205 }
206 msg->buffer=newPtr;
207 msg->maxSize=newSize;
208 }
209
210 memmove(msg->buffer+msg->currentPos, bufferPtr, bufferLen);
211 msg->currentPos+=bufferLen;
212 msg->bytesInBuffer+=bufferLen;
213 return 0;
214 }
215 return GWEN_ERROR_GENERIC;
216}
217
218
219
221{
222 if (msg) {
223 if ((msg->currentPos<msg->maxSize) &&
224 (msg->currentPos<msg->bytesInBuffer)) {
225 return ((int)(msg->buffer[(msg->currentPos)++])) & 0xff;
226 }
227 }
228 return GWEN_ERROR_EOF;
229}
230
231
232
233int GWEN_Msg_IncCurrentPos(GWEN_MSG *msg, uint32_t i)
234{
235 if (msg) {
236 if (((msg->currentPos+i)<=msg->maxSize) &&
237 ((msg->currentPos+i)<=msg->bytesInBuffer)) {
238 msg->currentPos+=i;
239 return 0;
240 }
241 }
242 return GWEN_ERROR_EOF;
243}
244
245
246
248{
249 if (msg) {
250 msg->currentPos=0;
251 return 0;
252 }
253 return GWEN_ERROR_EOF;
254}
255
256
257
259{
260 if (msg)
261 return msg->bytesInBuffer-msg->currentPos;
262 return 0;
263}
264
265
266
268{
269 if (msg)
270 return msg->parsedPayloadSize;
271 return 0;
272}
273
274
275
277{
278 if (msg)
279 msg->parsedPayloadSize=v;
280}
281
282
283
285{
286 if (msg)
287 return msg->parsedPayloadOffset;
288 return 0;
289}
290
291
292
294{
295 if (msg)
296 msg->parsedPayloadOffset=v;
297}
298
299
300
301uint32_t GWEN_Msg_GetFlags(const GWEN_MSG *msg)
302{
303 if (msg)
304 return msg->flags;
305 return 0;
306}
307
308
309
310void GWEN_Msg_SetFlags(GWEN_MSG *msg, uint32_t f)
311{
312 if (msg)
313 msg->flags=f;
314}
315
316
317
318void GWEN_Msg_AddFlags(GWEN_MSG *msg, uint32_t f)
319{
320 if (msg)
321 msg->flags|=f;
322}
323
324
325
326void GWEN_Msg_DelFlags(GWEN_MSG *msg, uint32_t f)
327{
328 if (msg)
329 msg->flags&=~f;
330}
331
332
333
335{
336 if (msg)
337 return msg->dbParsedInfo;
338 return NULL;
339}
340
341
342
344{
345 if (msg) {
346 if (msg->dbParsedInfo)
347 GWEN_DB_Group_free(msg->dbParsedInfo);
348 msg->dbParsedInfo=db;
349 }
350}
351
352
353
354uint64_t GWEN_Msg_GetUint64At(const GWEN_MSG *msg, int offs, uint64_t defaultValue)
355{
356 if (msg) {
357 if (msg->bytesInBuffer>=offs+8) {
358 const uint8_t *ptr;
359 uint64_t v;
360
361 ptr=msg->buffer+offs;
362 v=(uint64_t)(*(ptr++));
363 v|=(uint64_t)(*(ptr++))<<8;
364 v|=(uint64_t)(*(ptr++))<<16;
365 v|=(uint64_t)(*(ptr++))<<24;
366 v|=(uint64_t)(*(ptr++))<<32;
367 v|=(uint64_t)(*(ptr++))<<40;
368 v|=(uint64_t)(*(ptr++))<<48;
369 v|=(uint64_t)(*(ptr++))<<56;
370 return v;
371 }
372 }
373 return defaultValue;
374}
375
376
377
378uint32_t GWEN_Msg_GetUint32At(const GWEN_MSG *msg, int offs, uint32_t defaultValue)
379{
380 if (msg) {
381 if (msg->bytesInBuffer>=offs+4) {
382 const uint8_t *ptr;
383
384 ptr=msg->buffer+offs;
385 return (uint32_t)(ptr[0])+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
386 }
387 }
388 return defaultValue;
389}
390
391
392
393uint16_t GWEN_Msg_GetUint16At(const GWEN_MSG *msg, int offs, uint16_t defaultValue)
394{
395 if (msg) {
396 if (msg->bytesInBuffer>=offs+2) {
397 const uint8_t *ptr;
398
399 ptr=msg->buffer+offs;
400 return (uint16_t)(ptr[0])+(ptr[1]<<8);
401 }
402 }
403 return defaultValue;
404}
405
406
407
408uint8_t GWEN_Msg_GetUint8At(const GWEN_MSG *msg, int offs, uint8_t defaultValue)
409{
410 if (msg) {
411 if (msg->bytesInBuffer>=offs+1) {
412 const uint8_t *ptr;
413
414 ptr=msg->buffer+offs;
415 return ptr[0];
416 }
417 }
418 return defaultValue;
419}
420
421
422
423void GWEN_Msg_Dump(const GWEN_MSG *msg, GWEN_BUFFER *buf)
424{
425 GWEN_Buffer_AppendArgs(buf, "Msg: bytesInBuffer=%d, maxSize=%d, currentPos=%d",
426 msg->bytesInBuffer, msg->maxSize, msg->currentPos);
427 if (msg->buffer && msg->bytesInBuffer) {
428 GWEN_Buffer_AppendByte(buf, '\n');
429 GWEN_Text_DumpString2Buffer((const char*)(msg->buffer), msg->bytesInBuffer, buf, 2);
430 }
431}
432
433
434
435
#define NULL
Definition binreloc.c:300
int GWEN_Buffer_AppendArgs(GWEN_BUFFER *bf, const char *fmt,...)
Definition buffer.c:1087
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
GWEN_DB_NODE * GWEN_DB_Group_dup(const GWEN_DB_NODE *n)
Definition db.c:428
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition db.c:421
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_MEMORY_FULL
Definition error.h:77
#define GWEN_ERROR_GENERIC
Definition error.h:62
#define GWEN_ERROR_EOF
Definition error.h:96
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_INHERIT_FUNCTIONS(t)
Definition inherit.h:163
#define GWEN_INHERIT_INIT(t, element)
Definition inherit.h:223
#define GWEN_INHERIT_FINI(t, element)
Definition inherit.h:238
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466
#define GWEN_LOGDOMAIN
Definition logger.h:35
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
uint8_t GWEN_Msg_GetUint8At(const GWEN_MSG *msg, int offs, uint8_t defaultValue)
Definition msg.c:408
uint32_t GWEN_Msg_GetCurrentPos(const GWEN_MSG *msg)
Definition msg.c:172
int GWEN_Msg_AddBytes(GWEN_MSG *msg, const uint8_t *bufferPtr, uint32_t bufferLen)
Definition msg.c:189
void GWEN_Msg_AddFlags(GWEN_MSG *msg, uint32_t f)
Definition msg.c:318
void GWEN_Msg_SetParsedPayloadSize(GWEN_MSG *msg, uint32_t v)
Definition msg.c:276
GWEN_MSG * GWEN_Msg_dup(const GWEN_MSG *srcMsg)
Definition msg.c:91
int GWEN_Msg_GetRemainingBytes(const GWEN_MSG *msg)
Definition msg.c:258
void GWEN_Msg_Dump(const GWEN_MSG *msg, GWEN_BUFFER *buf)
Definition msg.c:423
uint32_t GWEN_Msg_GetMaxSize(const GWEN_MSG *msg)
Definition msg.c:165
int GWEN_Msg_IncCurrentPos(GWEN_MSG *msg, uint32_t i)
Definition msg.c:233
void GWEN_Msg_SetParsedPayloadOffset(GWEN_MSG *msg, uint32_t v)
Definition msg.c:293
uint64_t GWEN_Msg_GetUint64At(const GWEN_MSG *msg, int offs, uint64_t defaultValue)
Definition msg.c:354
void GWEN_Msg_DelFlags(GWEN_MSG *msg, uint32_t f)
Definition msg.c:326
GWEN_DB_NODE * GWEN_Msg_GetDbParsedInfo(const GWEN_MSG *msg)
Definition msg.c:334
int GWEN_Msg_ReadNextByte(GWEN_MSG *msg)
Definition msg.c:220
void GWEN_Msg_SetFlags(GWEN_MSG *msg, uint32_t f)
Definition msg.c:310
uint32_t GWEN_Msg_GetParsedPayloadSize(const GWEN_MSG *msg)
Definition msg.c:267
uint16_t GWEN_Msg_GetUint16At(const GWEN_MSG *msg, int offs, uint16_t defaultValue)
Definition msg.c:393
#define GWEN_MSG_SIZE_MASK
Definition msg.c:25
#define GWEN_MSG_SIZE_STEP
Definition msg.c:24
void GWEN_Msg_SetDbParsedInfo(GWEN_MSG *msg, GWEN_DB_NODE *db)
Definition msg.c:343
void GWEN_Msg_Attach(GWEN_MSG *msg)
Definition msg.c:66
void GWEN_Msg_SetBytesInBuffer(GWEN_MSG *msg, uint32_t i)
Definition msg.c:157
uint32_t GWEN_Msg_GetFlags(const GWEN_MSG *msg)
Definition msg.c:301
void GWEN_Msg_SetGroupId(GWEN_MSG *msg, int groupId)
Definition msg.c:122
uint32_t GWEN_Msg_GetParsedPayloadOffset(const GWEN_MSG *msg)
Definition msg.c:284
int GWEN_Msg_AddByte(GWEN_MSG *msg, uint8_t b)
Definition msg.c:182
uint32_t GWEN_Msg_GetBytesInBuffer(const GWEN_MSG *msg)
Definition msg.c:147
GWEN_MSG * GWEN_Msg_fromBytes(const uint8_t *ptr, uint32_t len)
Definition msg.c:50
int GWEN_Msg_GetGroupId(const GWEN_MSG *msg)
Definition msg.c:115
const uint8_t * GWEN_Msg_GetConstBuffer(const GWEN_MSG *msg)
Definition msg.c:138
uint32_t GWEN_Msg_GetUint32At(const GWEN_MSG *msg, int offs, uint32_t defaultValue)
Definition msg.c:378
uint8_t * GWEN_Msg_GetBuffer(GWEN_MSG *msg)
Definition msg.c:129
void GWEN_Msg_free(GWEN_MSG *msg)
Definition msg.c:74
GWEN_MSG * GWEN_Msg_new(uint32_t bufferSize)
Definition msg.c:33
int GWEN_Msg_RewindCurrentPos(GWEN_MSG *msg)
Definition msg.c:247
struct GWEN_MSG GWEN_MSG
Definition msg.h:25
void GWEN_Text_DumpString2Buffer(const char *s, unsigned int l, GWEN_BUFFER *mbuf, unsigned int insert)
Definition text.c:1324