Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4850357dc4 | |||
| b07795a039 | |||
| 8ddcddf18f | |||
| 8c46b58783 | |||
| 6429f8b102 | |||
| 546667e837 | |||
| 1d37a8fbba | |||
| 3b5e72391f | |||
| c989ec05db | |||
| 1ff36de125 | |||
| 067cb2df5e | |||
| 39ac80efda | |||
| b5d07964dd | |||
| 07ea3de219 | |||
| 9332a57be2 | |||
| 1f684819a4 | |||
| b1d0950b71 | |||
| 6eea614d6c | |||
| 81756b45dd | |||
|
|
44f7aba37b | ||
|
|
68aa01d300 | ||
|
|
fb41052802 | ||
|
|
822146bf90 | ||
|
|
d0723c4a76 | ||
|
|
6451c66518 | ||
| baa1574746 | |||
| 0a9ff172a5 | |||
|
|
b6dba50071 | ||
|
|
81bfa9eecc |
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
0.0.2 (28-oct-2025)
|
||||
* Zero copying support
|
||||
* Read only buffer support
|
||||
* Manual pages
|
||||
* Packaging for linux
|
||||
* Added possibility to use user defined memory ops with:
|
||||
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *, const size_t);
|
||||
* Fixed bug with pkgconfig %VERSION% value
|
||||
|
||||
|
||||
0.0.1 (24-nov-2017)
|
||||
* initial version with all functions done
|
||||
* tired from reuse this code and ... now it's lib
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
## Sample for libndbuf automaken stuff
|
||||
## (c) alex@vapaa.xyz
|
||||
## Distributed under GNU LGPL v2.1 or later
|
||||
## Originally written by Alexander Vdolainen <alex@vapaa.xyz> (c) 2017
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = include
|
||||
SUBDIRS = include man
|
||||
|
||||
clean-local:
|
||||
|
||||
|
||||
46
README
46
README
@ -1,30 +1,28 @@
|
||||
libndbuf: Network designed buffer ops library
|
||||
----------------------------------------------
|
||||
libndbuf: Network-oriented buffer operations library
|
||||
----------------------------------------------------
|
||||
|
||||
1. What the shit is that ?
|
||||
This is a quite small library to manipulate with binary packed buffers
|
||||
in a normal network manner (i.e. bigendian). It might be useful to
|
||||
apply for network packet creating/parsing.
|
||||
Anyway, originally this code was resided in my different other *small*
|
||||
projects - and i hate copy-paste -- well, that's why it gone to
|
||||
this quite small library.
|
||||
1. What is it?
|
||||
A small C library providing a simple API to read and write typed values
|
||||
to/from buffers with correct endianness handling.
|
||||
|
||||
2. API
|
||||
Check out include directory...
|
||||
btw, might be later i will write manpages, but for now didn't see any
|
||||
sense for those effort.
|
||||
Generally speaking - all is quite simple - create ndbuf_t structure fill
|
||||
it in printf() style, read with sscanf() style, take raw data pointer and ...
|
||||
send it somewhere whatever bla bla - you get a point.
|
||||
2. Purpose
|
||||
Make parsing and building network packets easy and concise. The API is
|
||||
intended to act like a binary printf/scanf for packet fields.
|
||||
|
||||
Example:
|
||||
|
||||
Packet layout:
|
||||
<16-bit><8-bit><32-bit><raw data>
|
||||
|
||||
Reading with a single call:
|
||||
ndbuf_escan(buf, "wbdR", &a16, &a8, &a32, &data_ptr)
|
||||
|
||||
The same style is used to build packets.
|
||||
|
||||
3. Future plans
|
||||
Fix bugs (but ... there are no bugs found, since this code was heavly used
|
||||
already, but ... report me if found).
|
||||
Write manpages (in my few projects those API is like a part of POSIX -
|
||||
still cannot remember all).
|
||||
Maybe will add a new functions (useful ones).
|
||||
* Improve the API ergonomics (better support for preallocated buffers).
|
||||
* Add convenience helpers and safer bounds checks.
|
||||
* Possibly extend format specifiers and documentation.
|
||||
|
||||
4. Contact
|
||||
That's simple -
|
||||
Email/XMPP: alex@vapaa.xyz
|
||||
|
||||
Email: alex@vapaa.xyz
|
||||
|
||||
@ -16,4 +16,5 @@ AC_OUTPUT([
|
||||
Makefile
|
||||
libndbuf.pc
|
||||
include/Makefile
|
||||
man/Makefile
|
||||
])
|
||||
|
||||
@ -5,12 +5,12 @@
|
||||
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
||||
* (c) Alexander Vdolainen 2017 <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
|
||||
* by the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
@ -27,16 +27,33 @@
|
||||
|
||||
#define NDBUF_TERMINAT 0xdeadbeef
|
||||
|
||||
/* List of supported flags: */
|
||||
#define NDBUF_BURN (1 << 1) /* burn buffer data before free */
|
||||
#define NDBUF_NREA (1 << 2) /* non reallocatable buffer */
|
||||
#define NDBUF_UCMO (1 << 3) /* user defined memops functions */
|
||||
#define NDBUF_RORB (1 << 4) /* read-only buffer */
|
||||
#define NDBUF_MOLS (1 << 5) /* "memory-ops"-less escan i.e. return
|
||||
* pointers to the raw buffer itself,
|
||||
* instead of alloc/memcpy
|
||||
*/
|
||||
|
||||
struct ndbuf_memops {
|
||||
void *(*alloc)(size_t);
|
||||
uint32_t (*zero)(void *, size_t);
|
||||
void (*free)(void *ptr);
|
||||
};
|
||||
|
||||
typedef struct __rawdatabuffer_type {
|
||||
char *raw;
|
||||
union {
|
||||
void (*freebuf)(char *);
|
||||
const struct ndbuf_memops *mop;
|
||||
};
|
||||
uint32_t rlength; /* raw buffer allocated length */
|
||||
uint32_t ulength; /* length of used allocated space */
|
||||
uint32_t curr; /* cursor for read/write operations */
|
||||
int flags;
|
||||
void (*freebuf)(char *);
|
||||
size_t blk_size;
|
||||
uint32_t flags;
|
||||
} ndbuf_t;
|
||||
|
||||
/* variadic macro workaround */
|
||||
@ -67,12 +84,15 @@ typedef struct __rawdatabuffer_type {
|
||||
/* allocate raw buffer with defaults preallocation */
|
||||
ndbuf_t *ndbuf_new(void);
|
||||
|
||||
/* will do the same as ndbuf_new but will allocate given length */
|
||||
/* will do the same as ndbuf_new but will pre-allocate with the given length */
|
||||
ndbuf_t *ndbuf_new_palloc(uint32_t);
|
||||
|
||||
/* create ndbuf from raw buffer */
|
||||
ndbuf_t *ndbuf_new_frombuf(char *buf, size_t buf_len, void (*freebuf)(char *));
|
||||
|
||||
/* create a new buffer with user defined memops */
|
||||
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *, const size_t);
|
||||
|
||||
/* free all allocated space and buffer itself */
|
||||
void ndbuf_free(ndbuf_t *);
|
||||
|
||||
@ -137,15 +157,15 @@ void *ndbuf_rdata(ndbuf_t *);
|
||||
/* return pointer to the data currently being read/write */
|
||||
void *ndbuf_rdatacur(ndbuf_t *);
|
||||
|
||||
/* reset current pointer */
|
||||
void ndbuf_resetcur(ndbuf_t *);
|
||||
|
||||
/* set flags to the raw buffer */
|
||||
void ndbuf_setflags(ndbuf_t *, int);
|
||||
|
||||
/* exchange flags for raw buff */
|
||||
void ndbuf_exflags(ndbuf_t *, int);
|
||||
|
||||
/* reset current pointer */
|
||||
void ndbuf_resetcur(ndbuf_t *);
|
||||
|
||||
/* reset all the flags */
|
||||
#define ndbuf_flagsreset(a) ndbuf_exflags((a), 0)
|
||||
|
||||
@ -158,4 +178,7 @@ int ndbuf_cmp(ndbuf_t *, ndbuf_t *);
|
||||
*/
|
||||
int ndbuf_memopt(ndbuf_t *);
|
||||
|
||||
/* free in a right way: freing allocated memory during escan */
|
||||
void ndbuf_free_item(ndbuf_t *b, void *ip, size_t is);
|
||||
|
||||
#endif /* __NDBUF_H__ */
|
||||
|
||||
@ -7,7 +7,7 @@ includedir=@includedir@
|
||||
|
||||
Name: libndbuf
|
||||
Description: Network designed binary buffer pack/unpack library
|
||||
Version: @LIBNDBUF_VERSION@
|
||||
Version: @VERSION@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lndbuf
|
||||
Cflags: -I${includedir}
|
||||
|
||||
66
linux/libndbuf-9999.ebuild
Normal file
66
linux/libndbuf-9999.ebuild
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 1999-2025 Gentoo Authors
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
|
||||
EAPI=8
|
||||
|
||||
inherit git-r3 autotools toolchain-funcs
|
||||
|
||||
DESCRIPTION="Binary buffer helper library (libndbuf)"
|
||||
HOMEPAGE="https://vapaa.work/public/libndbuf"
|
||||
SRC_URI="git+https://vapaa.work/public/libndbuf.git"
|
||||
|
||||
LICENSE="LGPL-2.1-or-later"
|
||||
SLOT="0"
|
||||
KEYWORDS=""
|
||||
IUSE=""
|
||||
|
||||
# Adjust build/run deps as needed
|
||||
DEPEND="sys-devel/autoconf
|
||||
sys-devel/automake
|
||||
sys-devel/libtool
|
||||
sys-devel/make
|
||||
sys-devel/gcc
|
||||
sys-libs/glibc"
|
||||
RDEPEND=""
|
||||
|
||||
S="${WORKDIR}/git"
|
||||
|
||||
src_prepare() {
|
||||
default
|
||||
|
||||
# If the repo includes generated configure, skip autoreconf; otherwise run it.
|
||||
if ! [[ -x configure ]]; then
|
||||
einfo "Running autoreconf -fi"
|
||||
# regenerate configure and friends
|
||||
autoreconf -fi || die "autoreconf failed"
|
||||
fi
|
||||
# Ensure scripts are executable
|
||||
if [[ -f configure ]]; then
|
||||
chmod +x configure || die "chmod configure failed"
|
||||
fi
|
||||
}
|
||||
|
||||
src_configure() {
|
||||
econf \
|
||||
--prefix=/usr \
|
||||
--libdir=/usr/lib64 \
|
||||
--disable-static || die "configure failed"
|
||||
}
|
||||
|
||||
src_compile() {
|
||||
emake V=1 || die "make failed"
|
||||
}
|
||||
|
||||
src_install() {
|
||||
emake DESTDIR="${D}" install || die "make install failed"
|
||||
|
||||
# Ensure headers are in /usr/include and libs in /usr/lib
|
||||
# Remove any bundled or undesired files if necessary
|
||||
if [[ -d "${D}/usr/lib64/pkgconfig" ]]; then
|
||||
dodir /usr/lib64/pkgconfig
|
||||
fi
|
||||
}
|
||||
|
||||
pkg_postinst() {
|
||||
elog "libndbuf installed"
|
||||
}
|
||||
8
man/Makefile.am
Normal file
8
man/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
man_MANS = ndbuf_new.3 ndbuf_new_palloc.3 ndbuf_new_wmops.3 ndbuf_new_frombuf.3 \
|
||||
ndbuf_free.3 ndbuf_free_item.3 ndbuf_read_raw.3 ndbuf_read_u8.3 ndbuf_read_u16.3 \
|
||||
ndbuf_read_u32.3 ndbuf_read_u64.3 ndbuf_write_raw.3 ndbuf_write_u8.3 ndbuf_write_u16.3 \
|
||||
ndbuf_write_u32.3 ndbuf_write_u64.3 ndbuf_write_raw_head.3 ndbuf_escan.3 \
|
||||
ndbuf_escan_va.3 ndbuf_escan_wot.3 ndbuf_print.3 ndbuf_print_va.3 ndbuf_print_wot.3 \
|
||||
ndbuf_length.3 ndbuf_alength.3 ndbuf_leftlength.3 ndbuf_setlength.3 ndbuf_rdata.3 \
|
||||
ndbuf_rdatacur.3 ndbuf_resetcur.3 ndbuf_setflags.3 ndbuf_exflags.3 ndbuf_flagsreset.3
|
||||
|
||||
1
man/ndbuf_alength.3
Symbolic link
1
man/ndbuf_alength.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_length.3
|
||||
90
man/ndbuf_escan.3
Normal file
90
man/ndbuf_escan.3
Normal file
@ -0,0 +1,90 @@
|
||||
.TH NDBUF_ESCAN 3 "15 Septermber 2018" "NDBUF" "Binary buffers lib manual"
|
||||
.SH NAME
|
||||
ndbuf_escan, ndbuf_escan_va, ndbuf_escan_wot - parse formatted input from ndbuf
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <ndbuf/ndbuf.h>
|
||||
int ndbuf_escan(ndbuf_t *b, const char *fmt, ...);
|
||||
int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap);
|
||||
int ndbuf_escan_wot(ndbuf_t *b, const char *fmt, int argc, ...);
|
||||
|
||||
.nf
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
.SH DESCRIPTION
|
||||
The ndbuf_escan, ndbuf_escan_wot, ndbuf_escan_va functions scans data from the buffer referenced by b according to the format string fmt, using a pre-built va_list ap for supplying destination pointers. It behaves similarly to a vscanf-style formatted scanner but operates on an ndbuf_t source and supports the scanning features provided by the libndbuf scanning API.
|
||||
|
||||
The arguments are:
|
||||
.IP "\fBndbuf_t *b\fR"
|
||||
Pointer to an ndbuf buffer object from which data will be read.
|
||||
.IP "\fBconst char *fmt\fR"
|
||||
A null-terminated format string that describes the expected input and the conversion specifiers, following libndbuf's scanning conventions.
|
||||
.IP "\fBint argc\fR"
|
||||
The number of expected conversion fields (the number of destination pointers the format requires). This value is used by the implementation to validate or limit processing.
|
||||
.IP "\fBva_list ap\fR"
|
||||
An initialized variable argument list providing the destination pointers corresponding to the conversion specifiers in fmt.
|
||||
|
||||
.SH FORMAT SPECIFIERS
|
||||
The following conversion specifiers are recognized:
|
||||
.IP "\fBb\fR"
|
||||
8 bit unsigned integer. Argument: pointer to uint8_t (or unsigned char).
|
||||
.IP "\fBw\fR"
|
||||
16 bit unsigned integer. Argument: pointer to uint16_t.
|
||||
.IP "\fBd\fR"
|
||||
32 bit unsigned integer. Argument: pointer to uint32_t.
|
||||
.IP "\fBq\fR"
|
||||
64 bit unsigned integer. Argument: pointer to uint64_t.
|
||||
.IP "\fBs\fR"
|
||||
NULL terminated C string. Argument: pointer to char **. If the ndbuf has zero-copy (copyless) mode enabled, the function will set the pointer to point into the buffer's storage (no allocation). Otherwise the function allocates a new NUL-terminated buffer and copies the string; the caller must free that allocation with ndbuf_free_item when finished.
|
||||
.IP "\fBp\fR"
|
||||
Raw data with externally supplied length. Argument list: (size_t *) for length followed by (void **) pointer-to-pointer for data. If zero-copy is enabled, the data pointer is set to point into the buffer; otherwise a new allocation is made and must be freed with ndbuf_free_item.
|
||||
.IP "\fBP\fR"
|
||||
Length-prefixed raw data. The length is read from the ndbuf contents; the caller supplies a (void **) pointer-to-pointer to receive the data. Zero-copy behavior applies as with 'p'. Allocated data must be freed with ndbuf_free_item when appropriate.
|
||||
.IP "\fBR\fR"
|
||||
Will do the same as 'P', but instead of memory chunk a new ndbuf will be created with NDBUF_BURN flag set and all contents copied. Ignores zero copy flag.
|
||||
|
||||
|
||||
.SH RETURN VALUE
|
||||
On success, ndbuf_escan_va returns the number of input items successfully assigned. If a matching failure occurs before any conversions, it returns EOF (or a negative error code as used by the library). The exact error convention follows libndbuf's error reporting (see ERRORS).
|
||||
|
||||
.SH ERRORS
|
||||
The function may return:
|
||||
.TP
|
||||
.DL
|
||||
.B -1
|
||||
General failure or EOF encountered before any conversions.
|
||||
.TP
|
||||
.DL
|
||||
.B <argc
|
||||
Fewer items converted than requested; the return value indicates how many were converted.
|
||||
.PP
|
||||
Consult libndbuf's error codes and diagnostics for additional failure semantics; implementations may set internal error state on the ndbuf_t object.
|
||||
|
||||
.SH THREAD SAFETY
|
||||
Libndbuf doesn't provide any locking for ndbuf_t structure, so all those functions should be considered not thread safe. Developer should care about that with external locking primitives.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_print ,
|
||||
.BR ndbuf_new ,
|
||||
.BR ndbuf_setflags ,
|
||||
.BR ndbuf_free_item
|
||||
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
/* Example: parse two integers from an ndbuf /
|
||||
int a, b;
|
||||
va_list ap;
|
||||
va_start(ap, / in real use: this would be inside a variadic wrapper /);
|
||||
va_arg(ap, int ) = &a; /* illustrative only; use a proper variadic wrapper /
|
||||
va_arg(ap, int ) = &b;
|
||||
int ret = ndbuf_escan_va(mybuf, "%d %d", 2, ap);
|
||||
va_end(ap);
|
||||
.nf
|
||||
|
||||
|
||||
.SH COPYRIGHT
|
||||
This software licensed under GNU LGPL v2.1 or later. See COPYING for further details.
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 <http://vapaa.xyz>
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen (alex@vapaa.xyz)
|
||||
1
man/ndbuf_escan_va.3
Symbolic link
1
man/ndbuf_escan_va.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_escan.3
|
||||
1
man/ndbuf_escan_wot.3
Symbolic link
1
man/ndbuf_escan_wot.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_escan.3
|
||||
1
man/ndbuf_exflags.3
Symbolic link
1
man/ndbuf_exflags.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_setflags.3
|
||||
1
man/ndbuf_flagsreset.3
Symbolic link
1
man/ndbuf_flagsreset.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_setflags.3
|
||||
1
man/ndbuf_free.3
Symbolic link
1
man/ndbuf_free.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_new.3
|
||||
1
man/ndbuf_free_item.3
Symbolic link
1
man/ndbuf_free_item.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_new.3
|
||||
1
man/ndbuf_leftlength.3
Symbolic link
1
man/ndbuf_leftlength.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_length.3
|
||||
75
man/ndbuf_length.3
Normal file
75
man/ndbuf_length.3
Normal file
@ -0,0 +1,75 @@
|
||||
.TH NDBUF_LENGTH 3 "28 October 2021" "NDBUF" "Binary buffers library manual"
|
||||
|
||||
.SH NAME
|
||||
ndbuf_length, ndbuf_setlength, ndbuf_alength, ndbuf_leftlength - query and manipulate ndbuf buffer lengths
|
||||
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <ndbuf/ndbuf.h>
|
||||
|
||||
uint32_t ndbuf_length(ndbuf_t *b);
|
||||
int ndbuf_setlength(ndbuf_t *b, uint32_t len);
|
||||
uint32_t ndbuf_alength(ndbuf_t *b);
|
||||
uint32_t ndbuf_leftlength(ndbuf_t *b);
|
||||
.nf
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
These utility functions provide access to length and capacity information for an ndbuf_t buffer and allow controlled adjustment of the buffer's recorded used length.
|
||||
|
||||
.IP "\fBuint32_t ndbuf_length(ndbuf_t *b)\fR"
|
||||
Return the number of bytes currently used (occupied) in the buffer b. This represents the logical size of the data stored in the buffer and is the length that most read/scan operations consider valid.
|
||||
|
||||
.IP "\fBint ndbuf_setlength(ndbuf_t *b, uint32_t len)\fR"
|
||||
Set the buffer's used length to len. Valid usage depends on len being less than or equal to the allocated length (ndbuf_alength(b)). If len is greater than the allocated capacity, the function may fail (returning non‑zero) or trigger a reallocation depending on the library implementation. Typical return values:
|
||||
.TP
|
||||
.B 0
|
||||
Success; the used length was updated.
|
||||
.TP
|
||||
.B -1
|
||||
Failure; len is invalid (e.g., greater than allowed capacity) or an allocation/reallocation error occurred.
|
||||
|
||||
Setting length shorter than the previous value effectively truncates the logical content. Setting length larger than the previous value but within allocated capacity increases the logical size; the newly added bytes' contents are undefined and should be initialized by the caller if required.
|
||||
|
||||
.IP "\fBuint32_t ndbuf_alength(ndbuf_t *b)\fR"
|
||||
Return the allocated capacity (in bytes) of the buffer b. This is the total storage reserved for the buffer and is always greater than or equal to ndbuf_length(b). Use this value to determine whether appending additional data will require reallocation.
|
||||
|
||||
.IP "\fBuint32_t ndbuf_leftlength(ndbuf_t *b)\fR"
|
||||
Return the number of bytes available to read from the current read position to the end of the used data. This is equivalent to (ndbuf_length(b) - current_read_offset), and indicates how many readable bytes remain for scanning or extraction operations.
|
||||
|
||||
.SH RETURN VALUES
|
||||
|
||||
ndbuf_length, ndbuf_alength, ndbuf_leftlength: return unsigned 32-bit byte counts as described above.
|
||||
ndbuf_setlength: returns 0 on success; non-zero (commonly -1) on error.
|
||||
|
||||
.SH ERRORS AND VALIDATION
|
||||
Invalid operations or argument values may cause ndbuf_setlength to fail. Common failure causes:
|
||||
.TP
|
||||
.B len > ndbuf_alength(b)
|
||||
Requested used length exceeds buffer capacity (unless implementation grows buffer).
|
||||
.TP
|
||||
.B Allocation failure
|
||||
Attempt to grow buffer to satisfy len failed due to memory allocation error.
|
||||
.TP
|
||||
.B Invalid buffer pointer
|
||||
Passing NULL or an invalid ndbuf_t may produce undefined behavior or a failure return.
|
||||
|
||||
.SH EXAMPLE
|
||||
NONE.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_new(3) ,
|
||||
.BR ndbuf_print(3) ,
|
||||
.BR ndbuf_escan(3) ,
|
||||
.BR ndbuf_setflags(3)
|
||||
|
||||
.SH COPYRIGHT
|
||||
This software is licensed under the GNU Lesser General Public License version 2.1 or later. See the COPYING file in the project repository for full license text.
|
||||
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 (http://vapaa.xyz)
|
||||
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen <alex@vapaa.xyz>
|
||||
160
man/ndbuf_new.3
Normal file
160
man/ndbuf_new.3
Normal file
@ -0,0 +1,160 @@
|
||||
.TH NDBUF_NEW 3 "15 September 2018" "NDBUF" "Binary buffers lib manual"
|
||||
.SH NAME
|
||||
ndbuf_new, ndbuf_new_palloc, ndbuf_new_frombuf, ndbuf_new_wmops, ndbuf_free - allocate and free buffer structure
|
||||
.SH SYNOPSIS
|
||||
.B "#include <ndbuf/ndbuf.h>"
|
||||
.PP
|
||||
.nf
|
||||
ndbuf_t *ndbuf_new(void);
|
||||
ndbuf_t *ndbuf_new_palloc(uint32_t len);
|
||||
ndbuf_t *ndbuf_new_frombuf(char *buf, size_t buf_len,
|
||||
void (*freebuf)(char *));
|
||||
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *mops,
|
||||
const size_t block_size);
|
||||
void ndbuf_free(ndbuf_t *b);
|
||||
void ndbuf_free_item(ndbuf_t *b, void *item, size_t item_size);
|
||||
.PP
|
||||
struct ndbuf_memops {
|
||||
.br
|
||||
void *(*alloc)(size_t);
|
||||
.br
|
||||
uint32_t (*zero)(void *, size_t);
|
||||
.br
|
||||
void (*free)(void *);
|
||||
.br
|
||||
};
|
||||
.fi
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B ndbuf_new
|
||||
family of functions create and initialize an
|
||||
.B ndbuf_t
|
||||
structure using different allocation and memory-operation options. These routines simplify handling raw network-oriented buffers while providing hooks for custom memory management and secure wiping.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_new()
|
||||
Allocate and return a newly initialized
|
||||
.B ndbuf_t
|
||||
using library defaults. A default memory chunk is preallocated. No special flags are set.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_new_palloc(uint32_t len)
|
||||
Allocate and return a new
|
||||
.B ndbuf_t
|
||||
with an initial buffer of the specified length (in bytes). Other defaults apply; no special flags are set.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_new_frombuf(char *buf, size_t buf_len, void (*freebuf)(char *))
|
||||
Create a
|
||||
.B ndbuf_t
|
||||
that uses the provided buffer pointer
|
||||
.I buf
|
||||
of length
|
||||
.I buf_len
|
||||
as its underlying storage. If
|
||||
.I freebuf
|
||||
is a valid pointer to the function, it will be called to free the buffer when the ndbuf is destroyed. The returned ndbuf will have the
|
||||
.B NDBUF_NREA
|
||||
flag set, indicating the buffer is non-reallocatable. See
|
||||
.BR ndbuf_setflags(3)
|
||||
for flag details.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_new_wmops(const struct ndbuf_memops *mops, const size_t block_size)
|
||||
Create a
|
||||
.B ndbuf_t
|
||||
that uses the caller-provided memory-operation callbacks and a custom block size. The
|
||||
.I mops
|
||||
structure must provide the following function pointers:
|
||||
.IP
|
||||
.B alloc(size_t)
|
||||
Function to allocate a memory block of the given size.
|
||||
.IP
|
||||
.B zero(void *, size_t)
|
||||
Function to zero or overwrite a memory region; used when the
|
||||
.B NDBUF_BURN
|
||||
flag is set to securely erase memory.
|
||||
.IP
|
||||
.B free(void *)
|
||||
Free a previously allocated memory block.
|
||||
.IP
|
||||
No special flags are set by this call.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_free(ndbuf_t *b)
|
||||
Free the
|
||||
.I ndbuf_t
|
||||
structure and, unless prevented by flags or missing free callbacks, free the associated buffer data. The underlying buffer is not freed if:
|
||||
.IP
|
||||
The
|
||||
.B NDBUF_NREA
|
||||
flag is set and no
|
||||
.I freebuf
|
||||
callback was provided in
|
||||
.B ndbuf_new_frombuf().
|
||||
.IP
|
||||
The
|
||||
.B NDBUF_RORB
|
||||
flag is set.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B ndbuf_free_item(ndbuf_t *b, void item, size_t item_size)
|
||||
Free an item previously allocated via the library's escan function. If the
|
||||
.B NDBUF_BURN
|
||||
flag is set and
|
||||
.I item_size
|
||||
is non-zero, the buffer will be securely zeroed (via
|
||||
.B zero()
|
||||
or
|
||||
.B memset()
|
||||
) before being freed. This function uses the default memory ops unless custom ops were provided at creation.
|
||||
.SH RETURN VALUE
|
||||
On success the
|
||||
.B ndbuf_new
|
||||
family of functions returns a pointer to the newly created
|
||||
.B ndbuf_t.
|
||||
On failure they return
|
||||
.B NULL.
|
||||
No specific
|
||||
.I errno
|
||||
value is set by these functions.
|
||||
.SH ERRORS
|
||||
These functions return NULL on allocation or initialization failure. Callers should check the return value before use.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
.nf
|
||||
/ Create a default buffer */
|
||||
ndbuf_t *b = ndbuf_new();
|
||||
if (!b) { / handle error */ }
|
||||
|
||||
/* Create buffer from existing memory */
|
||||
char *buf = malloc(256);
|
||||
ndbuf_t *b2 = ndbuf_new_frombuf(buf, 256, free);
|
||||
|
||||
/* Create buffer with custom memory ops */
|
||||
struct ndbuf_memops mops = { custom_alloc, custom_zero, custom_free };
|
||||
ndbuf_t *b3 = ndbuf_new_wmops(&mops, 4096);
|
||||
.fi
|
||||
.SH RATIONALE
|
||||
The
|
||||
.B ndbuf_new_wmops()
|
||||
function is useful for environments requiring special memory handling (for example, preventing pages from being swapped, using locked memory, or providing a custom zeroing routine to avoid compiler optimizations).
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_setflags(3),
|
||||
.BR ndbuf_escan(3)
|
||||
.SH COPYRIGHT
|
||||
This software licensed under GNU LGPL v2.1 or later. See COPYING for further details.
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 <http://vapaa.xyz>
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen (alex@vapaa.xyz)
|
||||
1
man/ndbuf_new_frombuf.3
Symbolic link
1
man/ndbuf_new_frombuf.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_new.3
|
||||
1
man/ndbuf_new_palloc.3
Symbolic link
1
man/ndbuf_new_palloc.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_new.3
|
||||
1
man/ndbuf_new_wmops.3
Symbolic link
1
man/ndbuf_new_wmops.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_new.3
|
||||
119
man/ndbuf_print.3
Normal file
119
man/ndbuf_print.3
Normal file
@ -0,0 +1,119 @@
|
||||
.TH NDBUF_PRINT 3 "28 October 2025" "NDBUF" "Binary buffers library manual"
|
||||
|
||||
.SH NAME
|
||||
ndbuf_print, ndbuf_print_va, ndbuf_print_wot - format and append data into an ndbuf
|
||||
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <ndbuf/ndbuf.h>
|
||||
|
||||
uint32_t ndbuf_print_va(ndbuf_t *b, const char *fmt, int argc, va_list ap);
|
||||
uint32_t ndbuf_print_wot(ndbuf_t *b, const char *fmt, int argc, ...);
|
||||
|
||||
uint32_t ndbuf_print(b, fmt, ...);
|
||||
.nf
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
The ndbuf_print family formats values according to fmt and appends the resulting representation into the buffer b. These functions are the counterpart to the ndbuf_escan scanning APIs and support libndbuf's format specifiers for binary-safe and textual output.
|
||||
|
||||
ndbuf_print_va: accepts a pre-initialized va_list (ap) and an explicit argument count (argc).
|
||||
ndbuf_print_wot: variadic form taking an explicit argc followed by the argument list.
|
||||
ndbuf_print: convenience macro that computes argc from the variadic arguments and appends the NDBUF_TERMINAT sentinel.
|
||||
|
||||
The functions write to the provided ndbuf_t, growing it as necessary. They respect buffer flags that affect allocation and zero-copy behavior where applicable.
|
||||
|
||||
.IP "\fBndbuf_t *b\fR"
|
||||
Target buffer to which formatted output will be appended.
|
||||
|
||||
.IP "\fBconst char *fmt\fR"
|
||||
Null-terminated format string describing how to format the provided arguments. Specifiers follow libndbuf conventions (see FORMAT SPECIFIERS).
|
||||
|
||||
.IP "\fBint argc\fR"
|
||||
Number of values supplied in the argument list (number of conversion fields fmt expects).
|
||||
|
||||
.IP "\fBva_list ap\fR"
|
||||
Initialized variable argument list supplying source values for ndbuf_print_va.
|
||||
|
||||
.SH FORMAT SPECIFIERS
|
||||
The following conversion specifiers are recognized for printing:
|
||||
|
||||
.IP "\fBb\fR"
|
||||
8-bit unsigned integer. Argument: integer promotable to uint8_t.
|
||||
|
||||
.IP "\fBw\fR"
|
||||
16-bit unsigned integer. Argument: integer promotable to uint16_t.
|
||||
|
||||
.IP "\fBd\fR"
|
||||
32-bit unsigned integer. Argument: integer promotable to uint32_t.
|
||||
|
||||
.IP "\fBq\fR"
|
||||
64-bit unsigned integer. Argument: integer promotable to uint64_t.
|
||||
|
||||
.IP "\fBs\fR"
|
||||
NULL-terminated C string. Argument: const char *. The string bytes are appended (excluding the terminating NUL) and — depending on buffer flags — may be copied or referenced via zero-copy mechanisms.
|
||||
|
||||
.IP "\fBp\fR"
|
||||
Raw data with externally supplied length. Argument list: (size_t) length followed by (const void *) data pointer. The specified number of bytes are appended.
|
||||
|
||||
.IP "\fBP\fR"
|
||||
Length-prefixed raw data. Argument: a pointer to a length/value pair is not required; the format string indicates that the function should write the length followed by the data bytes from a supplied pointer (the exact calling convention mirrors the scanning 'P' semantics — see libndbuf source for precise ordering).
|
||||
|
||||
.IP "\fBR\fR"
|
||||
Append an ndbuf slice (argument: ndbuf_t *). The target buffer will incorporate the source buffer contents according to copy/zero-copy semantics and flags; if necessary, data will be copied.
|
||||
|
||||
.SH RETURN VALUE
|
||||
On success, the functions return the number of bytes appended to the buffer (a uint32_t). On failure (allocation error, invalid arguments, or other internal errors) the function returns 0;
|
||||
|
||||
.SH ERRORS
|
||||
Possible failure conditions include:
|
||||
.TP
|
||||
.B 0
|
||||
Indicates an error prevented appending data (allocation failure, malformed format/arguments, or other runtime error). Partial writes are not guaranteed; callers should verify buffer state if 0 is returned.
|
||||
.PP
|
||||
For detailed error reporting, inspect the ndbuf_t error state or enable library diagnostics. Refer to the libndbuf source for implementation-specific error codes.
|
||||
|
||||
.SH USAGE NOTES
|
||||
|
||||
The ndbuf_print macro automatically supplies a terminator (NDBUF_TERMINAT) and computes argc using the compiler's VA_NARG helper; ensure the variadic argument list and fmt are consistent.
|
||||
Thread safety: concurrent modification of the same ndbuf_t without external synchronization is unsafe unless documented otherwise.
|
||||
|
||||
.SH EXAMPLES
|
||||
.nf
|
||||
/* Example: append two 32-bit integers and a string */
|
||||
uint32_t a = 42, b = 100;
|
||||
const char s = "hello";
|
||||
ndbuf_print(buf, "%d %d %s", a, b, s); /* macro computes argc and appends data */
|
||||
|
||||
/* Example: using va_list variant (caller prepares va_list) */
|
||||
#include <stdarg.h>
|
||||
|
||||
uint32_t print_with_va(ndbuf_t *buf, const char fmt, ...)
|
||||
{
|
||||
uint32_t written;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
/* In real use, convert or count args appropriately before calling ndbuf_print_va */
|
||||
written = ndbuf_print_va(buf, fmt, /*argc*/ 3, ap);
|
||||
va_end(ap);
|
||||
return written;
|
||||
}
|
||||
.nf
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_escan(3) ,
|
||||
.BR ndbuf_escan_va(3) ,
|
||||
.BR ndbuf_new(3) ,
|
||||
.BR ndbuf_setflags(3) ,
|
||||
.BR ndbuf_free_item(3)
|
||||
|
||||
.SH COPYRIGHT
|
||||
This software is licensed under the GNU Lesser General Public License version 2.1 or later. See the COPYING file in the project repository for full license text.
|
||||
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 <http://vapaa.xyz>
|
||||
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen (alex@vapaa.xyz)
|
||||
1
man/ndbuf_print_va.3
Symbolic link
1
man/ndbuf_print_va.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_print.3
|
||||
1
man/ndbuf_print_wot.3
Symbolic link
1
man/ndbuf_print_wot.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_print.3
|
||||
60
man/ndbuf_rdata.3
Normal file
60
man/ndbuf_rdata.3
Normal file
@ -0,0 +1,60 @@
|
||||
.TH NDBUF_RDATA 3 "28 October 2021" "NDBUF" "Binary buffers library manual"
|
||||
|
||||
.SH NAME
|
||||
ndbuf_rdata, ndbuf_rdatacur, ndbuf_resetcur - access and control the current data pointer in an ndbuf
|
||||
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <ndbuf/ndbuf.h>
|
||||
|
||||
void *ndbuf_rdata(ndbuf_t *b);
|
||||
void *ndbuf_rdatacur(ndbuf_t *b);
|
||||
void ndbuf_resetcur(ndbuf_t *b);
|
||||
.nf
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
These functions provide direct access to the buffer storage and to the buffer's current read/write cursor within an ndbuf_t instance, and allow resetting that cursor.
|
||||
|
||||
.IP "\fBvoid *ndbuf_rdata(ndbuf_t *b)\fR"
|
||||
Return a pointer to the start of the buffer's raw data storage. The returned pointer refers to the internal storage area that holds the buffer's contents. The pointer remains valid until the buffer is reallocated, freed, or otherwise mutated in a way that changes its storage location.
|
||||
|
||||
.IP "\fBvoid *ndbuf_rdatacur(ndbuf_t *b)\fR"
|
||||
Return a pointer to the current read/write position within the buffer (the "current" cursor). This pointer equals (ndbuf_rdata(b) + current_offset) where current_offset is the buffer's internal read/write offset. Use this pointer to read from or write to the buffer at the current cursor position; after writing directly to this location the caller should update the logical used length with ndbuf_setlength if bytes were appended.
|
||||
|
||||
.IP "\fBvoid ndbuf_resetcur(ndbuf_t *b)\fR"
|
||||
Reset the buffer's current read/write cursor to the start of the buffer (offset zero). This sets the current cursor so subsequent read or scan operations begin from the buffer start. Does not modify the buffer's used length; it only changes the read/write position.
|
||||
|
||||
.SH RETURN VALUES AND BEHAVIOR
|
||||
|
||||
ndbuf_rdata and ndbuf_rdatacur return NULL if b is NULL or if the buffer has no allocated storage.
|
||||
ndbuf_rdatacur reflects the buffer's current internal cursor; reading beyond the used length leads to undefined behavior unless the caller ensures sufficient data via ndbuf_length/ndbuf_leftlength checks.
|
||||
ndbuf_resetcur returns no value; it unconditionally sets the cursor to the buffer start (or to a defined initial state).
|
||||
|
||||
.SH SAFETY AND OWNERSHIP
|
||||
|
||||
The returned pointers reference internal buffer storage. Do not free or persist them beyond the lifetime of the ndbuf_t or across operations that may reallocate the buffer.
|
||||
Direct writes into the buffer's storage bypass internal bookkeeping; after performing writes that extend used data, callers must call ndbuf_setlength to update the logical length.
|
||||
Respect buffer flags (e.g., read-only or zero-copy semantics) and do not modify storage when prohibited.
|
||||
|
||||
.SH THREAD SAFETY
|
||||
Concurrent access to the same ndbuf_t without external synchronization is unsafe. Use locks when multiple threads may read/write the buffer and its cursor.
|
||||
|
||||
.SH EXAMPLES
|
||||
NONE
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_length(3) ,
|
||||
.BR ndbuf_setlength(3) ,
|
||||
.BR ndbuf_leftlength(3)
|
||||
|
||||
.SH COPYRIGHT
|
||||
This software is licensed under the GNU Lesser General Public License version 2.1 or later. See the COPYING file in the project repository for full license text.
|
||||
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 (http://vapaa.xyz)
|
||||
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen <alex@vapaa.xyz>
|
||||
1
man/ndbuf_rdatacur.3
Symbolic link
1
man/ndbuf_rdatacur.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_rdata.3
|
||||
96
man/ndbuf_read_raw.3
Normal file
96
man/ndbuf_read_raw.3
Normal file
@ -0,0 +1,96 @@
|
||||
.TH NDBUF_READ_RAW 3 "15 September 2018" "NDBUF" "Binary buffers lib manual"
|
||||
.SH NAME
|
||||
ndbuf_read_u8, ndbuf_read_u16, ndbuf_read_u32, ndbuf_read_u64,
|
||||
ndbuf_read_raw - read data of specified length and type
|
||||
.SH SYNOPSIS
|
||||
.B "#include <ndbuf/ndbuf.h>"
|
||||
.PP
|
||||
.nf
|
||||
uint32_t ndbuf_read_u8(ndbuf_t *b, uint8_t *val);
|
||||
uint32_t ndbuf_read_u16(ndbuf_t *b, uint16_t *val);
|
||||
uint32_t ndbuf_read_u32(ndbuf_t *b, uint32_t *val);
|
||||
uint32_t ndbuf_read_u64(ndbuf_t *b, uint64_t *val);
|
||||
uint32_t ndbuf_read_raw(ndbuf_t *b, void *dst, uint32_t len);
|
||||
.fi
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
The ndbuf_read_ family copies data from an
|
||||
.B ndbuf_t
|
||||
instance into caller-provided storage. On success each function returns the number of bytes read; on error it returns 0.
|
||||
|
||||
.TP
|
||||
.B ndbuf_read_u8(ndbuf_t *b, uint8_t *val)
|
||||
Read one unsigned 8‑bit value from the current buffer position into
|
||||
.I val
|
||||
and advance the buffer cursor by one byte. Returned value is the number of bytes read (1) or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_read_u16(ndbuf_t *b, uint16_t *val)
|
||||
Read one unsigned 16‑bit value, store it into
|
||||
.I val
|
||||
and advance the cursor by two bytes. Returns 2 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_read_u32(ndbuf_t *b, uint32_t *val)
|
||||
Read one unsigned 32‑bit value, store into
|
||||
.I val
|
||||
and advance the cursor by four bytes. Returns 4 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_read_u64(ndbuf_t *b, uint64_t *val)
|
||||
Read one unsigned 64‑bit value, store into
|
||||
.I val
|
||||
and advance the cursor by eight bytes. Returns 8 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_read_raw(ndbuf_t *b, void *dst, uint32_t len)
|
||||
Copy
|
||||
.I len
|
||||
bytes of raw data from the buffer to
|
||||
.I dst
|
||||
and advance the cursor by
|
||||
.I len. The caller must ensure
|
||||
.I dst
|
||||
points to memory at least
|
||||
.I len
|
||||
bytes long. Returns the number of bytes copied or 0 on error.
|
||||
.SH RETURN VALUE
|
||||
On success each function returns the number of bytes read. On error they return 0; no specific
|
||||
.I errno
|
||||
value is set.
|
||||
.SH ERRORS
|
||||
Functions return 0 when the requested read would exceed the available data, when
|
||||
.I b
|
||||
is NULL, or on other internal errors. Callers must validate the return value before using output data.
|
||||
.SH RATIONALE
|
||||
Use these functions when you need a local copy of numeric or raw data. For zero-copy parsing or formatted
|
||||
extraction consider the
|
||||
.BR ndbuf_escan(3)
|
||||
family instead.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
.nf
|
||||
/* Read values from buffer */
|
||||
uint8_t a8;
|
||||
uint16_t a16;
|
||||
uint32_t a32;
|
||||
if (ndbuf_read_u8(b, &a8) != 1) { /* handle error */ }
|
||||
if (ndbuf_read_u16(b, &a16) != 2) { /* handle error */ }
|
||||
if (ndbuf_read_u32(b, &a32) != 4) { /* handle error */ }
|
||||
|
||||
/* Read raw payload */
|
||||
char payload[128];
|
||||
if (ndbuf_read_raw(b, payload, sizeof(payload)) != sizeof(payload)) { /* handle error */ }
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_write_raw(3),
|
||||
.BR ndbuf_escan(3)
|
||||
.SH COPYRIGHT
|
||||
This software licensed under GNU LGPL v2.1 or later. See COPYING for further details.
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 <http://vapaa.xyz>
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen (alex@vapaa.xyz)
|
||||
1
man/ndbuf_read_u16.3
Symbolic link
1
man/ndbuf_read_u16.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_read_raw.3
|
||||
1
man/ndbuf_read_u32.3
Symbolic link
1
man/ndbuf_read_u32.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_read_raw.3
|
||||
1
man/ndbuf_read_u64.3
Symbolic link
1
man/ndbuf_read_u64.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_read_raw.3
|
||||
1
man/ndbuf_read_u8.3
Symbolic link
1
man/ndbuf_read_u8.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_read_raw.3
|
||||
1
man/ndbuf_resetcur.3
Symbolic link
1
man/ndbuf_resetcur.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_rdata.3
|
||||
83
man/ndbuf_setflags.3
Normal file
83
man/ndbuf_setflags.3
Normal file
@ -0,0 +1,83 @@
|
||||
.TH NDBUF_SETFLAGS 3 "28 October 2021" "NDBUF" "Binary buffers library manual"
|
||||
|
||||
.SH NAME
|
||||
ndbuf_setflags, ndbuf_exflags, ndbuf_flagsreset - manage flags controlling ndbuf behaviour
|
||||
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <ndbuf/ndbuf.h>
|
||||
|
||||
void ndbuf_setflags(ndbuf_t *b, int flags);
|
||||
void ndbuf_exflags(ndbuf_t *b, int flags);
|
||||
|
||||
#define ndbuf_flagsreset(a) ndbuf_exflags((a), 0)
|
||||
.nf
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
These functions manipulate the flags associated with an ndbuf_t instance. Flags control behavioural aspects such as zero-copy/copyless operation, burn semantics, read/write permissions, and other implementation-specific options. See SUPPORTED FLAGS.
|
||||
|
||||
.IP "\fBvoid ndbuf_setflags(ndbuf_t *b, int flags)\fR"
|
||||
Set the buffer's flags to the provided flags value. This replaces the current flag set with flags. Use this when you want to explicitly assign a new flags mask.
|
||||
|
||||
.IP "\fBvoid ndbuf_exflags(ndbuf_t *b, int flags)\fR"
|
||||
Exchange (apply) flags with the buffer; semantics are implementation-dependent but commonly used to modify or merge flags. In libndbuf this function is used to set flags while optionally returning or replacing previous flags state (check the header/source for exact behavior). Typically exflags will update the buffer's flags to flags; callers expecting previous flags should obtain them via the appropriate accessor if available.
|
||||
|
||||
.IP "\fB#define ndbuf_flagsreset(a) ndbuf_exflags((a), 0)\fR"
|
||||
Reset all flags on the buffer by calling ndbuf_exflags with 0. This macro provides a convenient way to clear all flag bits.
|
||||
|
||||
.SH SUPPORTED FLAGS
|
||||
.IP "\fBNDBUF_BURN\fR"
|
||||
Burn data before freeing.
|
||||
|
||||
.IP "\fBNDBUF_NREA\fR"
|
||||
Make the data buffer non-reallocatable.
|
||||
|
||||
.IP "\fBNDBUF_UCMD\fR"
|
||||
Buffer with custom memory operations provided.
|
||||
|
||||
.IP "\fBNDBUF_RORB\fR"
|
||||
Buffer is read-only.
|
||||
|
||||
.IP "\fBNDBUF_MOLS\fR"
|
||||
Zero-copy buffer.
|
||||
|
||||
|
||||
.SH BEHAVIOR AND USAGE NOTES
|
||||
|
||||
Flags are implementation-defined bitmasks; use only the constants defined by libndbuf.
|
||||
Changing flags can affect memory ownership and lifetime semantics (for example, toggling zero-copy/copyless may change whether returned pointers reference internal storage or newly allocated memory). Ensure callers understand implications before changing flags on a buffer containing live data.
|
||||
These functions do not allocate memory themselves. However, changing flags that affect ownership semantics may influence subsequent operations that allocate or free memory.
|
||||
There is no return value; error conditions (if any) are reported via ndbuf_t state or other library diagnostics. Passing a NULL pointer yields undefined behavior.
|
||||
|
||||
.SH THREAD SAFETY
|
||||
Concurrent modification of flags on the same ndbuf_t without external synchronization is unsafe. Use appropriate locking when multiple threads may read or modify flags.
|
||||
|
||||
.SH EXAMPLES
|
||||
.nf
|
||||
/* Set buffer to copyless (zero-copy) and burn mode */
|
||||
ndbuf_setflags(buf, NDBUF_MOLS | NDBUF_BURN);
|
||||
|
||||
/* Clear all flags */
|
||||
ndbuf_flagsreset(buf);
|
||||
|
||||
/* Exchange flags - set read-only */
|
||||
ndbuf_exflags(buf, NDBUF_RORB);
|
||||
.nf
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_new(3) ,
|
||||
.BR ndbuf_free_item(3) ,
|
||||
.BR ndbuf_escan(3) ,
|
||||
.BR ndbuf_print(3)
|
||||
|
||||
.SH COPYRIGHT
|
||||
This software is licensed under the GNU Lesser General Public License version 2.1 or later. See the COPYING file in the project repository for full license text.
|
||||
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 (http://vapaa.xyz)
|
||||
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen <alex@vapaa.xyz>
|
||||
1
man/ndbuf_setlength.3
Symbolic link
1
man/ndbuf_setlength.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_length.3
|
||||
94
man/ndbuf_write_raw.3
Normal file
94
man/ndbuf_write_raw.3
Normal file
@ -0,0 +1,94 @@
|
||||
.TH NDBUF_WRITE_RAW 3 "15 September 2018" "NDBUF" "Binary buffers lib manual"
|
||||
.SH NAME
|
||||
ndbuf_write_u8, ndbuf_write_u16, ndbuf_write_u32, ndbuf_write_u64,
|
||||
ndbuf_write_raw - write data to the buffer of specified length and type
|
||||
.SH SYNOPSIS
|
||||
.B "#include <ndbuf/ndbuf.h>"
|
||||
.PP
|
||||
.nf
|
||||
uint32_t ndbuf_write_u8(ndbuf_t *b, uint8_t val);
|
||||
uint32_t ndbuf_write_u16(ndbuf_t *b, uint16_t val);
|
||||
uint32_t ndbuf_write_u32(ndbuf_t *b, uint32_t val);
|
||||
uint32_t ndbuf_write_u64(ndbuf_t *b, uint64_t val);
|
||||
uint32_t ndbuf_write_raw(ndbuf_t *b, void *src, uint32_t len);
|
||||
uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *src, uint32_t len);
|
||||
.fi
|
||||
|
||||
.SH LIBRARY
|
||||
libndbuf
|
||||
|
||||
.SH DESCRIPTION
|
||||
The ndbuf_write_ family writes data to an
|
||||
.B ndbuf_t
|
||||
instance from caller-provided storage. On success each function returns the number of bytes written; on error it returns 0.
|
||||
|
||||
.TP
|
||||
.B ndbuf_write_u8(ndbuf_t *b, uint8_t val)
|
||||
Write one unsigned 8‑bit value to the current buffer position from
|
||||
.I val
|
||||
and advance the buffer cursor by one byte. Returned value is the number of bytes written (1) or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_write_u16(ndbuf_t *b, uint16_t val)
|
||||
Writes one unsigned 16‑bit value, from
|
||||
.I val
|
||||
and advance the cursor by two bytes. Returns 2 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_write_u32(ndbuf_t *b, uint32_t val)
|
||||
Write one unsigned 32‑bit value, from
|
||||
.I val
|
||||
and advance the cursor by four bytes. Returns 4 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_write_u64(ndbuf_t *b, uint64_t val)
|
||||
Write one unsigned 64‑bit value, from
|
||||
.I val
|
||||
and advance the cursor by eight bytes. Returns 8 on success or 0 on error.
|
||||
|
||||
.TP
|
||||
.B ndbuf_write_raw(ndbuf_t *b, void *src, uint32_t len)
|
||||
Copy
|
||||
.I len
|
||||
from
|
||||
.I src
|
||||
to the buffer and advance the cursor by
|
||||
.I len. The caller must ensure
|
||||
.I src
|
||||
points to memory at least
|
||||
.I len
|
||||
bytes long. Returns the number of bytes copied or 0 on error.
|
||||
.TP
|
||||
.B ndbuf_write_raw_head(ndbuf_t *b, void *src, uint32_t len)
|
||||
Copy
|
||||
.I len
|
||||
from
|
||||
.I src
|
||||
to the buffer head. The caller must ensure
|
||||
.I src
|
||||
points to memory at least
|
||||
.I len
|
||||
bytes long. Returns the number of bytes copied or 0 on error.
|
||||
|
||||
.SH RETURN VALUE
|
||||
On success each function returns the number of bytes read. On error they return 0; no specific
|
||||
.I errno
|
||||
value is set.
|
||||
.SH ERRORS
|
||||
Functions return 0 when the requested read would exceed the available data, when
|
||||
.I b
|
||||
is NULL, or on other internal errors. Callers must validate the return value before using output data.
|
||||
.SH RATIONALE
|
||||
None
|
||||
.SH EXAMPLES
|
||||
None
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
.BR ndbuf_read_raw(3),
|
||||
.BR ndbuf_print(3)
|
||||
.SH COPYRIGHT
|
||||
This software licensed under GNU LGPL v2.1 or later. See COPYING for further details.
|
||||
.PP
|
||||
(c) Authors of libndbuf 2017-2018 <http://vapaa.xyz>
|
||||
.SH AUTHOR
|
||||
Alexander Vdolainen (alex@vapaa.xyz)
|
||||
1
man/ndbuf_write_raw_head.3
Symbolic link
1
man/ndbuf_write_raw_head.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_write_raw.3
|
||||
1
man/ndbuf_write_u16.3
Symbolic link
1
man/ndbuf_write_u16.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_write_raw.3
|
||||
1
man/ndbuf_write_u32.3
Symbolic link
1
man/ndbuf_write_u32.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_write_raw.3
|
||||
1
man/ndbuf_write_u64.3
Symbolic link
1
man/ndbuf_write_u64.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_write_raw.3
|
||||
1
man/ndbuf_write_u8.3
Symbolic link
1
man/ndbuf_write_u8.3
Symbolic link
@ -0,0 +1 @@
|
||||
ndbuf_write_raw.3
|
||||
285
ndbuf.c
285
ndbuf.c
@ -2,14 +2,14 @@
|
||||
* Networking binary buffers pack/unpack library
|
||||
*
|
||||
* (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
|
||||
* by the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
@ -34,7 +34,7 @@ static inline uint64_t ntohll(uint64_t n)
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
return n;
|
||||
#else /* WORDS_BIGENDIAN */
|
||||
return (((uint64_t)(n) << 56) | \
|
||||
return (uint64_t)(((uint64_t)(n) << 56) | \
|
||||
(((uint64_t)(n) << 40) & 0xff000000000000ULL) | \
|
||||
(((uint64_t)(n) << 24) & 0xff0000000000ULL) | \
|
||||
(((uint64_t)(n) << 8) & 0xff00000000ULL) | \
|
||||
@ -78,7 +78,8 @@ ndbuf_t *ndbuf_new_frombuf(char *buf, size_t buf_len, void (*freebuf)(char *))
|
||||
|
||||
/* init buffer */
|
||||
b->raw = buf;
|
||||
b->rlength = b->ulength = buf_len;
|
||||
b->rlength = buf_len;
|
||||
b->ulength = 0; /* assume it's not used */
|
||||
b->flags = b->curr = 0;
|
||||
b->freebuf = freebuf;
|
||||
b->flags |= NDBUF_NREA;
|
||||
@ -104,16 +105,51 @@ ndbuf_t *ndbuf_new_palloc(uint32_t alen)
|
||||
return b;
|
||||
}
|
||||
|
||||
ndbuf_t *ndbuf_new_wmops(const struct ndbuf_memops *o, const size_t blk_len)
|
||||
{
|
||||
ndbuf_t *b = NULL;
|
||||
|
||||
if(!o) return NULL;
|
||||
else { /* avoid nil calls */
|
||||
if(!o->alloc || !o->free) return NULL;
|
||||
}
|
||||
|
||||
if(!(b = malloc(sizeof(ndbuf_t)))) return NULL;
|
||||
else memset(b, 0, sizeof(ndbuf_t));
|
||||
|
||||
if(blk_len <= 0) b->blk_size = DEFAULT_PREALLOC_SIZE;
|
||||
|
||||
if(!(b->raw = o->alloc(b->blk_size))) {
|
||||
free(b);
|
||||
return NULL;
|
||||
} else {
|
||||
b->rlength = b->blk_size;
|
||||
b->ulength = b->curr = 0;
|
||||
b->mop = o;
|
||||
b->flags |= NDBUF_UCMO;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* free all allocated space and buffer itself */
|
||||
void ndbuf_free(ndbuf_t *b)
|
||||
{
|
||||
const struct ndbuf_memops *o = NULL;
|
||||
if(!b) return;
|
||||
|
||||
if((b->flags & NDBUF_BURN) && b->raw)
|
||||
memset(b->raw, 0, b->rlength);
|
||||
if(b->flags & NDBUF_UCMO) o = b->mop;
|
||||
|
||||
if((b->flags & NDBUF_NREA) && b->freebuf) b->freebuf(b->raw);
|
||||
else if(b->raw) free(b->raw);
|
||||
if(o) {
|
||||
if((b->flags & NDBUF_BURN) && o->zero) o->zero((void *)b->raw, b->rlength);
|
||||
o->free(b->raw);
|
||||
} else {
|
||||
if((b->flags & NDBUF_BURN) && b->raw)
|
||||
memset(b->raw, 0, b->rlength);
|
||||
|
||||
if((b->flags & NDBUF_NREA) && b->freebuf) b->freebuf(b->raw);
|
||||
else if(b->raw) free(b->raw);
|
||||
}
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(b, 0, sizeof(ndbuf_t));
|
||||
free(b);
|
||||
@ -210,35 +246,61 @@ static int __rdb_grow(ndbuf_t *b, uint32_t len)
|
||||
{
|
||||
uint32_t rlen;
|
||||
char *ne = NULL;
|
||||
const struct ndbuf_memops *o = NULL;
|
||||
size_t bs = b->blk_size;
|
||||
|
||||
if(!len) return -1;
|
||||
if(b->rlength + len > NDBUF_MAXLENGTH) return -1;
|
||||
|
||||
rlen = len +
|
||||
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
|
||||
if(b->flags & NDBUF_UCMO) o = b->mop;
|
||||
|
||||
rlen = len + (len%bs != 0 ? (bs - len%bs) : 0);
|
||||
if(b->rlength + rlen > NDBUF_MAXLENGTH) rlen = len;
|
||||
|
||||
rlen += b->rlength;
|
||||
if(!(ne = malloc(rlen))) return -1;
|
||||
if(o) ne = (char *)o->alloc(rlen);
|
||||
else ne = malloc(rlen);
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(ne, 0, rlen);
|
||||
if(!ne) return -1;
|
||||
|
||||
if(b->flags & NDBUF_BURN) {
|
||||
if(o) o->zero((void *)ne, rlen);
|
||||
else memset(ne, 0, rlen);
|
||||
}
|
||||
|
||||
memcpy(ne, b->raw, b->ulength);
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
|
||||
free(b->raw);
|
||||
if(o) {
|
||||
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
|
||||
o->free((void *)b->raw);
|
||||
} else {
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
|
||||
free(b->raw);
|
||||
}
|
||||
b->raw = ne;
|
||||
b->rlength = rlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __ndbuf_is_ro(ndbuf_t *b)
|
||||
{
|
||||
return (b->flags & NDBUF_RORB) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline int __ndbuf_is_nrea(ndbuf_t *b)
|
||||
{
|
||||
return (b->flags & NDBUF_NREA) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* write different types, should return the size of the
|
||||
* written data, otherwise error occurs */
|
||||
uint32_t ndbuf_write_u8(ndbuf_t *b, uint8_t u)
|
||||
{
|
||||
if(!b || !b->raw) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
if(b->ulength == b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
if(__rdb_grow(b, sizeof(uint8_t))) return 0;
|
||||
}
|
||||
|
||||
@ -251,7 +313,9 @@ uint32_t ndbuf_write_u8(ndbuf_t *b, uint8_t u)
|
||||
uint32_t ndbuf_write_u16(ndbuf_t *b, uint16_t uu)
|
||||
{
|
||||
if(!b || !b->raw) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
if(b->ulength + sizeof(uint16_t) >= b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
if(__rdb_grow(b, sizeof(uint16_t))) return 0;
|
||||
}
|
||||
|
||||
@ -264,7 +328,9 @@ uint32_t ndbuf_write_u16(ndbuf_t *b, uint16_t uu)
|
||||
uint32_t ndbuf_write_u32(ndbuf_t *b, uint32_t uu)
|
||||
{
|
||||
if(!b || !b->raw) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
if(b->ulength + sizeof(uint32_t) >= b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
if(__rdb_grow(b, sizeof(uint32_t))) return 0;
|
||||
}
|
||||
|
||||
@ -277,7 +343,9 @@ uint32_t ndbuf_write_u32(ndbuf_t *b, uint32_t uu)
|
||||
uint32_t ndbuf_write_u64(ndbuf_t *b, uint64_t uu)
|
||||
{
|
||||
if(!b || !b->raw) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
if(b->ulength + sizeof(uint64_t) >= b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
if(__rdb_grow(b, sizeof(uint64_t))) return 0;
|
||||
}
|
||||
|
||||
@ -292,7 +360,10 @@ uint32_t ndbuf_write_raw(ndbuf_t *b, void *wi, uint32_t len)
|
||||
{
|
||||
if(!b || !b->raw) return 0;
|
||||
if(!wi || !len) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
|
||||
if(b->ulength + len >= b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
if(__rdb_grow(b, len)) return 0;
|
||||
}
|
||||
|
||||
@ -306,27 +377,46 @@ uint32_t ndbuf_write_raw(ndbuf_t *b, void *wi, uint32_t len)
|
||||
uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *wi, uint32_t len)
|
||||
{
|
||||
char *ne;
|
||||
const struct ndbuf_memops *o = NULL;
|
||||
uint32_t rlen;
|
||||
size_t bs = b->blk_size;
|
||||
|
||||
if(!b || !b->raw) return 0;
|
||||
if(!wi || !len) return 0;
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
|
||||
if(b->ulength + len > b->rlength) {
|
||||
if(__ndbuf_is_nrea(b)) return 0; /* non reallocatable buffer */
|
||||
/* allocate a new one and copy it right */
|
||||
if(b->rlength + len > NDBUF_MAXLENGTH) return -1;
|
||||
|
||||
rlen = len +
|
||||
(len%DEFAULT_PREALLOC_SIZE != 0 ? (DEFAULT_PREALLOC_SIZE - len%DEFAULT_PREALLOC_SIZE) : 0);
|
||||
rlen = len + (len%bs != 0 ? (bs - len%bs) : 0);
|
||||
if(b->rlength + rlen > NDBUF_MAXLENGTH) rlen = len;
|
||||
|
||||
rlen += b->rlength;
|
||||
if(!(ne = malloc(rlen))) return -1;
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(ne, 0, rlen);
|
||||
if(b->flags & NDBUF_UCMO) o = b->mop;
|
||||
|
||||
if(o) ne = (char *)o->alloc(rlen);
|
||||
else ne = malloc(rlen);
|
||||
|
||||
if(!ne) return -1;
|
||||
|
||||
if(b->flags & NDBUF_BURN) {
|
||||
if(o) o->zero((void *)ne, rlen);
|
||||
else memset(ne, 0, rlen);
|
||||
}
|
||||
|
||||
memcpy((void *)ne + len, b->raw, b->ulength);
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
|
||||
free(b->raw);
|
||||
if(o) {
|
||||
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
|
||||
o->free((void *)b->raw);
|
||||
} else {
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
|
||||
free(b->raw);
|
||||
}
|
||||
|
||||
b->raw = ne;
|
||||
b->rlength = rlen;
|
||||
} else {
|
||||
@ -339,8 +429,14 @@ uint32_t ndbuf_write_raw_head(ndbuf_t *b, void *wi, uint32_t len)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
register uint32_t fo = b->flags;
|
||||
register uint32_t len;
|
||||
uint32_t clen;
|
||||
va_list ap_copy;
|
||||
union {
|
||||
uint8_t *_u8;
|
||||
@ -352,7 +448,6 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
ndbuf_t **_rdb;
|
||||
} d;
|
||||
const char *t, *last;
|
||||
uint32_t len, clen;
|
||||
int r, count;
|
||||
|
||||
va_copy(ap_copy, ap);
|
||||
@ -393,18 +488,26 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
/* FIXME: Document the following line in manpages %limits% */
|
||||
if(clen > NDBUF_MAXLENGTH) goto __errrbread;
|
||||
if((*d._cstr = malloc(clen + sizeof(char))) == NULL) {
|
||||
r = -ENOMEM;
|
||||
break;
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._cstr, clen);
|
||||
if(len != clen) {
|
||||
free(*d._cstr);
|
||||
goto __errrbread;
|
||||
}
|
||||
(*d._cstr)[len] = '\0';
|
||||
d._cstr = NULL;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._cstr, clen);
|
||||
if(len != clen) {
|
||||
free(*d._cstr);
|
||||
goto __errrbread;
|
||||
}
|
||||
(*d._cstr)[len] = '\0';
|
||||
d._cstr = NULL;
|
||||
r = 0;
|
||||
break;
|
||||
case 'p':
|
||||
@ -414,14 +517,20 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
*d._dp = NULL;
|
||||
count++;
|
||||
|
||||
if((*d._dp = malloc(clen)) == NULL) {
|
||||
r = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._dp, clen);
|
||||
if(len != clen) {
|
||||
free(*d._dp);
|
||||
goto __errrbread;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._dp, clen);
|
||||
if(len != clen) {
|
||||
free(*d._dp);
|
||||
goto __errrbread;
|
||||
}
|
||||
}
|
||||
d._dp = NULL;
|
||||
r = 0;
|
||||
@ -435,19 +544,25 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
if((*d._dp = malloc(clen)) == NULL) {
|
||||
r = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._dp, clen);
|
||||
if(len != clen) {
|
||||
free(*d._dp);
|
||||
goto __errrbread;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
len = ndbuf_read_raw(b, *d._dp, clen);
|
||||
if(len != clen) {
|
||||
free(*d._dp);
|
||||
goto __errrbread;
|
||||
}
|
||||
}
|
||||
d._dp = NULL;
|
||||
r = 0;
|
||||
break;
|
||||
case 'R':
|
||||
case 'R': /* FIXME: what about moless and user defined ops ? */
|
||||
d._rdb = va_arg(ap, ndbuf_t **);
|
||||
*d._rdb = NULL;
|
||||
|
||||
@ -498,9 +613,14 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
break;
|
||||
case 's':
|
||||
d._cstr = va_arg(ap_copy, char **);
|
||||
if(*d._cstr) {
|
||||
memset(*d._cstr, 0, strlen(*d._cstr));
|
||||
free(*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));
|
||||
free(*d._cstr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
@ -511,7 +631,10 @@ int ndbuf_escan_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
(void)va_arg(ap_copy, size_t);
|
||||
case 'P':
|
||||
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;
|
||||
default:
|
||||
(void)va_arg(ap_copy, void *);
|
||||
@ -552,6 +675,8 @@ uint32_t ndbuf_print_va(ndbuf_t *b, const char *fmt, int argc, va_list ap)
|
||||
uint32_t len = 0, clen;
|
||||
int r, count;
|
||||
|
||||
if(__ndbuf_is_ro(b)) return 0; /* read only buffer */
|
||||
|
||||
for(t = fmt, count = 0; *t != '\0'; t++, count++) {
|
||||
if(count > argc && argc != -1) return 0;
|
||||
switch(*t) {
|
||||
@ -705,6 +830,8 @@ void ndbuf_setflags(ndbuf_t *b, int af)
|
||||
{
|
||||
if(!b) return;
|
||||
|
||||
if(((af & NDBUF_BURN) && (b->flags & NDBUF_UCMO)) && !b->mop->zero) return;
|
||||
|
||||
b->flags |= af;
|
||||
|
||||
return;
|
||||
@ -715,6 +842,8 @@ void ndbuf_exflags(ndbuf_t *b, int nf)
|
||||
{
|
||||
if(!b) return;
|
||||
|
||||
if(b->flags & NDBUF_UCMO) nf |= NDBUF_UCMO;
|
||||
|
||||
b->flags = nf;
|
||||
|
||||
return;
|
||||
@ -749,24 +878,43 @@ int ndbuf_cmp(ndbuf_t *b1, ndbuf_t *b2)
|
||||
/* let the buffer to use actually used bytes, not all allocated space
|
||||
* will return 0 on success (or in case if it doesn't required),
|
||||
* ENOMEM or other error if fails
|
||||
* TODO: ? make this buffer non reallocable ?
|
||||
*/
|
||||
int ndbuf_memopt(ndbuf_t *b)
|
||||
{
|
||||
uint32_t len;
|
||||
size_t bs = b->blk_size;
|
||||
char *ne;
|
||||
const struct ndbuf_memops *o = NULL;
|
||||
|
||||
if(!b || !b->raw) return EINVAL;
|
||||
|
||||
if((b->rlength - b->ulength) > DEFAULT_PREALLOC_SIZE) {
|
||||
if((b->rlength - b->ulength) > bs) {
|
||||
len = b->ulength +
|
||||
(b->ulength%DEFAULT_PREALLOC_SIZE != 0 ?
|
||||
(DEFAULT_PREALLOC_SIZE - b->ulength%DEFAULT_PREALLOC_SIZE) : 0);
|
||||
if(!(ne = malloc(len))) return ENOMEM;
|
||||
(b->ulength%bs != 0 ? (bs - b->ulength%bs) : 0);
|
||||
|
||||
if(b->flags & NDBUF_UCMO) o = b->mop;
|
||||
|
||||
if(o) ne = (char *)o->alloc(len);
|
||||
else ne = malloc(len);
|
||||
|
||||
if(!ne) return ENOMEM;
|
||||
|
||||
if(b->flags & NDBUF_BURN) {
|
||||
if(o) o->zero((void *)ne, len);
|
||||
else memset(ne, 0, len);
|
||||
}
|
||||
|
||||
if(b->flags & NDBUF_BURN) memset(ne, 0, len);
|
||||
memcpy(ne, b->raw, b->ulength);
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->ulength);
|
||||
free(b->raw);
|
||||
|
||||
if(o) {
|
||||
if(b->flags & NDBUF_BURN) o->zero((void *)b->raw, b->rlength);
|
||||
o->free((void *)b->raw);
|
||||
} else {
|
||||
if(b->flags & NDBUF_BURN) memset(b->raw, 0, b->rlength);
|
||||
free(b->raw);
|
||||
}
|
||||
|
||||
b->raw = ne;
|
||||
b->rlength = len;
|
||||
}
|
||||
@ -774,4 +922,21 @@ int ndbuf_memopt(ndbuf_t *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ndbuf_free_item(ndbuf_t *b, void *ip, size_t is)
|
||||
{
|
||||
if(!b || !ip) return;
|
||||
|
||||
if(__is_moless(b->flags)) return;
|
||||
|
||||
if(__is_usermo(b->flags)) {
|
||||
if((b->flags & NDBUF_BURN) && (is > 0)) b->mop->zero(ip, is);
|
||||
b->mop->free(ip);
|
||||
} else {
|
||||
if((b->flags & NDBUF_BURN) && (is > 0)) memset(ip, 0, is);
|
||||
free(ip);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#undef DEFAULT_PREALLOC_SIZE
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user