Commit c508e5e5 authored by Matthieu Dorier's avatar Matthieu Dorier

added serialization/deserialization of bake regions and targets to/from strings

parent 91d8c5a3
......@@ -47,6 +47,49 @@ typedef struct {
*/
void bake_perror(char *s, int ret);
/**
* @brief Converts a target id into an ASCII readable string.
*
* @param tid Target id to convert into a string.
* @param str Resulting string (must be allocated to at least 37 bytes)
* @param size size of the allocated string.
*
* @return error code.
*/
int bake_target_id_to_string(bake_target_id_t tid, char* str, size_t size);
/**
* @brief Converts an ASCI readable representation of the target id into
* and actual target id.
*
* @param str Null-terminated string to read from.
* @param tid Resulting target id.
*
* @return error code.
*/
int bake_target_id_from_string(const char* str, bake_target_id_t* tid);
/**
* @brief Converts the region id into an ASCII readable representation.
*
* @param rid Region id.
* @param str Resulting string, should be preallocated wirg sufficient size.
* @param size size of the preallocated string.
*
* @return error code.
*/
int bake_region_id_to_string(bake_region_id_t rid, char* str, size_t size);
/**
* @brief Converts a string back into a region id.
*
* @param str String to convert.
* @param rid Resulting region id.
*
* @return error code.
*/
int bake_region_id_from_string(const char* str, bake_region_id_t* rid);
/**
* Convert region id into printable string for debugging purposes
*
......
......@@ -2,7 +2,9 @@ noinst_LTLIBRARIES = \
src/libutil.la
src_libutil_la_SOURCES = \
src/util.c
src/util.c \
src/base64/encode.c \
src/base64/decode.c
src_libbake_client_la_SOURCES += \
src/bake-client.c
......
The MIT License (MIT)
Copyright (c) 2014 Little Star Media, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The code in this directory was taken from https://github.com/littlstar/b64.c
and modified by Matthieu Dorier.
/**
* `b64.h' - b64
*
* copyright (c) 2014 joseph werle
*/
#ifndef B64_H
#define B64_H
char* bake_b64_encode(const unsigned char* data, size_t data_size);
unsigned char* bake_b64_decode(const char* str, size_t);
#endif
/**
* `decode.c' - b64
*
* copyright (c) 2014 joseph werle
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "b64.h"
/**
* Base64 index table.
*/
static const char b64_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
static unsigned char *
b64_decode_ex (const char *src, size_t len, size_t *decsize) {
int i = 0;
int j = 0;
int l = 0;
size_t size = 0;
unsigned char *dec = NULL;
unsigned char buf[3];
unsigned char tmp[4];
// alloc
dec = (unsigned char *) malloc(1);
if (NULL == dec) { return NULL; }
// parse until end of source
while (len--) {
// break if char is `=' or not base64 char
if ('=' == src[j]) { break; }
if (!(isalnum(src[j]) || '+' == src[j] || '/' == src[j])) { break; }
// read up to 4 bytes at a time into `tmp'
tmp[i++] = src[j++];
// if 4 bytes read then decode into `buf'
if (4 == i) {
// translate values in `tmp' from table
for (i = 0; i < 4; ++i) {
// find translation char in `b64_table'
for (l = 0; l < 64; ++l) {
if (tmp[i] == b64_table[l]) {
tmp[i] = l;
break;
}
}
}
// decode
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
// write decoded buffer to `dec'
dec = (unsigned char *) realloc(dec, size + 3);
if (dec != NULL){
for (i = 0; i < 3; ++i) {
dec[size++] = buf[i];
}
} else {
return NULL;
}
// reset
i = 0;
}
}
// remainder
if (i > 0) {
// fill `tmp' with `\0' at most 4 times
for (j = i; j < 4; ++j) {
tmp[j] = '\0';
}
// translate remainder
for (j = 0; j < 4; ++j) {
// find translation char in `b64_table'
for (l = 0; l < 64; ++l) {
if (tmp[j] == b64_table[l]) {
tmp[j] = l;
break;
}
}
}
// decode remainder
buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
// write remainer decoded buffer to `dec'
dec = (unsigned char *) realloc(dec, size + (i - 1));
if (dec != NULL){
for (j = 0; (j < i - 1); ++j) {
dec[size++] = buf[j];
}
} else {
return NULL;
}
}
// Make sure we have enough space to add '\0' character at end.
dec = (unsigned char *) realloc(dec, size + 1);
if (dec != NULL){
dec[size] = '\0';
} else {
return NULL;
}
// Return back the size of decoded string if demanded.
if (decsize != NULL) {
*decsize = size;
}
return dec;
}
unsigned char *
bake_b64_decode (const char *src, size_t len) {
return b64_decode_ex(src, len, NULL);
}
/**
* `encode.c' - b64
*
* copyright (c) 2014 joseph werle
*/
#include <stdio.h>
#include <stdlib.h>
#include "b64.h"
/**
* Base64 index table.
*/
static const char b64_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
char *
bake_b64_encode (const unsigned char *src, size_t len) {
int i = 0;
int j = 0;
char *enc = NULL;
size_t size = 0;
unsigned char buf[4];
unsigned char tmp[3];
// alloc
enc = (char *) malloc(1);
if (NULL == enc) { return NULL; }
// parse until end of source
while (len--) {
// read up to 3 bytes at a time into `tmp'
tmp[i++] = *(src++);
// if 3 bytes read then encode into `buf'
if (3 == i) {
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
// allocate 4 new byts for `enc` and
// then translate each encoded buffer
// part by index from the base 64 index table
// into `enc' unsigned char array
enc = (char *) realloc(enc, size + 4);
for (i = 0; i < 4; ++i) {
enc[size++] = b64_table[buf[i]];
}
// reset index
i = 0;
}
}
// remainder
if (i > 0) {
// fill `tmp' with `\0' at most 3 times
for (j = i; j < 3; ++j) {
tmp[j] = '\0';
}
// perform same codec as above
buf[0] = (tmp[0] & 0xfc) >> 2;
buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
buf[3] = tmp[2] & 0x3f;
// perform same write to `enc` with new allocation
for (j = 0; (j < i + 1); ++j) {
enc = (char *) realloc(enc, size + 1);
enc[size++] = b64_table[buf[j]];
}
// while there is still a remainder
// append `=' to `enc'
while ((i++ < 3)) {
enc = (char *) realloc(enc, size + 1);
enc[size++] = '=';
}
}
// Make sure we have enough space to add '\0' character at end.
enc = (char *) realloc(enc, size + 1);
enc[size] = '\0';
return enc;
}
......@@ -6,9 +6,11 @@
#include "bake-config.h"
#include "bake.h"
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <libpmemobj.h>
#include "base64/b64.h"
static char * bake_err_str(int ret)
{
......@@ -77,3 +79,38 @@ void bake_print_dbg_region_id_t(char *str, size_t size, bake_region_id_t rid)
return;
}
int bake_target_id_to_string(bake_target_id_t tid, char* str, size_t size)
{
if(size < 37)
return BAKE_ERR_INVALID_ARG;
uuid_unparse(tid.id, str);
return BAKE_SUCCESS;
}
int bake_target_id_from_string(const char* str, bake_target_id_t* tid)
{
if(uuid_parse(str, tid->id) != 0)
return BAKE_ERR_INVALID_ARG;
return BAKE_SUCCESS;
}
int bake_region_id_to_string(bake_region_id_t rid, char* str, size_t size)
{
char* s = bake_b64_encode((const unsigned char*)&rid, sizeof(rid));
if(size < strlen(s)+1) {
free(s);
return BAKE_ERR_INVALID_ARG;
}
strcpy(str,s);
free(s);
return BAKE_SUCCESS;
}
int bake_region_id_from_string(const char* str, bake_region_id_t* tid)
{
unsigned char* data = bake_b64_decode(str, strlen(str));
memcpy(tid, data, sizeof(*tid));
free(data);
return BAKE_SUCCESS;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment