#include #include #include #include "mstorage.h" /* this is tinyldap specific. If the data contains at least one 0-byte, * it is stored in a tinyldap specific encoding: * char 0; * uint32 len; * char data[len] */ ssize_t mstorage_add_bin(mstorage_t* p,const char* s,size_t n) { ssize_t x; if (n >> 31) // limit length to 32-bit SSIZE_MAX return -1; // #range #if 1 // unsigned int i; // static char zero; // char intbuf[4]; if (n==0 || memchr(s,0,n)) { // n+5 can't overflow because we limited to SSIZE_MAX on a size_t x=mstorage_reserve(p,n+5); if (x!=-1) { char* t=p->root+x; *t=0; uint32_pack(t+1,n); memcpy(t+5,s,n); } return x; } else { // regular string; make sure there's a 0-terminator // n-1 doesn't underflow because for n==0 we took the other branch size_t needzero=(s[n-1] != 0); x=mstorage_reserve(p,n+needzero); if (x!=-1) { char* t=p->root+x; memcpy(t,s,n); if (needzero) t[n]=0; } return x; } #else if (n==0 || (n==1 && s[0]==0)) goto encodebinary; for (i=0; i #include "mstorage_add.c" #include "mstorage_init.c" #include "mstorage_unmap.c" int main() { mstorage_t m; mstorage_init(&m); assert(mstorage_add_bin(&m,"foo",(size_t)-1) == -1); // #range assert(mstorage_add_bin(&m,"foo",3) == 0); // make sure 0 byte is added assert(mstorage_add_bin(&m,"bar",3) == 4); // trigger binary header m.used=0; assert(mstorage_add_bin(&m,"f\x00o",3) == 0); assert(m.used == 8); // 0, len, f\0o mstorage_unmap(&m); return 0; } #endif