mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-22 10:10:54 +00:00
Add base64_encodev() multi-buffer Base64 encoder
Also replace base64_encode_len() inline function with macro BASE64_ENCODED_LEN()
This commit is contained in:
parent
b8e0859880
commit
e59a62115b
50
str.c
50
str.c
@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/uio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
@ -86,28 +87,33 @@ const char base64_symbols[64] = {
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
|
||||
size_t base64_encode(char *const dstBase64, const unsigned char *src, size_t srclen)
|
||||
size_t base64_encodev(char *dstBase64, const struct iovec *const iov, int const iovcnt)
|
||||
{
|
||||
char *dst = dstBase64;
|
||||
unsigned place = 0;
|
||||
unsigned char buf = 0;
|
||||
for (; srclen; --srclen, ++src) {
|
||||
switch (place) {
|
||||
case 0:
|
||||
*dst++ = base64_symbols[*src >> 2];
|
||||
buf = (*src << 4) & 0x3f;
|
||||
place = 1;
|
||||
break;
|
||||
case 1:
|
||||
*dst++ = base64_symbols[(*src >> 4) | buf];
|
||||
buf = (*src << 2) & 0x3f;
|
||||
place = 2;
|
||||
break;
|
||||
case 2:
|
||||
*dst++ = base64_symbols[(*src >> 6) | buf];
|
||||
*dst++ = base64_symbols[*src & 0x3f];
|
||||
place = 0;
|
||||
break;
|
||||
int iovc = 0;
|
||||
for (iovc = 0; iovc != iovcnt; ++iovc) {
|
||||
unsigned char *src = iov[iovc].iov_base;
|
||||
size_t cnt = iov[iovc].iov_len;
|
||||
for (; cnt; --cnt, ++src) {
|
||||
switch (place) {
|
||||
case 0:
|
||||
*dst++ = base64_symbols[*src >> 2];
|
||||
buf = (*src << 4) & 0x3f;
|
||||
place = 1;
|
||||
break;
|
||||
case 1:
|
||||
*dst++ = base64_symbols[(*src >> 4) | buf];
|
||||
buf = (*src << 2) & 0x3f;
|
||||
place = 2;
|
||||
break;
|
||||
case 2:
|
||||
*dst++ = base64_symbols[(*src >> 6) | buf];
|
||||
*dst++ = base64_symbols[*src & 0x3f];
|
||||
place = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (place)
|
||||
@ -121,6 +127,14 @@ size_t base64_encode(char *const dstBase64, const unsigned char *src, size_t src
|
||||
return dst - dstBase64;
|
||||
}
|
||||
|
||||
size_t base64_encode(char *const dstBase64, const unsigned char *src, size_t srclen)
|
||||
{
|
||||
struct iovec iov;
|
||||
iov.iov_base = (void *) src;
|
||||
iov.iov_len = srclen;
|
||||
return base64_encodev(dstBase64, &iov, 1);
|
||||
}
|
||||
|
||||
char *to_base64_str(char *const dstBase64, const unsigned char *srcBinary, size_t srcBytes)
|
||||
{
|
||||
dstBase64[base64_encode(dstBase64, srcBinary, srcBytes)] = '\0';
|
||||
|
14
str.h
14
str.h
@ -124,30 +124,32 @@ size_t strn_fromhex(unsigned char *dstBinary, ssize_t dstlen, const char *src, c
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
__SERVAL_DNA_STR_INLINE size_t base64_encode_len(size_t binaryBytes) {
|
||||
return (binaryBytes + 2) / 3 * 4;
|
||||
}
|
||||
#define BASE64_ENCODED_LEN(binaryBytes) (((size_t)(binaryBytes) + 2) / 3 * 4)
|
||||
|
||||
const char base64_symbols[64];
|
||||
|
||||
/* Encode 'srcBytes' bytes of binary data at 'srcBinary' into Base64 representation at 'dstBase64',
|
||||
* which must point to at least 'base64_encode_len(srcBytes)' bytes. The encoding is terminated
|
||||
* which must point to at least 'BASE64_ENCODED_LEN(srcBytes)' bytes. The encoding is terminated
|
||||
* by a "=" or "==" pad to bring the total number of encoded bytes up to a multiple of 4.
|
||||
*
|
||||
* Returns the total number of encoded bytes writtent at 'dstBase64'.
|
||||
*
|
||||
* The base64_encodev() is a multi-buffer gather variant, analagous to readv(2) and writev(2).
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
size_t base64_encode(char *dstBase64, const unsigned char *srcBinary, size_t srcBytes);
|
||||
struct iovec;
|
||||
size_t base64_encodev(char *dstBase64, const struct iovec *iov, int iovcnt);
|
||||
|
||||
/* The same as base64_encode() but appends a terminating NUL character to the encoded string,
|
||||
* so 'dstBase64' must point to at least 'base64_encode_len(srcBytes) + 1' bytes.
|
||||
* so 'dstBase64' must point to at least 'BASE64_ENCODED_LEN(srcBytes) + 1' bytes.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
char *to_base64_str(char *dstBase64, const unsigned char *srcBinary, size_t srcBytes);
|
||||
|
||||
#define alloca_base64(buf,len) to_base64_str(alloca(base64_encode_len(len) + 1), (buf), (len))
|
||||
#define alloca_base64(buf,len) to_base64_str(alloca(BASE64_ENCODED_LEN(len) + 1), (buf), (len))
|
||||
|
||||
/* Decode the string at 'srcBase64' as ASCII Base-64, writing up to 'dstsiz' decoded binary bytes at
|
||||
* 'dstBinary'. Returns the number of decoded binary bytes produced. If 'dstsiz' is zero or
|
||||
|
Loading…
x
Reference in New Issue
Block a user