|
|
@ -2,14 +2,14 @@
|
|
|
|
* Networking binary buffers pack/unpack library
|
|
|
|
* Networking binary buffers pack/unpack library
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
|
|
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
|
|
|
* (c) Alexander Vdolainen 2017 <alex@vapaa.xyz>
|
|
|
|
* (c) Alexander Vdolainen 2017, 2018 <alex@vapaa.xyz>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* libtbusd is free software: you can redistribute it and/or modify it
|
|
|
|
* libndbuf is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU Lesser General Public License as published
|
|
|
|
* under the terms of the GNU Lesser General Public License as published
|
|
|
|
* by the Free Software Foundation, either version 2.1 of the License, or
|
|
|
|
* by the Free Software Foundation, either version 2.1 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* libtbusd is distributed in the hope that it will be useful, but
|
|
|
|
* libndbuf is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU Lesser General Public License for more details.
|
|
|
|
* See the GNU Lesser General Public License for more details.
|
|
|
@ -420,8 +420,14 @@ uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *wi, uint32_t len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* parse */
|
|
|
|
/* parse */
|
|
|
|
|
|
|
|
#define __is_moless(x) ((x) & NDBUF_MOLS) ? 1 : 0
|
|
|
|
|
|
|
|
#define __is_usermo(x) ((x) & NDBUF_UCMO) ? 1 : 0
|
|
|
|
|
|
|
|
|
|
|
|
int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
register uint32_t fo = b->flags;
|
|
|
|
|
|
|
|
register uint32_t len;
|
|
|
|
|
|
|
|
uint32_t clen;
|
|
|
|
va_list ap_copy;
|
|
|
|
va_list ap_copy;
|
|
|
|
union {
|
|
|
|
union {
|
|
|
|
uint8_t *_u8;
|
|
|
|
uint8_t *_u8;
|
|
|
@ -433,7 +439,6 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
ndbuf_t **_rdb;
|
|
|
|
ndbuf_t **_rdb;
|
|
|
|
} d;
|
|
|
|
} d;
|
|
|
|
const char *t, *last;
|
|
|
|
const char *t, *last;
|
|
|
|
uint32_t len, clen;
|
|
|
|
|
|
|
|
int r, count;
|
|
|
|
int r, count;
|
|
|
|
|
|
|
|
|
|
|
|
va_copy(ap_copy, ap);
|
|
|
|
va_copy(ap_copy, ap);
|
|
|
@ -474,8 +479,15 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
r = -1;
|
|
|
|
r = -1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Document the following line in manpages %limits% */
|
|
|
|
if(clen > NDBUF_MAXLENGTH) goto __errrbread;
|
|
|
|
if(clen > NDBUF_MAXLENGTH) goto __errrbread;
|
|
|
|
if((*d._cstr = malloc(clen + sizeof(char))) == NULL) {
|
|
|
|
|
|
|
|
|
|
|
|
if(__is_moless(fo)) {
|
|
|
|
|
|
|
|
*d._cstr = b->raw + b->curr;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if(__is_usermo(fo)) *d._cstr = b->mop->alloc(clen + sizeof(char));
|
|
|
|
|
|
|
|
else *d._cstr = malloc(clen + sizeof(char));
|
|
|
|
|
|
|
|
if(*d._cstr == NULL) {
|
|
|
|
r = -ENOMEM;
|
|
|
|
r = -ENOMEM;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -486,6 +498,7 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*d._cstr)[len] = '\0';
|
|
|
|
(*d._cstr)[len] = '\0';
|
|
|
|
d._cstr = NULL;
|
|
|
|
d._cstr = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
r = 0;
|
|
|
|
r = 0;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
case 'p':
|
|
|
@ -495,7 +508,12 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
*d._dp = NULL;
|
|
|
|
*d._dp = NULL;
|
|
|
|
count++;
|
|
|
|
count++;
|
|
|
|
|
|
|
|
|
|
|
|
if((*d._dp = malloc(clen)) == NULL) {
|
|
|
|
if(__is_moless(fo)) {
|
|
|
|
|
|
|
|
*d._dp = b->raw + b->curr;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if(__is_usermo(fo)) *d._dp = b->mop->alloc(clen);
|
|
|
|
|
|
|
|
else *d._dp = malloc(clen);
|
|
|
|
|
|
|
|
if(*d._dp == NULL) {
|
|
|
|
r = -ENOMEM;
|
|
|
|
r = -ENOMEM;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -504,6 +522,7 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
free(*d._dp);
|
|
|
|
free(*d._dp);
|
|
|
|
goto __errrbread;
|
|
|
|
goto __errrbread;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
d._dp = NULL;
|
|
|
|
d._dp = NULL;
|
|
|
|
r = 0;
|
|
|
|
r = 0;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -516,7 +535,12 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
r = -1;
|
|
|
|
r = -1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if((*d._dp = malloc(clen)) == NULL) {
|
|
|
|
if(__is_moless(fo)) {
|
|
|
|
|
|
|
|
*d._dp = b->raw + b->curr;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if(__is_usermo(fo)) *d._dp = b->mop->alloc(clen);
|
|
|
|
|
|
|
|
else *d._dp = malloc(clen);
|
|
|
|
|
|
|
|
if(*d._dp == NULL) {
|
|
|
|
r = -ENOMEM;
|
|
|
|
r = -ENOMEM;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -525,10 +549,11 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
free(*d._dp);
|
|
|
|
free(*d._dp);
|
|
|
|
goto __errrbread;
|
|
|
|
goto __errrbread;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
d._dp = NULL;
|
|
|
|
d._dp = NULL;
|
|
|
|
r = 0;
|
|
|
|
r = 0;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
case 'R': /* FIXME: what about moless and user defined ops ? */
|
|
|
|
d._rdb = va_arg(ap, ndbuf_t **);
|
|
|
|
d._rdb = va_arg(ap, ndbuf_t **);
|
|
|
|
*d._rdb = NULL;
|
|
|
|
*d._rdb = NULL;
|
|
|
|
|
|
|
|
|
|
|
@ -579,10 +604,15 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
case 's':
|
|
|
|
d._cstr = va_arg(ap_copy, char **);
|
|
|
|
d._cstr = va_arg(ap_copy, char **);
|
|
|
|
if(*d._cstr) {
|
|
|
|
if(*d._cstr && !__is_moless(fo)) {
|
|
|
|
|
|
|
|
if(__is_usermo(fo)) {
|
|
|
|
|
|
|
|
b->mop->zero(*d._cstr, strlen(*d._cstr));
|
|
|
|
|
|
|
|
b->mop->free(*d._cstr);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
memset(*d._cstr, 0, strlen(*d._cstr));
|
|
|
|
memset(*d._cstr, 0, strlen(*d._cstr));
|
|
|
|
free(*d._cstr);
|
|
|
|
free(*d._cstr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
case 'R':
|
|
|
|
d._rdb = va_arg(ap_copy, ndbuf_t **);
|
|
|
|
d._rdb = va_arg(ap_copy, ndbuf_t **);
|
|
|
@ -592,7 +622,10 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
|
|
|
(void)va_arg(ap_copy, size_t);
|
|
|
|
(void)va_arg(ap_copy, size_t);
|
|
|
|
case 'P':
|
|
|
|
case 'P':
|
|
|
|
d._dp = va_arg(ap_copy, void **);
|
|
|
|
d._dp = va_arg(ap_copy, void **);
|
|
|
|
if(*d._dp) free(*d._dp);
|
|
|
|
if(*d._dp && !__is_moless(fo)) {
|
|
|
|
|
|
|
|
if(__is_usermo(fo)) b->mop->free(*d._dp);
|
|
|
|
|
|
|
|
else free(*d._dp);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
(void)va_arg(ap_copy, void *);
|
|
|
|
(void)va_arg(ap_copy, void *);
|
|
|
|