netstring.c (1718B)
1 #include <string.h> 2 #include <assert.h> 3 4 #include <skalibs/uint64.h> 5 #include <skalibs/types.h> 6 #include <skalibs/strerr.h> 7 8 #include "netstring.h" 9 10 void netstring_chunk_init (netstring_chunk *chunk, const bytebuffer source) { 11 memset(chunk, 0, sizeof(netstring_chunk)); 12 chunk->source = source; 13 } 14 15 bool netstring_chunk_next (netstring_chunk *c) { 16 // bytebuffer dbg_bb = {(void*)c, sizeof(netstring_chunk)}; 17 // dbg_print_bb1("netstring chunk", dbg_bb); 18 // dbg_print_bb1("netstring source", c->source); 19 20 if(!c->source.len) { 21 return false; 22 } 23 c->outer.data = c->source.data; 24 c->outer.len /* size of numerical prefix */ = uint64_scan(c->source.data, &c->inner.len); 25 if (c->source.data[c->outer.len] != ':') { 26 strerr_dief1x(111, "Malformed netstring (expected ':')"); 27 } 28 if (c->outer.len + c->inner.len + 2 > c->source.len) { 29 strerr_dief1x(111, "Malformed netstring (truncated)"); 30 } 31 if (c->source.data[c->outer.len + c->inner.len + 1] != ',') { 32 strerr_dief1x(111, "Malformed netstring (expected ',')"); 33 } 34 assert(c->source.len >= c->outer.len); 35 c->inner.data = &c->source.data[c->outer.len + 1]; 36 c->outer.len += c->inner.len + 2; 37 c->source.data += c->outer.len; 38 c->source.len -= c->outer.len; 39 // dbg_print_bb1("Chunk > Outer", c->outer); 40 // dbg_print_bb1("Chunk > Inner", c->inner); 41 return true; 42 } 43 44 size_t netstring_write (bytebuffer *dest, const bytebuffer src) { 45 size_t len; 46 len = size_fmt(dest ? dest->data : NULL, src.len); 47 assert(dest->len >= len + 2 + src.len); 48 dest->len -= len + 2 + src.len; 49 dest->data += len; 50 *(dest->data++) = ':'; 51 memcpy(dest->data, src.data, src.len); 52 dest->data += src.len; 53 *(dest->data++) = ';'; 54 return len + 2 + src.len; 55 }