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 
33 GWEN_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 
50 GWEN_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);
82  GWEN_FREE_OBJECT(msg);
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 
122 void 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 
138 const 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 
157 void GWEN_Msg_SetBytesInBuffer(GWEN_MSG *msg, uint32_t i)
158 {
159  if (msg && i<=msg->maxSize)
160  msg->bytesInBuffer=i;
161 }
162 
163 
164 
165 uint32_t GWEN_Msg_GetMaxSize(const GWEN_MSG *msg)
166 {
167  return msg?(msg->maxSize):0;
168 }
169 
170 
171 
172 uint32_t GWEN_Msg_GetCurrentPos(const GWEN_MSG *msg)
173 {
174  if (msg)
175  return msg->currentPos;
176  else
177  return 0;
178 }
179 
180 
181 
182 int GWEN_Msg_AddByte(GWEN_MSG *msg, uint8_t b)
183 {
184  return GWEN_Msg_AddBytes(msg, &b, 1);
185 }
186 
187 
188 
189 int 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");
204  return GWEN_ERROR_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 
233 int 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 
301 uint32_t GWEN_Msg_GetFlags(const GWEN_MSG *msg)
302 {
303  if (msg)
304  return msg->flags;
305  return 0;
306 }
307 
308 
309 
310 void GWEN_Msg_SetFlags(GWEN_MSG *msg, uint32_t f)
311 {
312  if (msg)
313  msg->flags=f;
314 }
315 
316 
317 
318 void GWEN_Msg_AddFlags(GWEN_MSG *msg, uint32_t f)
319 {
320  if (msg)
321  msg->flags|=f;
322 }
323 
324 
325 
326 void 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 
354 uint64_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 
378 uint32_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 
393 uint16_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 
408 uint8_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 
423 void 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 DBG_ERROR(dbg_logger, format,...)
Definition: debug.h:97
void GWEN_Msg_AddFlags(GWEN_MSG *msg, uint32_t f)
Definition: msg.c:318
int GWEN_Msg_IncCurrentPos(GWEN_MSG *msg, uint32_t i)
Definition: msg.c:233
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define GWEN_INHERIT_FINI(t, element)
Definition: inherit.h:238
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
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
uint32_t GWEN_Msg_GetMaxSize(const GWEN_MSG *msg)
Definition: msg.c:165
void GWEN_Msg_free(GWEN_MSG *msg)
Definition: msg.c:74
int GWEN_Msg_AddBytes(GWEN_MSG *msg, const uint8_t *bufferPtr, uint32_t bufferLen)
Definition: msg.c:189
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
uint32_t GWEN_Msg_GetFlags(const GWEN_MSG *msg)
Definition: msg.c:301
uint32_t GWEN_Msg_GetBytesInBuffer(const GWEN_MSG *msg)
Definition: msg.c:147
void GWEN_Msg_SetGroupId(GWEN_MSG *msg, int groupId)
Definition: msg.c:122
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWEN_Msg_RewindCurrentPos(GWEN_MSG *msg)
Definition: msg.c:247
#define GWEN_MSG_SIZE_STEP
Definition: msg.c:24
int GWEN_Msg_AddByte(GWEN_MSG *msg, uint8_t b)
Definition: msg.c:182
GWEN_MSG * GWEN_Msg_new(uint32_t bufferSize)
Definition: msg.c:33
void GWEN_Msg_SetFlags(GWEN_MSG *msg, uint32_t f)
Definition: msg.c:310
void GWEN_Text_DumpString2Buffer(const char *s, unsigned int l, GWEN_BUFFER *mbuf, unsigned int insert)
Definition: text.c:1324
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
uint32_t GWEN_Msg_GetParsedPayloadOffset(const GWEN_MSG *msg)
Definition: msg.c:284
void GWEN_Msg_SetParsedPayloadSize(GWEN_MSG *msg, uint32_t v)
Definition: msg.c:276
int GWEN_Buffer_AppendArgs(GWEN_BUFFER *bf, const char *fmt,...)
Definition: buffer.c:1087
#define GWEN_ERROR_GENERIC
Definition: error.h:62
uint16_t GWEN_Msg_GetUint16At(const GWEN_MSG *msg, int offs, uint16_t defaultValue)
Definition: msg.c:393
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
uint32_t GWEN_Msg_GetUint32At(const GWEN_MSG *msg, int offs, uint32_t defaultValue)
Definition: msg.c:378
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
int GWEN_Msg_GetGroupId(const GWEN_MSG *msg)
Definition: msg.c:115
uint32_t GWEN_Msg_GetCurrentPos(const GWEN_MSG *msg)
Definition: msg.c:172
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
void GWEN_Msg_Attach(GWEN_MSG *msg)
Definition: msg.c:66
void GWEN_Msg_SetDbParsedInfo(GWEN_MSG *msg, GWEN_DB_NODE *db)
Definition: msg.c:343
#define GWEN_ERROR_EOF
Definition: error.h:96
struct GWEN_MSG GWEN_MSG
Definition: msg.h:25
void GWEN_Msg_Dump(const GWEN_MSG *msg, GWEN_BUFFER *buf)
Definition: msg.c:423
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
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:466
int GWEN_Msg_ReadNextByte(GWEN_MSG *msg)
Definition: msg.c:220
uint8_t GWEN_Msg_GetUint8At(const GWEN_MSG *msg, int offs, uint8_t defaultValue)
Definition: msg.c:408
GWEN_DB_NODE * GWEN_Msg_GetDbParsedInfo(const GWEN_MSG *msg)
Definition: msg.c:334
void GWEN_Msg_SetBytesInBuffer(GWEN_MSG *msg, uint32_t i)
Definition: msg.c:157
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:367
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
uint32_t GWEN_Msg_GetParsedPayloadSize(const GWEN_MSG *msg)
Definition: msg.c:267
void GWEN_Msg_DelFlags(GWEN_MSG *msg, uint32_t f)
Definition: msg.c:326
uint8_t * GWEN_Msg_GetBuffer(GWEN_MSG *msg)
Definition: msg.c:129
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:475
#define GWEN_INHERIT_FUNCTIONS(t)
Definition: inherit.h:163
#define GWEN_ERROR_MEMORY_FULL
Definition: error.h:77
const uint8_t * GWEN_Msg_GetConstBuffer(const GWEN_MSG *msg)
Definition: msg.c:138
#define GWEN_MSG_SIZE_MASK
Definition: msg.c:25
GWEN_MSG * GWEN_Msg_fromBytes(const uint8_t *ptr, uint32_t len)
Definition: msg.c:50