diff options
author | Russell Belfer <rb@github.com> | 2012-10-11 01:54:31 +0400 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2012-10-11 01:54:31 +0400 |
commit | 2d3579bea699847b560e99a5107b12eac8d172ad (patch) | |
tree | 0c72fd4dc5246c51ffc644f62d1f58d3d46804f3 /src/buffer.c | |
parent | 8ea05f3f8f3485d39ce4a867b353f45c4eebf54e (diff) |
Add git_buf_put_base64 to buffer API
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/buffer.c b/src/buffer.c index 61cfaf9e2..ee2dd2804 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -186,6 +186,46 @@ int git_buf_puts_escaped( return 0; } +static const char b64str[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int git_buf_put_base64(git_buf *buf, const char *data, size_t len) +{ + size_t extra = len % 3; + uint8_t *write, a, b, c; + const uint8_t *read = (const uint8_t *)data; + + ENSURE_SIZE(buf, buf->size + ((len * 4 + 3) / 3) + 1); + write = (uint8_t *)&buf->ptr[buf->size]; + + /* convert each run of 3 bytes into 4 output bytes */ + for (len -= extra; len > 0; len -= 3) { + a = *read++; + b = *read++; + c = *read++; + + *write++ = b64str[a >> 2]; + *write++ = b64str[(a & 0x03) << 4 | b >> 4]; + *write++ = b64str[(b & 0x0f) << 2 | c >> 6]; + *write++ = b64str[c & 0x3f]; + } + + if (extra > 0) { + a = *read++; + b = (extra > 1) ? *read++ : 0; + + *write++ = b64str[a >> 2]; + *write++ = b64str[(a & 0x03) << 4 | b >> 4]; + *write++ = (extra > 1) ? b64str[(b & 0x0f) << 2] : '='; + *write++ = '='; + } + + buf->size = ((char *)write) - buf->ptr; + buf->ptr[buf->size] = '\0'; + + return 0; +} + int git_buf_vprintf(git_buf *buf, const char *format, va_list ap) { int len; |