mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-22 02:06:42 +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 <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.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','+','/'
|
'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;
|
char *dst = dstBase64;
|
||||||
unsigned place = 0;
|
unsigned place = 0;
|
||||||
unsigned char buf = 0;
|
unsigned char buf = 0;
|
||||||
for (; srclen; --srclen, ++src) {
|
int iovc = 0;
|
||||||
switch (place) {
|
for (iovc = 0; iovc != iovcnt; ++iovc) {
|
||||||
case 0:
|
unsigned char *src = iov[iovc].iov_base;
|
||||||
*dst++ = base64_symbols[*src >> 2];
|
size_t cnt = iov[iovc].iov_len;
|
||||||
buf = (*src << 4) & 0x3f;
|
for (; cnt; --cnt, ++src) {
|
||||||
place = 1;
|
switch (place) {
|
||||||
break;
|
case 0:
|
||||||
case 1:
|
*dst++ = base64_symbols[*src >> 2];
|
||||||
*dst++ = base64_symbols[(*src >> 4) | buf];
|
buf = (*src << 4) & 0x3f;
|
||||||
buf = (*src << 2) & 0x3f;
|
place = 1;
|
||||||
place = 2;
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 2:
|
*dst++ = base64_symbols[(*src >> 4) | buf];
|
||||||
*dst++ = base64_symbols[(*src >> 6) | buf];
|
buf = (*src << 2) & 0x3f;
|
||||||
*dst++ = base64_symbols[*src & 0x3f];
|
place = 2;
|
||||||
place = 0;
|
break;
|
||||||
break;
|
case 2:
|
||||||
|
*dst++ = base64_symbols[(*src >> 6) | buf];
|
||||||
|
*dst++ = base64_symbols[*src & 0x3f];
|
||||||
|
place = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (place)
|
if (place)
|
||||||
@ -121,6 +127,14 @@ size_t base64_encode(char *const dstBase64, const unsigned char *src, size_t src
|
|||||||
return dst - dstBase64;
|
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)
|
char *to_base64_str(char *const dstBase64, const unsigned char *srcBinary, size_t srcBytes)
|
||||||
{
|
{
|
||||||
dstBase64[base64_encode(dstBase64, srcBinary, srcBytes)] = '\0';
|
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>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
__SERVAL_DNA_STR_INLINE size_t base64_encode_len(size_t binaryBytes) {
|
#define BASE64_ENCODED_LEN(binaryBytes) (((size_t)(binaryBytes) + 2) / 3 * 4)
|
||||||
return (binaryBytes + 2) / 3 * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char base64_symbols[64];
|
const char base64_symbols[64];
|
||||||
|
|
||||||
/* Encode 'srcBytes' bytes of binary data at 'srcBinary' into Base64 representation at 'dstBase64',
|
/* 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.
|
* 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'.
|
* 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>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
size_t base64_encode(char *dstBase64, const unsigned char *srcBinary, size_t srcBytes);
|
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,
|
/* 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>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
*/
|
*/
|
||||||
char *to_base64_str(char *dstBase64, const unsigned char *srcBinary, size_t srcBytes);
|
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
|
/* 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
|
* 'dstBinary'. Returns the number of decoded binary bytes produced. If 'dstsiz' is zero or
|
||||||
|
Loading…
x
Reference in New Issue
Block a user