add compiler.h to abstract gcc attributes
This commit is contained in:
parent
51869a80f8
commit
ddfdd4d077
1
CHANGES
1
CHANGES
@ -5,6 +5,7 @@
|
||||
add automated way to run unit test: make check
|
||||
add parse.h
|
||||
add bytestream abstraction for parsing data from a buffer or a file
|
||||
add compiler.h to abstract gcc attributes
|
||||
|
||||
0.32:
|
||||
remove OpenBSD #warning (obsd maintainer says no longer needed)
|
||||
|
@ -209,7 +209,7 @@ INCLUDES=buffer.h byte.h fmt.h ip4.h ip6.h mmap.h scan.h socket.h str.h stralloc
|
||||
uint16.h uint32.h uint64.h open.h textcode.h tai.h taia.h dns.h iopause.h case.h \
|
||||
openreadclose.h readclose.h ndelay.h array.h io.h safemult.h iob.h havealloca.h \
|
||||
errmsg.h cdb.h cdb_make.h rangecheck.h iarray.h va_narg.h isset.h \
|
||||
compiletimeassert.h critbit.h parse.h
|
||||
compiletimeassert.h critbit.h parse.h compiler.h
|
||||
|
||||
libowfat:
|
||||
-mkdir libowfat
|
||||
|
44
array.h
44
array.h
@ -3,7 +3,8 @@
|
||||
#define ARRAY_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "uint64.h"
|
||||
#include <libowfat/compiler.h>
|
||||
#include <libowfat/uint64.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -21,25 +22,30 @@ typedef struct {
|
||||
size_t headroom; /* the actual pointer for free() and realloc() is p-headroom */
|
||||
} array;
|
||||
|
||||
void* array_allocate(array* x,uint64 membersize,int64 pos);
|
||||
void* array_get(const array* const x,uint64 membersize,int64 pos);
|
||||
void* array_start(const array* const x);
|
||||
int64 array_length(const array* const x,uint64 membersize);
|
||||
int64 array_bytes(const array* const x);
|
||||
void array_truncate(array* x,uint64 membersize,int64 len);
|
||||
void array_trunc(array* x);
|
||||
void array_reset(array* x);
|
||||
void array_fail(array* x);
|
||||
int array_equal(const array* const x,const array* const y);
|
||||
void array_cat(array* to,const array* const from);
|
||||
void array_catb(array* to,const char* from,uint64 len);
|
||||
void array_cats(array* to,const char* from);
|
||||
void array_cats0(array* to,const char* from);
|
||||
void array_cat0(array* to);
|
||||
void array_cate(array* to,const array* const from,int64 pos,int64 stop);
|
||||
void* array_allocate(array* x,uint64 membersize,int64 pos) noexcept;
|
||||
void* array_get(const array* const x,uint64 membersize,int64 pos) noexcept;
|
||||
void* array_start(const array* const x) noexcept;
|
||||
|
||||
void array_shift(array* x,uint64 membersize,uint64 members);
|
||||
void array_chop(array* x,uint64 membersize,uint64 members);
|
||||
att_pure
|
||||
int64 array_length(const array* const x,uint64 membersize) noexcept;
|
||||
|
||||
att_pure
|
||||
int64 array_bytes(const array* const x) noexcept;
|
||||
|
||||
void array_truncate(array* x,uint64 membersize,int64 len) noexcept;
|
||||
void array_trunc(array* x) noexcept;
|
||||
void array_reset(array* x) noexcept;
|
||||
void array_fail(array* x) noexcept;
|
||||
int array_equal(const array* const x,const array* const y) noexcept;
|
||||
void array_cat(array* to,const array* const from) noexcept;
|
||||
void array_catb(array* to,const char* from,uint64 len) noexcept;
|
||||
void array_cats(array* to,const char* from) noexcept;
|
||||
void array_cats0(array* to,const char* from) noexcept;
|
||||
void array_cat0(array* to) noexcept;
|
||||
void array_cate(array* to,const array* const from,int64 pos,int64 stop) noexcept;
|
||||
|
||||
void array_shift(array* x,uint64 membersize,uint64 members) noexcept;
|
||||
void array_chop(array* x,uint64 membersize,uint64 members) noexcept;
|
||||
|
||||
#define array_failed(x) (array_bytes(x)==-1)
|
||||
#define array_unallocated(x) (array_bytes(x)==0)
|
||||
|
44
buffer.h
44
buffer.h
@ -9,6 +9,8 @@
|
||||
/* for strlen */
|
||||
#include <string.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -43,12 +45,12 @@ typedef struct buffer {
|
||||
|
||||
/* Initialize a buffer with an existing memory area, which the buffer
|
||||
* will NOT take ownership of (i.e. won't free the memory when it's done */
|
||||
__writememsz__(4,5)
|
||||
att_writen(4,5)
|
||||
void buffer_init(buffer* b,ssize_t (*op)(),int fd,char* y,size_t ylen);
|
||||
|
||||
/* Initialize a buffer with an existing memory area, which the buffer
|
||||
* WILL take ownership of (it will call free() on it when it's done) */
|
||||
__writememsz__(4,5)
|
||||
att_writen(4,5)
|
||||
void buffer_init_free(buffer* b,ssize_t (*op)(),int fd,char* y,size_t ylen);
|
||||
|
||||
/* Initialize a buffer without actual I/O.
|
||||
@ -57,10 +59,12 @@ void buffer_init_free(buffer* b,ssize_t (*op)(),int fd,char* y,size_t ylen);
|
||||
* that memory area. If it reaches the end, it will signal EOF and never
|
||||
* actually attempt to read from any actual file.
|
||||
* Does not take ownership. Useful for testing. */
|
||||
att_readn(2,3)
|
||||
void buffer_init_staticcontents(buffer* b,char* y,size_t ylen);
|
||||
|
||||
/* Same but the buffer takes ownership of the static buffer and frees it
|
||||
* in buffer_close. */
|
||||
att_readn(2,3)
|
||||
void buffer_init_staticcontents_free(buffer* b,char* y,size_t ylen);
|
||||
|
||||
|
||||
@ -74,6 +78,7 @@ void buffer_munmap(void* buf);
|
||||
|
||||
/* Initialize a buffer so it will read from this file by memory mapping
|
||||
* the whole thing. */
|
||||
att_read(2)
|
||||
int buffer_mmapread(buffer* b,const char* filename);
|
||||
|
||||
/* Indicate you are done with a buffer.
|
||||
@ -86,17 +91,22 @@ void buffer_close(buffer* b);
|
||||
* the data in the buffer. */
|
||||
int buffer_flush(buffer* b);
|
||||
|
||||
__readmemsz__(2,3)
|
||||
att_readn(2,3)
|
||||
int buffer_put(buffer* b,const char* x,size_t len);
|
||||
__readmemsz__(2,3)
|
||||
|
||||
att_readn(2,3)
|
||||
int buffer_putalign(buffer* b,const char* x,size_t len);
|
||||
__readmemsz__(2,3)
|
||||
|
||||
att_readn(2,3)
|
||||
int buffer_putflush(buffer* b,const char* x,size_t len);
|
||||
__readmem__(2)
|
||||
|
||||
att_read(2)
|
||||
int buffer_puts(buffer* b,const char* x);
|
||||
__readmem__(2)
|
||||
|
||||
att_read(2)
|
||||
int buffer_putsalign(buffer* b,const char* x);
|
||||
__readmem__(2)
|
||||
|
||||
att_read(2)
|
||||
int buffer_putsflush(buffer* b,const char* x);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__LIBOWFAT_INTERNAL)
|
||||
@ -121,22 +131,22 @@ int buffer_putnlflush(buffer* b); /* put \n and flush */
|
||||
: buffer_put((s),&(c),1) \
|
||||
)
|
||||
|
||||
__writememsz__(2,3)
|
||||
att_writen(2,3)
|
||||
ssize_t buffer_get(buffer* b,char* x,size_t len);
|
||||
ssize_t buffer_feed(buffer* b);
|
||||
ssize_t buffer_getc(buffer* b,char* x);
|
||||
ssize_t buffer_peekc(buffer* b,char* x);
|
||||
__writememsz__(2,3)
|
||||
att_writen(2,3)
|
||||
ssize_t buffer_getn(buffer* b,char* x,size_t len);
|
||||
|
||||
/* read bytes until the destination buffer is full (len bytes), end of
|
||||
* file is reached or the read char is in charset (setlen bytes). An
|
||||
* empty line when looking for \n will write '\n' to x and return 0. If
|
||||
* EOF is reached, \0 is written to the buffer */
|
||||
__writememsz__(2,3)
|
||||
__readmemsz__(4,5)
|
||||
att_writen(2,3)
|
||||
att_readn(4,5)
|
||||
ssize_t buffer_get_token(buffer* b,char* x,size_t len,const char* charset,size_t setlen);
|
||||
__writememsz__(2,3)
|
||||
att_writen(2,3)
|
||||
ssize_t buffer_getline(buffer* b,char* x,size_t len);
|
||||
|
||||
/* this predicate is given the string as currently read from the buffer
|
||||
@ -144,7 +154,7 @@ ssize_t buffer_getline(buffer* b,char* x,size_t len);
|
||||
typedef int (*string_predicate)(const char* x,size_t len);
|
||||
|
||||
/* like buffer_get_token but the token ends when your predicate says so */
|
||||
__writememsz__(2,3)
|
||||
att_writen(2,3)
|
||||
ssize_t buffer_get_token_pred(buffer* b,char* x,size_t len,string_predicate p);
|
||||
|
||||
char *buffer_peek(buffer* b);
|
||||
@ -194,13 +204,13 @@ int buffer_putsaflush(buffer* b,const stralloc* sa);
|
||||
* data is available. */
|
||||
|
||||
/* read token from buffer to stralloc */
|
||||
__readmemsz__(3,4)
|
||||
att_readn(3,4)
|
||||
int buffer_get_token_sa(buffer* b,stralloc* sa,const char* charset,size_t setlen);
|
||||
/* read line from buffer to stralloc */
|
||||
int buffer_getline_sa(buffer* b,stralloc* sa);
|
||||
|
||||
/* same as buffer_get_token_sa but empty sa first */
|
||||
__readmemsz__(3,4)
|
||||
att_readn(3,4)
|
||||
int buffer_get_new_token_sa(buffer* b,stralloc* sa,const char* charset,size_t setlen);
|
||||
/* same as buffer_getline_sa but empty sa first */
|
||||
int buffer_getnewline_sa(buffer* b,stralloc* sa);
|
||||
@ -218,7 +228,7 @@ void buffer_fromsa(buffer* b,const stralloc* sa); /* read from sa */
|
||||
int buffer_tosa(buffer*b,stralloc* sa); /* write to sa, auto-growing it */
|
||||
#endif
|
||||
|
||||
__readmemsz__(2,3)
|
||||
att_readn(2,3)
|
||||
void buffer_frombuf(buffer* b,const char* x,size_t l); /* buffer reads from static buffer */
|
||||
|
||||
#ifdef ARRAY_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "parse.h"
|
||||
|
||||
size_t bs_capacityleft(struct bytestream* bs) {
|
||||
size_t bs_capacityleft(const struct bytestream* bs) {
|
||||
if (bs->cur>=bs->max) // if EOF or error, return 0
|
||||
return 0;
|
||||
return bs->max - bs->cur;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "parse.h"
|
||||
|
||||
int bs_err(struct bytestream* bs) {
|
||||
int bs_err(const struct bytestream* bs) {
|
||||
return (bs->cur > bs->max);
|
||||
}
|
||||
|
||||
|
67
byte.h
67
byte.h
@ -9,76 +9,69 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* dietlibc defines these in sys/cdefs.h, which is included from stddef.h */
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
|
||||
#ifndef __writememsz__
|
||||
#define __writememsz__(a,b)
|
||||
#define __readmemsz__(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef __readmem__
|
||||
#define __readmem__(a)
|
||||
#endif
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
/* byte_chr returns the smallest integer i between 0 and len-1
|
||||
* inclusive such that one[i] equals needle, or len if not found. */
|
||||
__readmemsz__(1,2)
|
||||
size_t byte_chr(const void* haystack, size_t len, char needle) __pure__;
|
||||
att_readn(1,2)
|
||||
size_t byte_chr(const void* haystack, size_t len, char needle) noexcept;
|
||||
|
||||
/* byte_rchr returns the largest integer i between 0 and len-1 inclusive
|
||||
* such that one[i] equals needle, or len if not found. */
|
||||
__readmemsz__(1,2)
|
||||
size_t byte_rchr(const void* haystack,size_t len,char needle) __pure__;
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
size_t byte_rchr(const void* haystack,size_t len,char needle) noexcept;
|
||||
|
||||
/* byte_copy copies in[0] to out[0], in[1] to out[1], ... and in[len-1]
|
||||
* to out[len-1]. */
|
||||
__writememsz__(1,2)
|
||||
__readmemsz__(3,2)
|
||||
void byte_copy(void* out, size_t len, const void* in);
|
||||
att_writen(1,2)
|
||||
att_readn(3,2)
|
||||
void byte_copy(void* out, size_t len, const void* in) noexcept;
|
||||
|
||||
/* byte_copyr copies in[len-1] to out[len-1], in[len-2] to out[len-2],
|
||||
* ... and in[0] to out[0] */
|
||||
__writememsz__(1,2)
|
||||
__readmemsz__(3,2)
|
||||
void byte_copyr(void* out, size_t len, const void* in);
|
||||
att_writen(1,2)
|
||||
att_readn(3,2)
|
||||
void byte_copyr(void* out, size_t len, const void* in) noexcept;
|
||||
|
||||
/* byte_diff returns negative, 0, or positive, depending on whether the
|
||||
* string a[0], a[1], ..., a[len-1] is lexicographically smaller
|
||||
* than, equal to, or greater than the string b[0], b[1], ...,
|
||||
* b[len-1]. When the strings are different, byte_diff does not read
|
||||
* bytes past the first difference. */
|
||||
__readmemsz__(1,2)
|
||||
__readmemsz__(3,2)
|
||||
int byte_diff(const void* a, size_t len, const void* b) __pure__;
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
att_readn(3,2)
|
||||
int byte_diff(const void* a, size_t len, const void* b) noexcept;
|
||||
|
||||
/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */
|
||||
__writememsz__(1,2)
|
||||
void byte_zero(void* out, size_t len);
|
||||
att_writen(1,2)
|
||||
void byte_zero(void* out, size_t len) noexcept;
|
||||
|
||||
#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
|
||||
|
||||
/* Return 1 iff (b,blen) is a prefix of (a,alen), 0 otherwise.
|
||||
* Will abort early on mismatch */
|
||||
__readmemsz__(1,2)
|
||||
__readmemsz__(3,4)
|
||||
int byte_start(const void* a,size_t alen,const void* b,size_t blen) __pure__;
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
att_readn(3,4)
|
||||
int byte_start(const void* a,size_t alen,const void* b,size_t blen) noexcept;
|
||||
|
||||
/* equivalent to byte_start(a,alen,str,strlen(str)) */
|
||||
__readmemsz__(1,2)
|
||||
__readmem__(3)
|
||||
int byte_starts(const void* a,size_t alen,const char* str) __pure__;
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
att_read(3)
|
||||
int byte_starts(const void* a,size_t alen,const char* str) noexcept;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__LIBOWFAT_INTERNAL)
|
||||
/* If str is a string constant, strlen will be done at compile time */
|
||||
#define byte_starts(a,alen,str) (__builtin_constant_p(str) ? byte_start(a,alen,str,strlen(str)) : byte_starts(a,alen,str))
|
||||
#endif
|
||||
|
||||
__readmemsz__(1,2)
|
||||
__readmemsz__(3,2)
|
||||
int byte_equal_notimingattack(const void* a, size_t len,const void* b) __pure__;
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
att_readn(3,2)
|
||||
int byte_equal_notimingattack(const void* a, size_t len,const void* b) noexcept;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define UNALIGNED_ACCESS_OK
|
||||
|
14
case.h
14
case.h
@ -3,22 +3,36 @@
|
||||
#define CASE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* turn upper case letters to lower case letters, ASCIIZ */
|
||||
att_mangle(1)
|
||||
void case_lowers(char *s);
|
||||
|
||||
/* turn upper case letters to lower case letters, binary */
|
||||
att_manglen(1,2)
|
||||
void case_lowerb(void *buf,size_t len);
|
||||
|
||||
/* like str_diff, ignoring case */
|
||||
att_pure
|
||||
att_read(1)
|
||||
att_read(2)
|
||||
int case_diffs(const char *,const char *);
|
||||
|
||||
/* like byte_diff, ignoring case */
|
||||
att_pure
|
||||
att_readn(1,2)
|
||||
att_readn(3,2)
|
||||
int case_diffb(const void *,size_t ,const void *);
|
||||
|
||||
/* like str_start, ignoring case */
|
||||
att_pure
|
||||
att_read(1)
|
||||
att_read(2)
|
||||
int case_starts(const char *,const char *);
|
||||
|
||||
#define case_equals(s,t) (!case_diffs((s),(t)))
|
||||
|
26
cdb.h
26
cdb.h
@ -2,16 +2,22 @@
|
||||
#ifndef CDB_H
|
||||
#define CDB_H
|
||||
|
||||
#include "uint32.h"
|
||||
#include "uint64.h"
|
||||
#include <stddef.h>
|
||||
#include <libowfat/uint32.h>
|
||||
#include <libowfat/uint64.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CDB_HASHSTART 5381
|
||||
extern uint32 cdb_hashadd(uint32 h,unsigned char c);
|
||||
extern uint32 cdb_hash(const unsigned char *buf,unsigned long int len);
|
||||
att_const
|
||||
uint32 cdb_hashadd(uint32 h, unsigned char c);
|
||||
|
||||
att_pure
|
||||
att_read(1)
|
||||
uint32 cdb_hash(const unsigned char *buf, size_t len);
|
||||
|
||||
struct cdb {
|
||||
char *map; /* 0 if no map is available */
|
||||
@ -26,19 +32,19 @@ struct cdb {
|
||||
uint32 dlen; /* initialized if cdb_findnext() returns 1 */
|
||||
} ;
|
||||
|
||||
extern void cdb_free(struct cdb *);
|
||||
extern void cdb_init(struct cdb *,int64 fd);
|
||||
void cdb_free(struct cdb *);
|
||||
void cdb_init(struct cdb *, int64 fd);
|
||||
|
||||
extern int cdb_read(struct cdb *,unsigned char *,unsigned long int,uint32);
|
||||
int cdb_read(struct cdb * restrict, unsigned char * restrict, size_t, uint32);
|
||||
|
||||
extern void cdb_findstart(struct cdb *);
|
||||
extern int cdb_findnext(struct cdb *,const unsigned char *,unsigned long int);
|
||||
extern int cdb_find(struct cdb *,const unsigned char *,unsigned long int);
|
||||
extern int cdb_findnext(struct cdb *, const unsigned char *, size_t);
|
||||
extern int cdb_find(struct cdb *, const unsigned char *, size_t);
|
||||
|
||||
extern int cdb_firstkey(struct cdb *c,uint32 *kpos);
|
||||
extern int cdb_nextkey(struct cdb *c,uint32 *kpos);
|
||||
|
||||
extern int cdb_successor(struct cdb *c,const unsigned char *,unsigned long int);
|
||||
extern int cdb_successor(struct cdb *c, const unsigned char *, size_t);
|
||||
|
||||
#define cdb_datapos(c) ((c)->dpos)
|
||||
#define cdb_datalen(c) ((c)->dlen)
|
||||
|
@ -58,7 +58,7 @@ void cdb_init(struct cdb *c,int64 fd) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int cdb_read(struct cdb *c,unsigned char *buf,unsigned long len,uint32 pos) {
|
||||
int cdb_read(struct cdb *c, unsigned char *buf, size_t len, uint32 pos) {
|
||||
if (c->map) {
|
||||
if ((pos > c->size) || (c->size - pos < len)) goto FORMAT;
|
||||
byte_copy(buf,len,c->map + pos);
|
||||
@ -96,7 +96,7 @@ int cdb_read(struct cdb *c,unsigned char *buf,unsigned long len,uint32 pos) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int match(struct cdb *c,const unsigned char *key,unsigned long int len,uint32 pos) {
|
||||
static int match(struct cdb * restrict c, const unsigned char * restrict key, size_t len, uint32 pos) {
|
||||
unsigned char buf[32];
|
||||
unsigned long n;
|
||||
|
||||
@ -112,7 +112,7 @@ static int match(struct cdb *c,const unsigned char *key,unsigned long int len,ui
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cdb_findnext(struct cdb *c,const unsigned char *key,unsigned long int len) {
|
||||
int cdb_findnext(struct cdb *c, const unsigned char *key, size_t len) {
|
||||
unsigned char buf[8];
|
||||
uint32 pos;
|
||||
uint32 u;
|
||||
@ -156,7 +156,7 @@ int cdb_findnext(struct cdb *c,const unsigned char *key,unsigned long int len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cdb_find(struct cdb *c,const unsigned char *key,unsigned long int len) {
|
||||
int cdb_find(struct cdb *c, const unsigned char *key, size_t len) {
|
||||
cdb_findstart(c);
|
||||
return cdb_findnext(c,key,len);
|
||||
}
|
||||
|
@ -6,13 +6,13 @@ cdb_find \- look up a key in a constant database
|
||||
.br
|
||||
.B #include <libowfat/uint32.h>
|
||||
|
||||
int cdb_find(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned long int \fIkeylen\fR);
|
||||
int cdb_find(struct cdb *\fIc\fR, char *\fIkey\fR, size_t \fIkeylen\fR);
|
||||
.br
|
||||
int cdb_datalen(struct cdb *\fIc\fR);
|
||||
.br
|
||||
int cdb_datapos(struct cdb *\fIc\fR);
|
||||
.br
|
||||
int cdb_findnext(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned long int \fIkeylen\fR);
|
||||
int cdb_findnext(struct cdb *\fIc\fR, char *\fIkey\fR, size_t \fIkeylen\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBcdb_find\fR looks for \fIkey\fR. If cdb_find returns 0, the database
|
||||
|
@ -6,7 +6,7 @@ cdb_firstkey \- find first physical record in constant database
|
||||
.br
|
||||
.B #include <libowfat/uint32.h>
|
||||
|
||||
int cdb_firstkey(struct cdb *\fIc\fR,uint32 *\fIkpos\fR);
|
||||
int cdb_firstkey(struct cdb *\fIc\fR, uint32 *\fIkpos\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBcdb_firstkey\fR finds the physically first record in the constant
|
||||
|
@ -6,7 +6,7 @@ uint32 cdb_hashadd(uint32 h,unsigned char c) {
|
||||
return h ^ c;
|
||||
}
|
||||
|
||||
uint32 cdb_hash(const unsigned char *buf,unsigned long int len) {
|
||||
uint32 cdb_hash(const unsigned char *buf,size_t len) {
|
||||
uint32 h;
|
||||
|
||||
h = CDB_HASHSTART;
|
||||
|
@ -4,7 +4,7 @@ cdb_init \- open a constant database
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/cdb.h>
|
||||
|
||||
int cdb_init(struct cdb *\fIc\fR,int \fIfd\fR);
|
||||
int cdb_init(struct cdb *\fIc\fR, int \fIfd\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B cdb_init
|
||||
|
@ -55,7 +55,7 @@ int cdb_make_addend(struct cdb_make *c,unsigned long int keylen,unsigned long in
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cdb_make_addbegin(struct cdb_make *c,unsigned long int keylen,unsigned long int datalen) {
|
||||
int cdb_make_addbegin(struct cdb_make *c, size_t keylen, size_t datalen) {
|
||||
char buf[8];
|
||||
|
||||
if (keylen > 0xffffffff) { errno = ENOMEM; return -1; }
|
||||
@ -67,7 +67,7 @@ int cdb_make_addbegin(struct cdb_make *c,unsigned long int keylen,unsigned long
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cdb_make_add(struct cdb_make *c,const unsigned char *key,unsigned long int keylen,const unsigned char *data,unsigned long int datalen)
|
||||
int cdb_make_add(struct cdb_make *c, const unsigned char *key, size_t keylen, const unsigned char *data, size_t datalen)
|
||||
{
|
||||
if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1;
|
||||
if (buffer_putalign(&c->b,(char*)key,keylen) == -1) return -1;
|
||||
|
@ -6,7 +6,7 @@ cdb_nextkey \- find next physical record in constant database
|
||||
.br
|
||||
.B #include <libowfat/uint32.h>
|
||||
|
||||
int cdb_nextkey(struct cdb *\fIc\fR,uint32 *\fIkpos\fR);
|
||||
int cdb_nextkey(struct cdb *\fIc\fR, uint32 *\fIkpos\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBcdb_nextkey\fR finds the next physical record in the constant
|
||||
|
@ -6,7 +6,7 @@ cdb_read \- read bytes from a constant database
|
||||
.br
|
||||
.B #include <libowfat/uint32.h>
|
||||
|
||||
int cdb_read(struct cdb *\fIc\fR,char *\fIbuf\fR,unsigned long int \fIlen\fR,uint32 \fIposition\fR);
|
||||
int cdb_read(struct cdb *\fIc\fR, char *\fIbuf\fR, size_t \fIlen\fR, uint32 \fIposition\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBcdb_read\fR reads \fIlen\fR bytes starting at \fIposition\fR from
|
||||
|
@ -4,7 +4,7 @@ cdb_successor \- find next record
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/cdb.h>
|
||||
|
||||
int cdb_successor(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned long int \fIklen\fR);
|
||||
int cdb_successor(struct cdb *\fIc\fR, char *\fIkey\fR, size_t \fIklen\fR);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBcdb_successor\fR finds the record that follows \fIkey\fR. If
|
||||
|
12
cdb_make.h
12
cdb_make.h
@ -2,9 +2,9 @@
|
||||
#ifndef CDB_MAKE_H
|
||||
#define CDB_MAKE_H
|
||||
|
||||
#include "buffer.h"
|
||||
#include "uint64.h"
|
||||
#include "uint32.h"
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/uint64.h>
|
||||
#include <libowfat/uint32.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -35,9 +35,9 @@ struct cdb_make {
|
||||
} ;
|
||||
|
||||
extern int cdb_make_start(struct cdb_make *,int64);
|
||||
extern int cdb_make_addbegin(struct cdb_make *,unsigned long int,unsigned long int);
|
||||
extern int cdb_make_addend(struct cdb_make *,unsigned long int,unsigned long int,uint32);
|
||||
extern int cdb_make_add(struct cdb_make *,const unsigned char *,unsigned long int,const unsigned char *,unsigned long int);
|
||||
extern int cdb_make_addbegin(struct cdb_make *, size_t, size_t);
|
||||
extern int cdb_make_addend(struct cdb_make *, size_t, size_t, uint32);
|
||||
extern int cdb_make_add(struct cdb_make *, const unsigned char *, size_t, const unsigned char *, size_t);
|
||||
extern int cdb_make_finish(struct cdb_make *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
110
compiler.h
Normal file
110
compiler.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef LIBOWFAT_ATTRIBUTES_H
|
||||
#define LIBOWFAT_ATTRIBUTES_H
|
||||
|
||||
#ifndef __GNUC__
|
||||
// macro attribute declarations away if we don't have gcc or clang
|
||||
#define __attribute__(x)
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define noexcept
|
||||
#endif
|
||||
|
||||
#define GCC_VERSION_ATLEAST(a,b) (__GNUC__ > a) || ((__GNUC__ == a) && (__GNUC_MINOR__ >= b))
|
||||
|
||||
#if GCC_VERSION_ATLEAST(2,95) && !defined(__STRICT_ANSI__)
|
||||
#undef restrict
|
||||
#else
|
||||
#define restrict
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(3,0)
|
||||
#define likely(a) __builtin_expect((a), 1)
|
||||
#define unlikely(a) __builtin_expect((a), 0)
|
||||
#else
|
||||
#define likely(a) (a)
|
||||
#define unlikely(a) (a)
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(2, 5)
|
||||
#define att_const __attribute__((__const__))
|
||||
#else
|
||||
#define att_const
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(2, 96)
|
||||
#define att_pure __attribute__((__pure__))
|
||||
#else
|
||||
#define att_pure
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(3, 0)
|
||||
#define att_malloc __attribute__((__malloc__))
|
||||
#else
|
||||
#define att_malloc
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(3, 4)
|
||||
#define att_warn_unused_result __attribute__((__warn_unused_result__))
|
||||
#else
|
||||
#define att_warn_unused_result
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(4, 3)
|
||||
#define att_hot __attribute__((__hot__))
|
||||
#define att_cold __attribute__((__cold__))
|
||||
#else
|
||||
#define att_hot
|
||||
#define att_cold
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(4, 3)
|
||||
#define att_alloc(x) __attribute__((alloc_size(x)))
|
||||
#define att_calloc(x,y) __attribute__((alloc_size(x,y)))
|
||||
#else
|
||||
#define att_alloc
|
||||
#define att_calloc
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(10, 0)
|
||||
#define att_read(argno_ptr) __attribute__((access(read_only, argno_ptr)))
|
||||
#define att_readn(argno_ptr, argno_size) __attribute__((access(read_only, argno_ptr, argno_size)))
|
||||
#define att_write(argno_ptr) __attribute__((access(write_only, argno_ptr)))
|
||||
#define att_writen(argno_ptr, argno_size) __attribute__((access(write_only, argno_ptr, argno_size)))
|
||||
#define att_mangle(argno_ptr) __attribute__((access(read_write, argno_ptr)))
|
||||
#define att_manglen(argno_ptr, argno_size) __attribute__((access(read_write, argno_ptr, argno_size)))
|
||||
#else
|
||||
#define att_read(argno_ptr)
|
||||
#define att_readn(argno_ptr, argno_size)
|
||||
#define att_write(argno_ptr)
|
||||
#define att_writen(argno_ptr, argno_size)
|
||||
#define att_mangle(argno_ptr)
|
||||
#define att_manglen(argno_ptr, argno_size)
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(3, 2)
|
||||
#define att_dontuse __attribute__((__deprecated__))
|
||||
#else
|
||||
#define att_dontuse
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(3, 3)
|
||||
#define att_nonnull(params) __attribute__((__nonnull__(params)))
|
||||
#else
|
||||
#define att_nonnull(params)l
|
||||
#endif
|
||||
|
||||
#if GCC_VERSION_ATLEAST(4, 3)
|
||||
#define att_warn(message) __attribute__((__warning__(message)))
|
||||
#define att_error(message) __attribute__((__warning__(message)))
|
||||
#else
|
||||
#define att_warn(message)
|
||||
#define att_error(message)
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __builtin_constant_p(x) 0
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,11 +1,17 @@
|
||||
|
||||
#if __STDC_VERSION__ >= 201710L
|
||||
#ifdef __clang__
|
||||
|
||||
#define compiletimeassert(cond) _Static_assert(cond)
|
||||
// clang already includes the condition in the error message and emits
|
||||
// an additional warning here if we use the variant without message
|
||||
#define compiletimeassert(cond) _Static_assert(cond,"")
|
||||
|
||||
#elif __STDC_VERSION__ >= 201710L
|
||||
|
||||
#define compiletimeassert(cond) _Static_assert(cond,#cond)
|
||||
|
||||
#elif __STDC_VERSION__ >= 201112L
|
||||
|
||||
#define compiletimeassert(cond) _Static_assert(cond,"")
|
||||
#define compiletimeassert(cond) _Static_assert(cond,#cond)
|
||||
|
||||
#else
|
||||
|
||||
|
22
critbit.h
22
critbit.h
@ -5,23 +5,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* for __pure__ if we are compiling under dietlibc */
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
typedef struct {
|
||||
void *root;
|
||||
} critbit0_tree;
|
||||
|
||||
int critbit0_contains(critbit0_tree *t, const char *u) __pure__;
|
||||
int critbit0_insert(critbit0_tree *t, const char *u);
|
||||
int critbit0_delete(critbit0_tree *t, const char *u);
|
||||
void critbit0_clear(critbit0_tree *t);
|
||||
att_pure
|
||||
int critbit0_contains(critbit0_tree *t, const char *u) noexcept;
|
||||
|
||||
int critbit0_insert(critbit0_tree *t, const char *u) noexcept;
|
||||
|
||||
int critbit0_delete(critbit0_tree *t, const char *u) noexcept;
|
||||
|
||||
void critbit0_clear(critbit0_tree *t) noexcept;
|
||||
|
||||
int critbit0_allprefixed(critbit0_tree *t, const char *prefix,
|
||||
int (*handle) (const char *, void *), void *arg);
|
||||
int (*handle) (const char *, void *), void *arg) noexcept;
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
6
dns.h
6
dns.h
@ -2,9 +2,9 @@
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
#include "stralloc.h"
|
||||
#include "iopause.h"
|
||||
#include "taia.h"
|
||||
#include <libowfat/stralloc.h>
|
||||
#include <libowfat/iopause.h>
|
||||
#include <libowfat/taia.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
171
fmt.h
171
fmt.h
@ -13,16 +13,13 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
/* for byte_copy */
|
||||
#include "byte.h"
|
||||
#include <libowfat/byte.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
|
||||
#define FMT_LONG 41 /* enough space to hold -2^127 in decimal, plus \0 */
|
||||
#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
|
||||
#define FMT_8LONG 44 /* enough space to hold 2^128 - 1 in octal, plus \0 */
|
||||
@ -50,31 +47,38 @@ extern "C" {
|
||||
/* convert signed src integer -23 to ASCII '-','2','3', return number of
|
||||
* bytes of value in output format (3 in this example).
|
||||
* If dest is not NULL, write result to dest */
|
||||
size_t fmt_long(char *dest,signed long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_long(char *dest,signed long src) noexcept;
|
||||
|
||||
/* convert unsigned src integer 23 to ASCII '2','3', return number of
|
||||
* bytes of value in output format (2 in this example).
|
||||
* If dest is not NULL, write result to dest */
|
||||
size_t fmt_ulong(char *dest,unsigned long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_ulong(char *dest,unsigned long src) noexcept;
|
||||
|
||||
/* convert unsigned src integer 0x23 to ASCII '2','3', return number of
|
||||
* bytes of value in output format (2 in this example).
|
||||
* If dest is not NULL, write result to dest */
|
||||
size_t fmt_xlong(char *dest,unsigned long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_xlong(char *dest,unsigned long src) noexcept;
|
||||
|
||||
/* convert unsigned src integer 023 to ASCII '2','3', return number of
|
||||
* bytes of value in output format (2 in this example).
|
||||
* If dest is not NULL, write result to dest */
|
||||
size_t fmt_8long(char *dest,unsigned long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_8long(char *dest,unsigned long src) noexcept;
|
||||
|
||||
/* like fmt_long but for long long */
|
||||
size_t fmt_longlong(char *dest,signed long long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_longlong(char *dest,signed long long src) noexcept;
|
||||
|
||||
/* like fmt_ulong but for unsigned long long */
|
||||
size_t fmt_ulonglong(char *dest,unsigned long long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_ulonglong(char *dest,unsigned long long src) noexcept;
|
||||
|
||||
/* like fmt_xlong but for unsigned long long */
|
||||
size_t fmt_xlonglong(char *dest,unsigned long long src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_xlonglong(char *dest,unsigned long long src) noexcept;
|
||||
|
||||
#define fmt_uint(dest,src) fmt_ulong(dest,src)
|
||||
#define fmt_int(dest,src) fmt_long(dest,src)
|
||||
@ -85,22 +89,26 @@ size_t fmt_xlonglong(char *dest,unsigned long long src) __pure__;
|
||||
* Does not truncate! */
|
||||
/* fmt_ulong0(buf,23,4) -> '0','0','2','3' return 4 */
|
||||
/* fmt_ulong0(buf,234,2) -> '2','3','4', return 3 */
|
||||
size_t fmt_ulong0(char *,unsigned long src,size_t padto) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_ulong0(char *,unsigned long src,size_t padto) noexcept;
|
||||
|
||||
#define fmt_uint0(buf,src,padto) fmt_ulong0(buf,src,padto)
|
||||
|
||||
/* convert src double 1.7 to ASCII '1','.','7', return length.
|
||||
* If dest is not NULL, write result to dest */
|
||||
size_t fmt_double(char *dest, double d,int max,int prec) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_double(char *dest, double d,int max,int prec) noexcept;
|
||||
|
||||
/* if src is negative, write '-' and return 1.
|
||||
* if src is positive, write '+' and return 1.
|
||||
* otherwise return 0 */
|
||||
size_t fmt_plusminus(char *dest,int src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_plusminus(char *dest,int src) noexcept;
|
||||
|
||||
/* if src is negative, write '-' and return 1.
|
||||
* otherwise return 0. */
|
||||
size_t fmt_minus(char *dest,int src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_minus(char *dest,int src) noexcept;
|
||||
|
||||
/* copy str to dest until \0 byte, return number of copied bytes. */
|
||||
/* fmt_str(NULL,str) == strlen(str) */
|
||||
@ -112,13 +120,17 @@ size_t fmt_minus(char *dest,int src) __pure__;
|
||||
* This is more efficient because strcat needs to scan the string to
|
||||
* find the end and append.
|
||||
*/
|
||||
size_t fmt_str(char *dest,const char *src) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_str(char *dest,const char *src) noexcept;
|
||||
|
||||
/* copy str to dest until \0 byte or limit bytes copied.
|
||||
* return number of copied bytes. */
|
||||
size_t fmt_strn(char *dest,const char *src,size_t limit) __pure__;
|
||||
att_writen(1,3)
|
||||
att_readn(2,3)
|
||||
size_t fmt_strn(char *dest,const char *src,size_t limit) noexcept;
|
||||
|
||||
/* copy n bytes from src to dest, return n */
|
||||
att_writen(1,3)
|
||||
static inline size_t fmt_copybytes(char* dest,const char* src,size_t n) {
|
||||
if (dest) byte_copy(dest,n,src);
|
||||
return n;
|
||||
@ -135,59 +147,103 @@ static inline size_t fmt_copybytes(char* dest,const char* src,size_t n) {
|
||||
* write padlen-srclen spaces, if that is >= 0. Then copy srclen
|
||||
* characters from src. Truncate only if total length is larger than
|
||||
* maxlen. Return number of characters written. */
|
||||
size_t fmt_pad(char* dest,const char* src,size_t srclen,size_t padlen,size_t maxlen) __pure__;
|
||||
att_writen(1,5)
|
||||
att_readn(2,3)
|
||||
size_t fmt_pad(char* dest,const char* src,size_t srclen,size_t padlen,size_t maxlen) noexcept;
|
||||
|
||||
/* "foo" -> "foo "
|
||||
* append padlen-srclen spaces after dest, if that is >= 0. Truncate
|
||||
* only if total length is larger than maxlen. Return number of
|
||||
* characters written. */
|
||||
size_t fmt_fill(char* dest,size_t srclen,size_t padlen,size_t maxlen) __pure__;
|
||||
att_writen(1,4)
|
||||
size_t fmt_fill(char* dest,size_t srclen,size_t padlen,size_t maxlen) noexcept;
|
||||
|
||||
/* 1 -> "1", 4900 -> "4.9k", 2300000 -> "2.3M" */
|
||||
size_t fmt_human(char* dest,unsigned long long l) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_human(char* dest,unsigned long long l) noexcept;
|
||||
|
||||
/* 1 -> "1", 4900 -> "4.8k", 2300000 -> "2.2M" */
|
||||
size_t fmt_humank(char* dest,unsigned long long l) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_humank(char* dest,unsigned long long l) noexcept;
|
||||
|
||||
/* "Sun, 06 Nov 1994 08:49:37 GMT" */
|
||||
size_t fmt_httpdate(char* dest,time_t t); /* not marked pure because it calls gmtime */
|
||||
att_write(1)
|
||||
size_t fmt_httpdate(char* dest,time_t t) noexcept; /* not marked pure because it calls gmtime */
|
||||
|
||||
/* "2014-05-27T19:22:16.247Z" */
|
||||
size_t fmt_iso8601(char* dest,time_t t) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_iso8601(char* dest,time_t t) noexcept;
|
||||
|
||||
#define FMT_UTF8 5
|
||||
#define FMT_ASN1LENGTH 17 /* enough space to hold 2^128-1 */
|
||||
#define FMT_ASN1TAG 19 /* enough space to hold 2^128-1 */
|
||||
|
||||
/* some variable length encodings for integers */
|
||||
size_t fmt_utf8(char* dest,uint32_t n) __pure__; /* can store 0-0x7fffffff */
|
||||
size_t fmt_utf8_scratch(char* dest,uint32_t n) __pure__; /* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
size_t fmt_asn1derlength(char* dest,unsigned long long l) __pure__; /* 0-0x7f: 1 byte, above that 1+bytes_needed bytes */
|
||||
size_t fmt_asn1derlength_scratch(char* dest,unsigned long long l) __pure__; /* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
size_t fmt_asn1dertag(char* dest,unsigned long long l) __pure__; /* 1 byte for each 7 bits; upper bit = more bytes coming */
|
||||
size_t fmt_asn1dertag_scratch(char* dest,unsigned long long l) __pure__;/* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
att_write(1)
|
||||
size_t fmt_utf8(char* dest,uint32_t n) noexcept; /* can store 0-0x7fffffff */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_utf8_scratch(char* dest,uint32_t n) noexcept; /* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_asn1derlength(char* dest,unsigned long long l) noexcept; /* 0-0x7f: 1 byte, above that 1+bytes_needed bytes */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_asn1derlength_scratch(char* dest,unsigned long long l) noexcept; /* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_asn1dertag(char* dest,unsigned long long l) noexcept; /* 1 byte for each 7 bits; upper bit = more bytes coming */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_asn1dertag_scratch(char* dest,unsigned long long l) noexcept;/* same, but is allowed to overwrite up to 7 additional bytes */
|
||||
|
||||
/* Google Protocol Buffers, https://developers.google.com/protocol-buffers/docs/encoding */
|
||||
size_t fmt_varint(char* dest,unsigned long long l) __pure__; /* protocol buffers encoding; like asn1dertag but little endian */
|
||||
size_t fmt_pb_tag(char* dest,size_t fieldno,unsigned char type) __pure__; /* protocol buffer tag */
|
||||
size_t fmt_pb_type0_int(char* dest,unsigned long long l) __pure__; /* protocol buffers encoding: type 0 bool/enum/int32/uint32/int64/uint64 */
|
||||
size_t fmt_pb_type0_sint(char* dest,signed long long l) __pure__;/* protocol buffers encoding: type 0 sint32/sint64 */
|
||||
size_t fmt_pb_type1_double(char* dest,double d) __pure__; /* protocol buffers encoding: double (64-bit little endian blob) */
|
||||
size_t fmt_pb_type1_fixed64(char* dest,uint64_t l) __pure__; /* protocol buffers encoding: 64-bit little endian blob */
|
||||
att_write(1)
|
||||
size_t fmt_varint(char* dest,unsigned long long l) noexcept; /* protocol buffers encoding; like asn1dertag but little endian */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_tag(char* dest,size_t fieldno,unsigned char type) noexcept; /* protocol buffer tag */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_type0_int(char* dest,unsigned long long l) noexcept; /* protocol buffers encoding: type 0 bool/enum/int32/uint32/int64/uint64 */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_type0_sint(char* dest,signed long long l) noexcept;/* protocol buffers encoding: type 0 sint32/sint64 */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_type1_double(char* dest,double d) noexcept; /* protocol buffers encoding: double (64-bit little endian blob) */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_type1_fixed64(char* dest,uint64_t l) noexcept; /* protocol buffers encoding: 64-bit little endian blob */
|
||||
|
||||
/* fmt_pb_type2_string can return 0 if (s,l) is clearly invalid */
|
||||
size_t fmt_pb_type2_string(char* dest,const char* s,size_t l) __pure__; /* protocol buffers encoding: varint length + blob */
|
||||
size_t fmt_pb_type5_float(char* dest,float f) __pure__; /* protocol buffers encoding: float (32-bit little endian blob) */
|
||||
size_t fmt_pb_type5_fixed32(char* dest,uint32_t l) __pure__; /* protocol buffers encoding: 32-bit little endian blob */
|
||||
att_write(1)
|
||||
size_t fmt_pb_type2_string(char* dest,const char* s,size_t l) noexcept; /* protocol buffers encoding: varint length + blob */
|
||||
|
||||
size_t fmt_pb_int(char* dest,size_t fieldno,unsigned long long l) __pure__;
|
||||
size_t fmt_pb_sint(char* dest,size_t fieldno,signed long long l) __pure__;
|
||||
size_t fmt_pb_double(char* dest,size_t fieldno,double d) __pure__;
|
||||
size_t fmt_pb_float(char* dest,size_t fieldno,float f) __pure__;
|
||||
size_t fmt_pb_string(char* dest,size_t fieldno,const char* s,size_t l) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_pb_type5_float(char* dest,float f) noexcept; /* protocol buffers encoding: float (32-bit little endian blob) */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_type5_fixed32(char* dest,uint32_t l) noexcept; /* protocol buffers encoding: 32-bit little endian blob */
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_int(char* dest,size_t fieldno,unsigned long long l) noexcept;
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_sint(char* dest,size_t fieldno,signed long long l) noexcept;
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_double(char* dest,size_t fieldno,double d) noexcept;
|
||||
|
||||
att_write(1)
|
||||
size_t fmt_pb_float(char* dest,size_t fieldno,float f) noexcept;
|
||||
|
||||
att_writen(1,4)
|
||||
size_t fmt_pb_string(char* dest,size_t fieldno,const char* s,size_t l) noexcept;
|
||||
|
||||
/* fmt_netstring can return 0 if (src,len) is clearly invalid */
|
||||
size_t fmt_netstring(char* dest,const char* src,size_t len) __pure__;
|
||||
att_writen(1,3)
|
||||
size_t fmt_netstring(char* dest,const char* src,size_t len) noexcept;
|
||||
|
||||
/* Marshaling helper functions.
|
||||
* Escape one character, no matter if it needs escaping or not.
|
||||
@ -199,27 +255,36 @@ size_t fmt_netstring(char* dest,const char* src,size_t len) __pure__;
|
||||
* unicode codepoint) may be limited to 0x7f, 0xff or 0x10ffff. */
|
||||
|
||||
/* XML escaping: '&' -> '&', '<' -> '<', 'ö' -> 'ö' */
|
||||
size_t fmt_escapecharxml(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharxml(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* HTML escaping is the same as XML escaping. */
|
||||
size_t fmt_escapecharhtml(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharhtml(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* JSON escaping: '\' -> '\\', '"' -> '\"', 'ö' -> '\u00f6' */
|
||||
size_t fmt_escapecharjson(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharjson(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* MIME quoted-printable escaping: 'ö' -> '=f6', characters > 0xff not supported */
|
||||
size_t fmt_escapecharquotedprintable(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharquotedprintable(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* MIME quoted-printable escaping with UTF-8: 'ö' -> '=c3=b6', characters > 0x7fffffff not supported */
|
||||
size_t fmt_escapecharquotedprintableutf8(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharquotedprintableutf8(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* C99 style escaping: '\' -> '\\', newline -> '\n', 0xc2 -> '\302' */
|
||||
size_t fmt_escapecharc(char* dest,uint32_t ch) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_escapecharc(char* dest,uint32_t ch) noexcept;
|
||||
|
||||
/* internal functions, may be independently useful */
|
||||
char fmt_tohex(char c) __attribute__((__const__));
|
||||
att_const
|
||||
char fmt_tohex(char c);
|
||||
|
||||
#define fmt_strm(b,...) fmt_strm_internal(b,__VA_ARGS__,(char*)0)
|
||||
size_t fmt_strm_internal(char* dest,...) __pure__;
|
||||
att_write(1)
|
||||
size_t fmt_strm_internal(char* dest,...) noexcept;
|
||||
|
||||
#ifndef MAX_ALLOCA
|
||||
#define MAX_ALLOCA 100000
|
||||
|
2
iarray.h
2
iarray.h
@ -9,7 +9,7 @@
|
||||
* - the compiler supports it via __sync_val_compare_and_swap
|
||||
*/
|
||||
|
||||
#include "uint64.h"
|
||||
#include <libowfat/uint64.h>
|
||||
#include <stddef.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
38
io.h
38
io.h
@ -4,8 +4,9 @@
|
||||
|
||||
/* http://cr.yp.to/lib/io.html */
|
||||
|
||||
#include "uint64.h"
|
||||
#include "taia.h"
|
||||
#include <libowfat/uint64.h>
|
||||
#include <libowfat/taia.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -13,33 +14,52 @@ extern "C" {
|
||||
|
||||
/* like open(s,O_RDONLY) */
|
||||
/* return 1 if ok, 0 on error */
|
||||
int io_readfile(int64* d,const char* s);
|
||||
att_read(2)
|
||||
att_write(1)
|
||||
int io_readfile(int64* d,const char* filename);
|
||||
|
||||
/* like open(s,O_WRONLY|O_CREAT|O_TRUNC,0600) */
|
||||
/* return 1 if ok, 0 on error */
|
||||
int io_createfile(int64* d,const char* s);
|
||||
att_read(2)
|
||||
att_write(1)
|
||||
int io_createfile(int64* d,const char* filename);
|
||||
|
||||
/* like open(s,O_RDWR) */
|
||||
/* return 1 if ok, 0 on error */
|
||||
int io_readwritefile(int64* d,const char* s);
|
||||
att_read(2)
|
||||
att_write(1)
|
||||
int io_readwritefile(int64* d,const char* filename);
|
||||
|
||||
/* like open(s,O_WRONLY|O_APPEND|O_CREAT,0600) */
|
||||
/* return 1 if ok, 0 on error */
|
||||
int io_appendfile(int64* d,const char* s);
|
||||
att_read(2)
|
||||
att_write(1)
|
||||
int io_appendfile(int64* d,const char* filename);
|
||||
|
||||
/* like pipe(d) */
|
||||
/* return 1 if ok, 0 on error */
|
||||
att_write(1)
|
||||
int io_pipe(int64* d);
|
||||
|
||||
/* like socketpair() */
|
||||
/* return 1 if ok, 0 on error */
|
||||
att_write(1)
|
||||
int io_socketpair(int64* d);
|
||||
|
||||
/* non-blocking read(), -1 for EAGAIN and -3+errno for other errors */
|
||||
att_writen(2, 3)
|
||||
int64 io_tryread(int64 d,char* buf,int64 len);
|
||||
|
||||
/* blocking read(), with -3 instead of -1 for errors */
|
||||
att_writen(2, 3)
|
||||
int64 io_waitread(int64 d,char* buf,int64 len);
|
||||
|
||||
/* non-blocking write(), -1 for EAGAIN and -3+errno for other errors */
|
||||
att_readn(2, 3)
|
||||
int64 io_trywrite(int64 d,const char* buf,int64 len);
|
||||
|
||||
/* blocking write(), with -3 instead of -1 for errors */
|
||||
att_readn(2, 3)
|
||||
int64 io_waitwrite(int64 d,const char* buf,int64 len);
|
||||
|
||||
/* modify timeout attribute of file descriptor */
|
||||
@ -47,10 +67,12 @@ void io_timeout(int64 d,tai6464 t);
|
||||
|
||||
/* like io_tryread but will return -2,errno=ETIMEDOUT if d has a timeout
|
||||
* associated and it is passed without input being there */
|
||||
att_writen(2, 3)
|
||||
int64 io_tryreadtimeout(int64 d,char* buf,int64 len);
|
||||
|
||||
/* like io_trywrite but will return -2,errno=ETIMEDOUT if d has a timeout
|
||||
* associated and it is passed without being able to write */
|
||||
att_readn(2, 3)
|
||||
int64 io_trywritetimeout(int64 d,const char* buf,int64 len);
|
||||
|
||||
void io_wantread(int64 d);
|
||||
@ -95,7 +117,9 @@ int io_fd(int64 d); /* use this for sockets before you called connect() or acce
|
||||
int io_fd_canwrite(int64 d); /* use this for connected sockets (assumes socket is writable) */
|
||||
int io_fd_flags(int64 d,int flags); /* can be used to tell io_fd to skip one syscall */
|
||||
|
||||
att_write(2)
|
||||
void io_setcookie(int64 d,void* cookie);
|
||||
|
||||
void* io_getcookie(int64 d);
|
||||
|
||||
/* put descriptor in non-blocking mode */
|
||||
@ -128,9 +152,11 @@ int64 io_receivefd(int64 sock);
|
||||
int io_starteventloopthread(unsigned int threads);
|
||||
|
||||
#define HAVE_IO_QUEUEFORREAD
|
||||
|
||||
/* Artificially queue a file descriptor as readable.
|
||||
* The next call to io_canread will return this descriptor. */
|
||||
int io_queueforread(int64 d);
|
||||
|
||||
/* Artificially queue a file descriptor as writable.
|
||||
* The next call to io_canread will return this descriptor. */
|
||||
int io_queueforwrite(int64 d);
|
||||
|
@ -4,10 +4,10 @@ io_appendfile \- open a file for appending
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/io.h>
|
||||
|
||||
int \fBio_appendfile\fP(int64* d,const char* s);
|
||||
int \fBio_appendfile\fP(int64* d,const char* filename);
|
||||
.SH DESCRIPTION
|
||||
io_appendfile sets d to the number of a new descriptor writing to the
|
||||
end of the disk file named \fIs\fR, and returns 1. If the file does not
|
||||
end of the disk file named \fIfilename\fR, and returns 1. If the file does not
|
||||
exist, it will be created with mode 0600.
|
||||
|
||||
If something goes wrong, io_appendfile sets \fIerrno\fR to indicate the error, and
|
||||
|
@ -4,10 +4,10 @@ io_createfile \- create a file
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/io.h>
|
||||
|
||||
int \fBio_createfile\fP(int64* d,const char* s);
|
||||
int \fBio_createfile\fP(int64* d,const char* filename);
|
||||
.SH DESCRIPTION
|
||||
io_createfile sets d to the number of a new descriptor writing to the disk file
|
||||
named \fIs\fR, and returns 1. If \fIs\fR already existed, it is truncated to length 0;
|
||||
named \fIs\fR, and returns 1. If \fIfilename\fR already existed, it is truncated to length 0;
|
||||
otherwise, it is created, with mode 0600.
|
||||
|
||||
If something goes wrong, io_createfile sets \fIerrno\fR to indicate the error, and
|
||||
|
@ -4,10 +4,10 @@ io_readfile \- open a file for reading
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/io.h>
|
||||
|
||||
int \fBio_readfile\fP(int64* d,const char* s);
|
||||
int \fBio_readfile\fP(int64* d,const char* filename);
|
||||
.SH DESCRIPTION
|
||||
io_readfile sets d to the number of a new descriptor reading from the
|
||||
disk file named \fIs\fR, and returns 1.
|
||||
disk file named \fIfilename\fR, and returns 1.
|
||||
|
||||
If something goes wrong, io_readfile sets \fIerrno\fR to indicate the error, and
|
||||
returns 0; it does not create a new descriptor, and it does not touch d.
|
||||
|
@ -4,10 +4,10 @@ io_readfile \- open a file for reading and writing
|
||||
.SH SYNTAX
|
||||
.B #include <libowfat/io.h>
|
||||
|
||||
int \fBio_readwritefile\fP(int64* d,const char* s);
|
||||
int \fBio_readwritefile\fP(int64* d,const char* filename);
|
||||
.SH DESCRIPTION
|
||||
io_readwritefile sets d to the number of a new descriptor reading from
|
||||
and writing to the disk file named \fIs\fR, and returns 1. The file
|
||||
and writing to the disk file named \fIfilename\fR, and returns 1. The file
|
||||
needs to exist.
|
||||
|
||||
If something goes wrong, io_readwritefile sets \fIerrno\fR to indicate the error, and
|
||||
|
15
iob.h
15
iob.h
@ -13,8 +13,9 @@
|
||||
* frames as possible. On Linux it will also use the TCP_CORK socket
|
||||
* option. */
|
||||
|
||||
#include "libowfat/io.h"
|
||||
#include "libowfat/array.h"
|
||||
#include <libowfat/io.h>
|
||||
#include <libowfat/array.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -27,10 +28,20 @@ typedef struct io_batch {
|
||||
} io_batch;
|
||||
|
||||
io_batch* iob_new(int hint_entries);
|
||||
|
||||
att_readn(2,3)
|
||||
int iob_addbuf(io_batch* b,const void* buf,uint64 n);
|
||||
|
||||
att_readn(2,3)
|
||||
int iob_addbuf_free(io_batch* b,const void* buf,uint64 n);
|
||||
|
||||
att_readn(2,3)
|
||||
int iob_addbuf_munmap(io_batch* b,const void* buf,uint64 n);
|
||||
|
||||
att_read(2)
|
||||
int iob_adds(io_batch* b,const char* s);
|
||||
|
||||
att_read(2)
|
||||
int iob_adds_free(io_batch* b,const char* s);
|
||||
int iob_addfile(io_batch* b,int64 fd,uint64 off,uint64 n);
|
||||
int iob_addfile_close(io_batch* b,int64 fd,uint64 off,uint64 n);
|
||||
|
4
ip6.h
4
ip6.h
@ -2,8 +2,8 @@
|
||||
#ifndef IP6_H
|
||||
#define IP6_H
|
||||
|
||||
#include "byte.h"
|
||||
#include "uint32.h"
|
||||
#include <libowfat/byte.h>
|
||||
#include <libowfat/uint32.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
8
open.h
8
open.h
@ -6,11 +6,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
/* open filename for reading and return the file handle or -1 on error */
|
||||
att_read(1)
|
||||
int open_read(const char* filename);
|
||||
|
||||
/* create filename for exclusive write only use (mode 0600) and return
|
||||
* the file handle or -1 on error */
|
||||
att_read(1)
|
||||
int open_excl(const char* filename);
|
||||
|
||||
/* open filename for appending write only use (mode 0600)
|
||||
@ -18,19 +22,23 @@ int open_excl(const char* filename);
|
||||
* All write operation will append after the last byte, regardless of
|
||||
* seeking or other processes also appending to the file. The file will
|
||||
* be created if it does not exist. */
|
||||
att_read(1)
|
||||
int open_append(const char* filename);
|
||||
|
||||
/* open filename for writing (mode 0644). Create the file if it does
|
||||
* not exist, truncate it to zero length otherwise. Return the file
|
||||
* handle or -1 on error. */
|
||||
att_read(1)
|
||||
int open_trunc(const char* filename);
|
||||
|
||||
/* open filename for writing. Create the file if it does not exist.
|
||||
* Return the file handle or -1 on error. */
|
||||
att_read(1)
|
||||
int open_write(const char* filename);
|
||||
|
||||
/* open filename for reading and writing. Create file if not there.
|
||||
* Return file handle or -1 on error. */
|
||||
att_read(1)
|
||||
int open_rw(const char* filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -2,12 +2,14 @@
|
||||
#ifndef OPENREADCLOSE_H
|
||||
#define OPENREADCLOSE_H
|
||||
|
||||
#include "stralloc.h"
|
||||
#include <libowfat/compiler.h>
|
||||
#include <libowfat/stralloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
att_read(1)
|
||||
int openreadclose(const char *filename,stralloc *buf,size_t initiallength);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
48
parse.h
48
parse.h
@ -7,6 +7,8 @@
|
||||
/* for uint32_t: */
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#include <libowfat/buffer.h>
|
||||
|
||||
#include <libowfat/uint16.h>
|
||||
@ -63,11 +65,20 @@ struct bytestream {
|
||||
} u;
|
||||
};
|
||||
|
||||
att_write(1)
|
||||
att_read(2)
|
||||
void bs_init_membuf(struct bytestream* bs,const unsigned char* membuf,size_t len);
|
||||
|
||||
att_write(1)
|
||||
att_mangle(2)
|
||||
void bs_init_iobuf(struct bytestream* bs,struct buffer* b);
|
||||
|
||||
att_write(1)
|
||||
att_mangle(2)
|
||||
void bs_init_iobuf_size(struct bytestream* bs,struct buffer* b,size_t maxlen);
|
||||
|
||||
att_write(1)
|
||||
att_mangle(2)
|
||||
void bs_init_bstream_size(struct bytestream* bs,struct bytestream* parent,size_t maxlen);
|
||||
|
||||
#define BS_FROM_MEMBUF(buf,len) { .type=MEMBUF, .max=(len), .u.base=(const unsigned char*)(buf) }
|
||||
@ -75,51 +86,80 @@ void bs_init_bstream_size(struct bytestream* bs,struct bytestream* parent,size_t
|
||||
#define BS_FROM_BUFFER_SIZE(buffer,len) { .type=IOBUF, .max=(len), u.b=(buffer) }
|
||||
|
||||
/* return next byte from stream or 0 if EOF or read error. */
|
||||
att_mangle(1)
|
||||
unsigned char bs_get(struct bytestream* bs);
|
||||
|
||||
/* like bs_get but do not advance position in stream. */
|
||||
// This is NOT read-only because it sets bs to error state if it hits EOF
|
||||
att_mangle(1)
|
||||
unsigned char bs_peek(struct bytestream* bs);
|
||||
|
||||
/* was there a read error or did we attempt to read more than maxlen bytes? */
|
||||
int bs_err(struct bytestream* bs);
|
||||
att_pure
|
||||
att_read(1)
|
||||
int bs_err(const struct bytestream* bs);
|
||||
|
||||
/* mark bytestream as erroneous */
|
||||
att_mangle(1)
|
||||
void bs_seterrorstate(struct bytestream* b);
|
||||
|
||||
/* Can we read this much more bytes from the bytestream? */
|
||||
/* returns 1 for yes, 0 for no */
|
||||
att_pure
|
||||
att_read(1)
|
||||
int bs_capacitycheck(struct bytestream* bs,size_t capacity);
|
||||
|
||||
/* Like bs_capacitycheck but will set stream to error state on fail */
|
||||
att_pure
|
||||
att_mangle(1)
|
||||
int bs_capacityassert(struct bytestream* bs,size_t capacity);
|
||||
|
||||
/* Return number of bytes left before limit, or 0 on error. */
|
||||
/* If the backend is an iobuf without limit, return max size_t value. */
|
||||
size_t bs_capacityleft(struct bytestream* bs);
|
||||
att_pure
|
||||
att_read(1)
|
||||
size_t bs_capacityleft(const struct bytestream* bs);
|
||||
|
||||
/* Assert there are no more bytes left in a bytestream. */
|
||||
/* Useful to make sure that you parsed the whole packet
|
||||
* and there were no slack bytes in the end.
|
||||
* Return 1 if there really were no more bytes in the stream.
|
||||
* If there ARE bytes left, will set error flag in stream and return 0 */
|
||||
att_mangle(1)
|
||||
int bs_nomoredataassert(struct bytestream* bs);
|
||||
|
||||
/* Consume all bytes left before limit */
|
||||
/* Useful for nested structs or when the backing store is an iobuf */
|
||||
/* Return number of bytes consumed */
|
||||
att_mangle(1)
|
||||
size_t bs_consumeleftovers(struct bytestream* bs);
|
||||
|
||||
/* Skip n bytes, return number skipped (or 0 if error) */
|
||||
att_mangle(1)
|
||||
size_t bs_skip(struct bytestream* bs, size_t n);
|
||||
|
||||
/* Read n bytes from stream. Return n.
|
||||
* Set stream to error state if not enough space or I/O error. */
|
||||
att_mangle(1)
|
||||
att_writen(2,3)
|
||||
ssize_t prs_readblob(struct bytestream* bs,unsigned char* dest,size_t destlen);
|
||||
|
||||
att_mangle(1)
|
||||
uint16_t prs_u16(struct bytestream* bs);
|
||||
|
||||
att_mangle(1)
|
||||
uint16_t prs_u16_big(struct bytestream* bs);
|
||||
|
||||
att_mangle(1)
|
||||
uint32_t prs_u32(struct bytestream* bs);
|
||||
|
||||
att_mangle(1)
|
||||
uint32_t prs_u32_big(struct bytestream* bs);
|
||||
|
||||
att_mangle(1)
|
||||
uint64_t prs_u64(struct bytestream* bs);
|
||||
|
||||
att_mangle(1)
|
||||
uint64_t prs_u64_big(struct bytestream* bs);
|
||||
|
||||
/* Read an asciiz string from the byte stream, up to len bytes (including the 0 terminator). */
|
||||
@ -127,6 +167,8 @@ uint64_t prs_u64_big(struct bytestream* bs);
|
||||
/* If there is no 0 byte in these len bytes, set error flag in stream and return -1. */
|
||||
/* Calling this function with destsize==0 is an error. */
|
||||
/* destsize will be clamped to the maximum number representable in ssize_t */
|
||||
att_mangle(1)
|
||||
att_writen(2, 3)
|
||||
ssize_t prs_asciiz(struct bytestream* bs, char* dest, size_t destsize);
|
||||
|
||||
/* Some protocols have a fixed field length for a string,
|
||||
@ -137,6 +179,8 @@ ssize_t prs_asciiz(struct bytestream* bs, char* dest, size_t destsize);
|
||||
* For a field of length 8, you need to pass destsize as 9 so we can add
|
||||
* a 0 terminator. This function will consume the 8 bytes and add a 0 byte.
|
||||
* The return value is strlen(dest). */
|
||||
att_mangle(1)
|
||||
att_writen(2, 3)
|
||||
ssize_t prs_asciiz_fixedlen(struct bytestream* bs, char* dest, size_t destsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -105,16 +107,20 @@ __static inline __gnuinline int range_bufinbuf(const void* buf1,size_t len1,cons
|
||||
|
||||
/* does an array of "elements" members of size "membersize" starting at
|
||||
* "arraystart" lie inside buf1[0..len-1]? */
|
||||
att_const
|
||||
int range_arrayinbuf(const void* buf,size_t len,
|
||||
const void* arraystart,size_t elements,size_t membersize);
|
||||
|
||||
/* does an ASCIIZ string starting at "ptr" lie in buf[0..len-1]? */
|
||||
att_const
|
||||
int range_strinbuf(const void* buf,size_t len,const void* stringstart);
|
||||
|
||||
/* does an UTF-16 string starting at "ptr" lie in buf[0..len-1]? */
|
||||
att_const
|
||||
int range_str2inbuf(const void* buf,size_t len,const void* stringstart);
|
||||
|
||||
/* does an UTF-32 string starting at "ptr" lie in buf[0..len-1]? */
|
||||
att_const
|
||||
int range_str4inbuf(const void* buf,size_t len,const void* stringstart);
|
||||
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
#ifndef SAFEMULT_H
|
||||
#define SAFEMULT_H
|
||||
|
||||
#include "uint16.h"
|
||||
#include "uint32.h"
|
||||
#include "uint64.h"
|
||||
#include <libowfat/uint16.h>
|
||||
#include <libowfat/uint32.h>
|
||||
#include <libowfat/uint64.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
148
scan.h
148
scan.h
@ -11,20 +11,12 @@
|
||||
/* for struct timespec: */
|
||||
#include <time.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* dietlibc defines these in sys/cdefs.h, which is included from stddef.h */
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
|
||||
#ifndef __writememsz__
|
||||
#define __writememsz__(a,b)
|
||||
#define __readmemsz__(a,b)
|
||||
#endif
|
||||
|
||||
/* This file declares functions used to decode / scan / unmarshal
|
||||
* integer or string values from a buffer.
|
||||
* The first argument is always the source buffer, the second argument
|
||||
@ -44,72 +36,90 @@ extern "C" {
|
||||
* NB: will detect integer overflow and abort on excessively large
|
||||
* values, i.e. on a 32-bit system:
|
||||
* scan_ulong("4294967296",&i" -> i=429496729, return 9 */
|
||||
size_t scan_ulong(const char *src,unsigned long *dest);
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_ulongn(const char* src,size_t n,unsigned long* dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_ulong(const char *src,unsigned long *dest) noexcept;
|
||||
att_readn(1,2) att_write(3)
|
||||
size_t scan_ulongn(const char* src,size_t n,unsigned long* dest) noexcept;
|
||||
|
||||
/* Interpret src as ASCII hexadecimal number, write number to dest and
|
||||
* return the number of bytes that were parsed.
|
||||
* Note: leading '+' or '-' not accepted! */
|
||||
size_t scan_xlong(const char *src,unsigned long *dest);
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_xlongn(const char *src,size_t n,unsigned long *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_xlong(const char *src,unsigned long *dest) noexcept;
|
||||
att_readn(1,2) att_write(3)
|
||||
size_t scan_xlongn(const char *src,size_t n,unsigned long *dest) noexcept;
|
||||
|
||||
/* interpret src as ASCII octal number, write number to dest and
|
||||
* return the number of bytes that were parsed.
|
||||
* Note: leading '+' or '-' not accepted! */
|
||||
size_t scan_8long(const char *src,unsigned long *dest);
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_8longn(const char *src,size_t n,unsigned long *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_8long(const char *src,unsigned long *dest) noexcept;
|
||||
att_readn(1,2) att_write(3)
|
||||
size_t scan_8longn(const char *src,size_t n,unsigned long *dest) noexcept;
|
||||
|
||||
/* interpret src as signed ASCII decimal number, write number to dest
|
||||
* and return the number of bytes that were parsed.
|
||||
* Note: leading spaces not accepted! */
|
||||
size_t scan_long(const char *src,signed long *dest);
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_longn(const char *src,size_t n,signed long *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_long(const char *src,signed long *dest) noexcept;
|
||||
att_readn(1,2) att_write(3)
|
||||
size_t scan_longn(const char *src,size_t n,signed long *dest) noexcept;
|
||||
|
||||
size_t scan_longlong(const char *src,signed long long *dest);
|
||||
size_t scan_ulonglong(const char *src,unsigned long long *dest);
|
||||
size_t scan_xlonglong(const char *src,unsigned long long *dest);
|
||||
size_t scan_8longlong(const char *src,unsigned long long *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_longlong(const char *src,signed long long *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_ulonglong(const char *src,unsigned long long *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_xlonglong(const char *src,unsigned long long *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_8longlong(const char *src,unsigned long long *dest) noexcept;
|
||||
|
||||
size_t scan_uint(const char *src,unsigned int *dest);
|
||||
size_t scan_xint(const char *src,unsigned int *dest);
|
||||
size_t scan_8int(const char *src,unsigned int *dest);
|
||||
size_t scan_int(const char *src,signed int *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_uint(const char *src,unsigned int *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_xint(const char *src,unsigned int *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_8int(const char *src,unsigned int *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_int(const char *src,signed int *dest) noexcept;
|
||||
|
||||
size_t scan_ushort(const char *src,unsigned short *dest);
|
||||
size_t scan_xshort(const char *src,unsigned short *dest);
|
||||
size_t scan_8short(const char *src,unsigned short *dest);
|
||||
size_t scan_short(const char *src,signed short *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_ushort(const char *src,unsigned short *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_xshort(const char *src,unsigned short *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_8short(const char *src,unsigned short *dest) noexcept;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_short(const char *src,signed short *dest) noexcept;
|
||||
|
||||
/* interpret src as double precision floating point number,
|
||||
* write number to dest and return the number of bytes that were parsed */
|
||||
size_t scan_double(const char *in, double *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_double(const char *in, double *dest) noexcept;
|
||||
|
||||
/* if *src=='-', set *dest to -1 and return 1.
|
||||
* if *src=='+', set *dest to 1 and return 1.
|
||||
* otherwise set *dest to 1 return 0. */
|
||||
size_t scan_plusminus(const char *src,signed int *dest);
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_plusminus(const char *src,signed int *dest) noexcept;
|
||||
|
||||
/* return the highest integer n<=limit so that isspace(in[i]) for all 0<=i<=n */
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_whitenskip(const char *in,size_t limit) __pure__;
|
||||
att_pure att_readn(1,2)
|
||||
size_t scan_whitenskip(const char *in,size_t limit) noexcept;
|
||||
|
||||
/* return the highest integer n<=limit so that !isspace(in[i]) for all 0<=i<=n */
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_nonwhitenskip(const char *in,size_t limit) __pure__;
|
||||
att_pure att_readn(1,2)
|
||||
size_t scan_nonwhitenskip(const char *in,size_t limit) noexcept;
|
||||
|
||||
/* return the highest integer n<=limit so that in[i] is element of
|
||||
* charset (ASCIIZ string) for all 0<=i<=n */
|
||||
__readmemsz__(1,3)
|
||||
size_t scan_charsetnskip(const char *in,const char *charset,size_t limit) __pure__;
|
||||
att_pure att_readn(1,3) att_read(2)
|
||||
size_t scan_charsetnskip(const char *in,const char *charset,size_t limit) noexcept;
|
||||
|
||||
/* return the highest integer n<=limit so that in[i] is not element of
|
||||
* charset (ASCIIZ string) for all 0<=i<=n */
|
||||
__readmemsz__(1,3)
|
||||
size_t scan_noncharsetnskip(const char *in,const char *charset,size_t limit) __pure__;
|
||||
att_pure att_readn(1,3) att_read(2)
|
||||
size_t scan_noncharsetnskip(const char *in,const char *charset,size_t limit) noexcept;
|
||||
|
||||
/* try to parse ASCII GMT date; does not understand time zones. */
|
||||
/* example dates:
|
||||
@ -117,17 +127,23 @@ size_t scan_noncharsetnskip(const char *in,const char *charset,size_t limit) __p
|
||||
* "Sunday, 06-Nov-94 08:49:37 GMT"
|
||||
* "Sun Nov 6 08:49:37 1994"
|
||||
*/
|
||||
size_t scan_httpdate(const char *in,time_t *t) __pure__;
|
||||
att_read(1) att_write(2)
|
||||
size_t scan_httpdate(const char *in,time_t *t) noexcept;
|
||||
|
||||
/* try to parse ASCII ISO-8601 date; does not understand time zones. */
|
||||
/* example date: "2014-05-27T19:22:16Z" */
|
||||
size_t scan_iso8601(const char* in,struct timespec* t) __pure__;
|
||||
att_pure att_read(1) att_write(2)
|
||||
size_t scan_iso8601(const char* in,struct timespec* t) noexcept;
|
||||
|
||||
/* some variable length encodings for integers */
|
||||
size_t scan_utf8(const char* in,size_t len,uint32_t* n) __pure__;
|
||||
size_t scan_utf8_sem(const char* in,size_t len,uint32_t* n) __pure__;
|
||||
size_t scan_asn1derlength(const char* in,size_t len,unsigned long long* n) __pure__;
|
||||
size_t scan_asn1dertag(const char* in,size_t len,unsigned long long* n) __pure__;
|
||||
att_pure att_readn(1, 2) att_write(3)
|
||||
size_t scan_utf8(const char* in,size_t len,uint32_t* n) noexcept;
|
||||
att_pure att_readn(1, 2) att_write(3)
|
||||
size_t scan_utf8_sem(const char* in,size_t len,uint32_t* n) noexcept;
|
||||
att_pure att_readn(1, 2) att_write(3)
|
||||
size_t scan_asn1derlength(const char* in,size_t len,unsigned long long* n) noexcept;
|
||||
att_pure att_readn(1, 2) att_write(3)
|
||||
size_t scan_asn1dertag(const char* in,size_t len,unsigned long long* n) noexcept;
|
||||
|
||||
/* Google protocol buffers */
|
||||
/* A protocol buffer is a sequence of (tag,value).
|
||||
@ -136,15 +152,21 @@ size_t scan_asn1dertag(const char* in,size_t len,unsigned long long* n) __pure__
|
||||
* 0, double type 1, strings type 2 and floats type 5. However, you
|
||||
* have to check this yourself.
|
||||
*/
|
||||
size_t scan_varint(const char* in,size_t len, unsigned long long* n) __pure__; /* internal */
|
||||
size_t scan_pb_tag(const char* in,size_t len, size_t* fieldno,unsigned char* type) __pure__;
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_varint(const char* in, size_t len, unsigned long long* n); /* internal */
|
||||
att_readn(1, 2) att_write(3) att_write(4)
|
||||
size_t scan_pb_tag(const char* in, size_t len, size_t* fieldno,unsigned char* type);
|
||||
|
||||
/* Then, depending on the field number, validate the type and call the
|
||||
* corresponding of these functions to parse the value */
|
||||
size_t scan_pb_type0_int(const char* in,size_t len,unsigned long long* l) __pure__;
|
||||
size_t scan_pb_type0_sint(const char* in,size_t len,signed long long* l) __pure__;
|
||||
size_t scan_pb_type1_double(const char* in,size_t len,double* d) __pure__;
|
||||
size_t scan_pb_type1_fixed64(const char* in,size_t len,uint64_t* b) __pure__;
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type0_int(const char* in,size_t len,unsigned long long* l);
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type0_sint(const char* in,size_t len,signed long long* l);
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type1_double(const char* in,size_t len,double* d);
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type1_fixed64(const char* in,size_t len,uint64_t* b);
|
||||
/* NOTE: scan_pb_type2_stringlen only parses the length of the string,
|
||||
* not the string itself. It will return the number of bytes parsed in
|
||||
* the length, then set slen to the value of the length integer it just
|
||||
@ -155,9 +177,12 @@ size_t scan_pb_type1_fixed64(const char* in,size_t len,uint64_t* b) __pure__;
|
||||
* parsing early without having to read and allocate memory for the rest
|
||||
* (potentially gigabytes) of the data announced by one unreasonable
|
||||
* string length value. */
|
||||
size_t scan_pb_type2_stringlen(const char* in,size_t len,const char** string, size_t* slen) __pure__;
|
||||
size_t scan_pb_type5_float(const char* in,size_t len,float* f) __pure__;
|
||||
size_t scan_pb_type5_fixed32(const char* in,size_t len,uint32_t* b) __pure__;
|
||||
att_readn(1, 2) att_write(3) att_write(4)
|
||||
size_t scan_pb_type2_stringlen(const char* in,size_t len,const char** string, size_t* slen);
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type5_float(const char* in,size_t len,float* f);
|
||||
att_readn(1, 2) att_write(3)
|
||||
size_t scan_pb_type5_fixed32(const char* in,size_t len,uint32_t* b);
|
||||
|
||||
/* parse a netstring, input buffer is in (len bytes).
|
||||
* if parsing is successful:
|
||||
@ -167,11 +192,12 @@ size_t scan_pb_type5_fixed32(const char* in,size_t len,uint32_t* b) __pure__;
|
||||
* return 0
|
||||
* Note: *dest will point inside the input buffer!
|
||||
*/
|
||||
__readmemsz__(1,2)
|
||||
size_t scan_netstring(const char* in,size_t len,char** dest,size_t* slen) __pure__;
|
||||
att_readn(1, 2) att_write(3) att_write(4)
|
||||
size_t scan_netstring(const char* in,size_t len,char** dest,size_t* slen);
|
||||
|
||||
/* internal function that might be useful independently */
|
||||
/* convert from hex ASCII, return 0 to 15 for success or -1 for failure */
|
||||
att_const
|
||||
int scan_fromhex(unsigned char c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
14
socket.h
14
socket.h
@ -4,8 +4,9 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "uint16.h"
|
||||
#include "uint32.h"
|
||||
#include <libowfat/compiler.h>
|
||||
#include <libowfat/uint16.h>
|
||||
#include <libowfat/uint32.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -38,12 +39,21 @@ int socket_bind6_reuse(int s,const char* ip,uint16 port,uint32 scope_id);
|
||||
int socket_listen(int s,unsigned int backlog);
|
||||
int socket_accept4(int s,char* ip,uint16* port);
|
||||
int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id);
|
||||
|
||||
att_writen(2,3) att_nonnull(2)
|
||||
ssize_t socket_recv4(int s,char* buf,size_t len,char* ip,uint16* port);
|
||||
att_writen(2,3) att_nonnull(2)
|
||||
ssize_t socket_recv6(int s,char* buf,size_t len,char* ip,uint16* port,uint32* scope_id);
|
||||
|
||||
att_readn(2,3) att_nonnull(2)
|
||||
ssize_t socket_send4(int s,const char* buf,size_t len,const char* ip,uint16 port);
|
||||
att_readn(2,3) att_nonnull(2)
|
||||
ssize_t socket_send4_flag(int s,const char* buf,size_t len,const char* ip,uint16 port,int flags);
|
||||
att_readn(2,3) att_nonnull(2)
|
||||
ssize_t socket_send6(int s,const char* buf,size_t len,const char* ip,uint16 port,uint32 scope_id);
|
||||
att_readn(2,3) att_nonnull(2)
|
||||
ssize_t socket_send6_flag(int s,const char* buf,size_t len,const char* ip,uint16 port,uint32 scope_id,int flags);
|
||||
|
||||
int socket_local4(int s,char* ip,uint16* port);
|
||||
int socket_local6(int s,char* ip,uint16* port,uint32* scope_id);
|
||||
int socket_remote4(int s,char* ip,uint16* port);
|
||||
|
27
str.h
27
str.h
@ -4,24 +4,24 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
|
||||
/* str_copy copies leading bytes from in to out until \0.
|
||||
* return number of copied bytes. */
|
||||
size_t str_copy(char *out,const char *in);
|
||||
att_write(1) att_read(2)
|
||||
size_t str_copy(char *out,const char *in) noexcept;
|
||||
|
||||
/* str_diff returns negative, 0, or positive, depending on whether the
|
||||
* string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than,
|
||||
* equal to, or greater than the string b[0], b[1], ..., b[m-1]=='\0'.
|
||||
* If the strings are different, str_diff does not read bytes past the
|
||||
* first difference. */
|
||||
int str_diff(const char *a,const char *b) __pure__;
|
||||
att_pure att_read(1) att_read(2)
|
||||
int str_diff(const char *a,const char *b) noexcept;
|
||||
|
||||
/* str_diffn returns negative, 0, or positive, depending on whether the
|
||||
* string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than,
|
||||
@ -29,24 +29,29 @@ int str_diff(const char *a,const char *b) __pure__;
|
||||
* If the strings are different, str_diffn does not read bytes past the
|
||||
* first difference. The strings will be considered equal if the first
|
||||
* limit characters match. */
|
||||
int str_diffn(const char *a,const char *b,size_t limit) __pure__;
|
||||
att_pure att_read(1) att_read(2)
|
||||
int str_diffn(const char *a,const char *b,size_t limit) noexcept;
|
||||
|
||||
#ifdef __dietlibc__
|
||||
#include <string.h>
|
||||
#define str_len(foo) strlen(foo)
|
||||
#else
|
||||
/* str_len returns the index of \0 in s */
|
||||
size_t str_len(const char *s) __pure__;
|
||||
att_pure att_read(1)
|
||||
size_t str_len(const char *s) noexcept;
|
||||
#endif
|
||||
|
||||
/* str_chr returns the index of the first occurance of needle or \0 in haystack */
|
||||
size_t str_chr(const char *haystack,char needle) __pure__;
|
||||
att_pure att_read(1)
|
||||
size_t str_chr(const char *haystack,char needle) noexcept;
|
||||
|
||||
/* str_rchr returns the index of the last occurance of needle or \0 in haystack */
|
||||
size_t str_rchr(const char *haystack,char needle) __pure__;
|
||||
att_pure att_read(1)
|
||||
size_t str_rchr(const char *haystack,char needle) noexcept;
|
||||
|
||||
/* str_start returns 1 if the b is a prefix of a, 0 otherwise */
|
||||
int str_start(const char *a,const char *b) __pure__;
|
||||
att_pure att_read(1) att_read(2)
|
||||
int str_start(const char *a,const char *b) noexcept;
|
||||
|
||||
/* convenience shortcut to test for string equality */
|
||||
#define str_equal(s,t) (!str_diff((s),(t)))
|
||||
|
66
stralloc.h
66
stralloc.h
@ -4,20 +4,12 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* dietlibc defines these in sys/cdefs.h, which is included from stddef.h */
|
||||
#ifndef __pure__
|
||||
#define __pure__
|
||||
#endif
|
||||
|
||||
#ifndef __writememsz__
|
||||
#define __writememsz__(a,b)
|
||||
#define __readmemsz__(a,b)
|
||||
#endif
|
||||
|
||||
/* stralloc is the internal data structure all functions are working on.
|
||||
* s is the string.
|
||||
* len is the used length of the string.
|
||||
@ -33,7 +25,7 @@ typedef struct stralloc {
|
||||
/* stralloc_init will initialize a stralloc.
|
||||
* Previously allocated memory will not be freed; use stralloc_free for
|
||||
* that. To assign an empty string, use stralloc_copys(sa,""). */
|
||||
void stralloc_init(stralloc* sa);
|
||||
void stralloc_init(stralloc* sa) noexcept;
|
||||
|
||||
/* stralloc_ready makes sure that sa has enough space allocated to hold
|
||||
* len bytes: If sa is not allocated, stralloc_ready allocates at least
|
||||
@ -42,53 +34,56 @@ void stralloc_init(stralloc* sa);
|
||||
* bytes of space, copies the old string into the new space, frees the
|
||||
* old space, and returns 1. Note that this changes sa.s. If the
|
||||
* allocation fails, stralloc_ready leaves sa alone and returns 0. */
|
||||
int stralloc_ready(stralloc* sa,size_t len);
|
||||
int stralloc_ready(stralloc* sa,size_t len) noexcept;
|
||||
|
||||
/* stralloc_readyplus is like stralloc_ready except that, if sa is
|
||||
* already allocated, stralloc_readyplus adds the current length of sa
|
||||
* to len. */
|
||||
int stralloc_readyplus(stralloc* sa,size_t len);
|
||||
int stralloc_readyplus(stralloc* sa,size_t len) noexcept;
|
||||
|
||||
/* stralloc_copyb copies the string buf[0], buf[1], ..., buf[len-1] into
|
||||
* sa, allocating space if necessary, and returns 1. If it runs out of
|
||||
* memory, stralloc_copyb leaves sa alone and returns 0. */
|
||||
__readmemsz__(2,3)
|
||||
int stralloc_copyb(stralloc* sa,const char* buf,size_t len);
|
||||
att_readn(2, 3)
|
||||
int stralloc_copyb(stralloc* sa,const char* buf,size_t len) noexcept;
|
||||
|
||||
/* stralloc_copys copies a \0-terminated string from buf into sa,
|
||||
* without the \0. It is the same as
|
||||
* stralloc_copyb(&sa,buf,str_len(buf)). */
|
||||
int stralloc_copys(stralloc* sa,const char* buf);
|
||||
att_read(2)
|
||||
int stralloc_copys(stralloc* sa,const char* buf) noexcept;
|
||||
|
||||
/* stralloc_copy copies the string stored in sa2 into sa. It is the same
|
||||
* as stralloc_copyb(&sa,sa2.s,sa2.len). sa2 must already be allocated. */
|
||||
int stralloc_copy(stralloc* sa,const stralloc* sa2);
|
||||
int stralloc_copy(stralloc* sa,const stralloc* sa2) noexcept;
|
||||
|
||||
/* stralloc_catb adds the string buf[0], buf[1], ... buf[len-1] to the
|
||||
* end of the string stored in sa, allocating space if necessary, and
|
||||
* returns 1. If sa is unallocated, stralloc_catb is the same as
|
||||
* stralloc_copyb. If it runs out of memory, stralloc_catb leaves sa
|
||||
* alone and returns 0. */
|
||||
__readmemsz__(2,3)
|
||||
int stralloc_catb(stralloc* sa,const char* in,size_t len);
|
||||
att_readn(2, 3)
|
||||
int stralloc_catb(stralloc* sa,const char* in,size_t len) noexcept;
|
||||
|
||||
/* stralloc_cats is analogous to stralloc_copys */
|
||||
int stralloc_cats(stralloc* sa,const char* in);
|
||||
att_read(2)
|
||||
int stralloc_cats(stralloc* sa,const char* in) noexcept;
|
||||
|
||||
void stralloc_zero(stralloc* sa);
|
||||
void stralloc_zero(stralloc* sa) noexcept;
|
||||
|
||||
/* like stralloc_cats but can cat more than one string at once */
|
||||
int stralloc_catm_internal(stralloc* sa,...);
|
||||
int stralloc_catm_internal(stralloc* sa,...) noexcept;
|
||||
|
||||
#define stralloc_catm(sa,...) stralloc_catm_internal(sa,__VA_ARGS__,(char*)0)
|
||||
#define stralloc_copym(sa,...) (stralloc_zero(sa), stralloc_catm_internal(sa,__VA_ARGS__,(char*)0))
|
||||
|
||||
/* stralloc_cat is analogous to stralloc_copy */
|
||||
int stralloc_cat(stralloc* sa,const stralloc* in);
|
||||
int stralloc_cat(stralloc* sa,const stralloc* in) noexcept;
|
||||
|
||||
/* stralloc_append adds one byte in[0] to the end of the string stored
|
||||
* in sa. It is the same as stralloc_catb(&sa,in,1). */
|
||||
int stralloc_append(stralloc* sa,const char* in); /* beware: this takes a pointer to 1 char */
|
||||
att_read(2)
|
||||
int stralloc_append(stralloc* sa,const char* in) noexcept; /* beware: this takes a pointer to 1 char */
|
||||
|
||||
#if 0
|
||||
#define stralloc_APPEND(sa,in) \
|
||||
@ -109,17 +104,20 @@ static inline int stralloc_APPEND(stralloc* sa,const char* in) {
|
||||
/* stralloc_starts returns 1 if the \0-terminated string in "in", without
|
||||
* the terminating \0, is a prefix of the string stored in sa. Otherwise
|
||||
* it returns 0. sa must already be allocated. */
|
||||
int stralloc_starts(stralloc* sa,const char* in) __pure__;
|
||||
att_pure att_read(2)
|
||||
int stralloc_starts(stralloc* sa,const char* in) noexcept;
|
||||
|
||||
/* stralloc_diff returns negative, 0, or positive, depending on whether
|
||||
* a is lexicographically smaller than, equal to, or greater than the
|
||||
* string b. */
|
||||
int stralloc_diff(const stralloc* a,const stralloc* b) __pure__;
|
||||
att_pure
|
||||
int stralloc_diff(const stralloc* a,const stralloc* b) noexcept;
|
||||
|
||||
/* stralloc_diffs returns negative, 0, or positive, depending on whether
|
||||
* a is lexicographically smaller than, equal to, or greater than the
|
||||
* string b[0], b[1], ..., b[n]=='\0'. */
|
||||
int stralloc_diffs(const stralloc* a,const char* b) __pure__;
|
||||
att_pure att_read(2)
|
||||
int stralloc_diffs(const stralloc* a,const char* b) noexcept;
|
||||
|
||||
#define stralloc_equal(a,b) (!stralloc_diff((a),(b)))
|
||||
#define stralloc_equals(a,b) (!stralloc_diffs((a),(b)))
|
||||
@ -128,15 +126,15 @@ int stralloc_diffs(const stralloc* a,const char* b) __pure__;
|
||||
#define stralloc_0(sa) stralloc_append(sa,"")
|
||||
|
||||
/* stralloc_catulong0 appends a '0' padded ASCII representation of in */
|
||||
int stralloc_catulong0(stralloc* sa,unsigned long int in,size_t n);
|
||||
int stralloc_catulong0(stralloc* sa,unsigned long int in,size_t n) noexcept;
|
||||
|
||||
/* stralloc_catlong0 appends a '0' padded ASCII representation of in */
|
||||
/* note that the n does not include the sign:
|
||||
* stralloc_catlong0(&sa,-10,4) -> "-0010" */
|
||||
int stralloc_catlong0(stralloc* sa,signed long int in,size_t n);
|
||||
int stralloc_catlong0(stralloc* sa,signed long int in,size_t n) noexcept;
|
||||
|
||||
/* stralloc_free frees the storage associated with sa */
|
||||
void stralloc_free(stralloc* sa);
|
||||
void stralloc_free(stralloc* sa) noexcept;
|
||||
|
||||
#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
|
||||
#define stralloc_catulong(sa,l) (stralloc_catulong0((sa),(l),0))
|
||||
@ -146,10 +144,10 @@ void stralloc_free(stralloc* sa);
|
||||
#define stralloc_catuint(sa,i) (stralloc_catulong0((sa),(i),0))
|
||||
|
||||
/* remove last char. Return removed byte as unsigned char (or -1 if stralloc was empty). */
|
||||
int stralloc_chop(stralloc* sa);
|
||||
int stralloc_chop(stralloc* sa) noexcept;
|
||||
|
||||
/* remove trailing "\r\n", "\n" or "\r". Return number of removed chars (0,1 or 2) */
|
||||
int stralloc_chomp(stralloc* sa);
|
||||
int stralloc_chomp(stralloc* sa) noexcept;
|
||||
|
||||
#ifdef BUFFER_H
|
||||
/* write stralloc to buffer */
|
||||
@ -169,13 +167,13 @@ int buffer_putsaflush(buffer* b,const stralloc* sa);
|
||||
* data is available. */
|
||||
|
||||
/* read token from buffer to stralloc */
|
||||
__readmemsz__(3,4)
|
||||
att_readn(3, 4)
|
||||
int buffer_get_token_sa(buffer* b,stralloc* sa,const char* charset,size_t setlen);
|
||||
/* read line from buffer to stralloc */
|
||||
int buffer_getline_sa(buffer* b,stralloc* sa);
|
||||
|
||||
/* same as buffer_get_token_sa but empty sa first */
|
||||
__readmemsz__(3,4)
|
||||
att_readn(3, 4)
|
||||
int buffer_get_new_token_sa(buffer* b,stralloc* sa,const char* charset,size_t setlen);
|
||||
/* same as buffer_getline_sa but empty sa first */
|
||||
int buffer_getnewline_sa(buffer* b,stralloc* sa);
|
||||
|
2
t.c
2
t.c
@ -37,6 +37,8 @@
|
||||
|
||||
// #define atomic_add(mem,val) asm volatile ("lock; add%z0 %1, %0": "+m" (mem): "ir" (val))
|
||||
|
||||
// compiletimeassert(sizeof(long) == 2);
|
||||
|
||||
int64 writecb(int64 fd,const void* buf,uint64 n) {
|
||||
(void)fd;
|
||||
(void)buf;
|
||||
|
2
tai.h
2
tai.h
@ -4,7 +4,7 @@
|
||||
|
||||
/* Times with 1 second precision */
|
||||
|
||||
#include "uint64.h"
|
||||
#include <libowfat/uint64.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
4
taia.h
4
taia.h
@ -4,8 +4,8 @@
|
||||
|
||||
/* Times with 1 attosecond precision */
|
||||
|
||||
#include "tai.h"
|
||||
#include "uint32.h"
|
||||
#include <libowfat/tai.h>
|
||||
#include <libowfat/uint32.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
60
textcode.h
60
textcode.h
@ -12,71 +12,91 @@ extern "C" {
|
||||
* dest (if dest != NULL), returning the number of bytes written. */
|
||||
|
||||
/* dietlibc defines these in sys/cdefs.h, which is included from stddef.h */
|
||||
#ifndef __writememsz__
|
||||
#ifndef __readmemsz__
|
||||
#define __readmemsz__(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef __writemem__
|
||||
#define __writemem__(a)
|
||||
#endif
|
||||
|
||||
/* Needs len/3*4 bytes */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_uuencoded(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Needs len/3*4 bytes */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_base64(char* dest,const char* src,size_t len);
|
||||
__readmemsz__(2,3)
|
||||
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_base64url(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Worst case: len*3 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_quotedprintable(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Worst case: len*3 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_quotedprintable2(char* dest,const char* src,size_t len,const char* escapeme);
|
||||
|
||||
/* Worst case: len*3 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_urlencoded(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Worst case: len*3 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_urlencoded2(char* dest,const char* src,size_t len,const char* escapeme);
|
||||
|
||||
/* Worst case: len*2 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_yenc(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Needs len*2 bytes */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_hexdump(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Change '<' to '<' and '&' to '&' and '\n' to '<br>'; worst case: len*5 */
|
||||
/* This is meant for outputting text that goes between tags */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_html(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Change '<' to '<' and '&' to '&' and '"' to '"'; worst case: len*6 */
|
||||
/* This is meant for outputting text that goes in a tag argument between double quotes*/
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_html_tagarg(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Change '<' to '<' and '&' to '&'; worst case: len*5 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_xml(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Change '\' to "\\", '\n' to "\n", ^A to "\x01" etc; worst case: len*4 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_cescape(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Worst case: len*4 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_cescape2(char* dest,const char* src,size_t len,const char* escapeme);
|
||||
|
||||
/* Fold whitespace to '_'; this is great for writing fields with
|
||||
* white spaces to a log file and still allow awk to do log analysis */
|
||||
/* Worst case: same size */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_foldwhitespace(char* dest,const char* src,size_t len);
|
||||
|
||||
/* Worst case: len*3 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_ldapescape(char* dest,const char* src,size_t len);
|
||||
__readmemsz__(2,3)
|
||||
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_ldapescape2(char* dest,const char* src,size_t len,const char* escapeme);
|
||||
|
||||
/* Encode JSON string from UTF-8; will backslash-escape the bare minimum.
|
||||
* Invalid UTF-8 in input will output as valid UTF-8 for each byte
|
||||
* Worst case: len*6 */
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_jsonescape(char* dest,const char* src,size_t len);
|
||||
|
||||
__readmemsz__(2,3)
|
||||
__writemem__(1) __readmemsz__(2,3)
|
||||
size_t fmt_base85(char* dest,const char* src,size_t len);
|
||||
|
||||
/* These read one line from src, decode it, and write the result to
|
||||
|
Loading…
x
Reference in New Issue
Block a user