diff options
Diffstat (limited to 'blob.c')
-rw-r--r-- | blob.c | 107 |
1 files changed, 104 insertions, 3 deletions
@@ -1,7 +1,81 @@ #include "blob.h" +/* RFC 3986 section 2.3 Unreserved Characters (January 2005) */ +#define CTYPE_UNRESERVED 1 + static const char *xd = "0123456789abcdefghijklmnopqrstuvwxyz"; +static const unsigned char chartype[128] = { + ['a'] = CTYPE_UNRESERVED, + ['b'] = CTYPE_UNRESERVED, + ['c'] = CTYPE_UNRESERVED, + ['d'] = CTYPE_UNRESERVED, + ['e'] = CTYPE_UNRESERVED, + ['f'] = CTYPE_UNRESERVED, + ['g'] = CTYPE_UNRESERVED, + ['h'] = CTYPE_UNRESERVED, + ['i'] = CTYPE_UNRESERVED, + ['j'] = CTYPE_UNRESERVED, + ['k'] = CTYPE_UNRESERVED, + ['l'] = CTYPE_UNRESERVED, + ['m'] = CTYPE_UNRESERVED, + ['n'] = CTYPE_UNRESERVED, + ['o'] = CTYPE_UNRESERVED, + ['p'] = CTYPE_UNRESERVED, + ['q'] = CTYPE_UNRESERVED, + ['r'] = CTYPE_UNRESERVED, + ['s'] = CTYPE_UNRESERVED, + ['t'] = CTYPE_UNRESERVED, + ['u'] = CTYPE_UNRESERVED, + ['v'] = CTYPE_UNRESERVED, + ['w'] = CTYPE_UNRESERVED, + ['x'] = CTYPE_UNRESERVED, + ['y'] = CTYPE_UNRESERVED, + ['z'] = CTYPE_UNRESERVED, + ['A'] = CTYPE_UNRESERVED, + ['B'] = CTYPE_UNRESERVED, + ['C'] = CTYPE_UNRESERVED, + ['D'] = CTYPE_UNRESERVED, + ['E'] = CTYPE_UNRESERVED, + ['F'] = CTYPE_UNRESERVED, + ['G'] = CTYPE_UNRESERVED, + ['H'] = CTYPE_UNRESERVED, + ['I'] = CTYPE_UNRESERVED, + ['J'] = CTYPE_UNRESERVED, + ['K'] = CTYPE_UNRESERVED, + ['L'] = CTYPE_UNRESERVED, + ['M'] = CTYPE_UNRESERVED, + ['N'] = CTYPE_UNRESERVED, + ['O'] = CTYPE_UNRESERVED, + ['P'] = CTYPE_UNRESERVED, + ['Q'] = CTYPE_UNRESERVED, + ['R'] = CTYPE_UNRESERVED, + ['S'] = CTYPE_UNRESERVED, + ['T'] = CTYPE_UNRESERVED, + ['U'] = CTYPE_UNRESERVED, + ['V'] = CTYPE_UNRESERVED, + ['W'] = CTYPE_UNRESERVED, + ['X'] = CTYPE_UNRESERVED, + ['Y'] = CTYPE_UNRESERVED, + ['Z'] = CTYPE_UNRESERVED, + + ['0'] = CTYPE_UNRESERVED, + ['1'] = CTYPE_UNRESERVED, + ['2'] = CTYPE_UNRESERVED, + ['3'] = CTYPE_UNRESERVED, + ['4'] = CTYPE_UNRESERVED, + ['5'] = CTYPE_UNRESERVED, + ['6'] = CTYPE_UNRESERVED, + ['7'] = CTYPE_UNRESERVED, + ['8'] = CTYPE_UNRESERVED, + ['9'] = CTYPE_UNRESERVED, + + ['-'] = CTYPE_UNRESERVED, + ['_'] = CTYPE_UNRESERVED, + ['.'] = CTYPE_UNRESERVED, + ['~'] = CTYPE_UNRESERVED, +}; + static inline int dx(int c) { if (likely(c >= '0' && c <= '9')) @@ -88,13 +162,24 @@ void blob_push(blob_t *b, blob_t d) } } +void blob_push_byte(blob_t *b, unsigned char byte) +{ + if (b->len) { + b->ptr[0] = byte; + b->ptr ++; + b->len --; + } else { + *b = BLOB_NULL; + } +} + void blob_push_uint(blob_t *to, unsigned int value, int radix) { char buf[64]; char *ptr = &buf[sizeof(buf)-1]; if (value == 0) { - blob_push(to, BLOB_STR("0")); + blob_push_byte(to, '0'); return; } @@ -108,7 +193,6 @@ void blob_push_uint(blob_t *to, unsigned int value, int radix) void blob_push_hexdump(blob_t *to, blob_t binary) { - static const char *xd = "0123456789abcdef"; char *d; int i; @@ -145,12 +229,29 @@ void blob_push_urldecode(blob_t *to, blob_t url) blob_shrink_tail(to, blob_pushed(orig, b), '/'); } else { /* copy decoded; FIXME decode percent encoding */ - blob_push(to, BLOB_STR("/")); + blob_push_byte(to, '/'); blob_push(to, b); } } while (1); } +void blob_push_urlencode(blob_t *to, blob_t url) +{ + unsigned char c; + int i; + + for (i = 0; i < url.len; i++) { + c = url.ptr[i]; + + if (c <= 127 && (chartype[c] & CTYPE_UNRESERVED)) { + blob_push_byte(to, c); + } else { + blob_push_byte(to, '%'); + blob_push_uint(to, c, 16); + } + } +} + blob_t blob_pull(blob_t *b, int len) { blob_t r; |