#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include "cseproto/cseproto.h"
#include "cseproto/cseproto_encode.h"
char *current_test = NULL;
#define mylog(a,b,c...) \
do { \
char __log_tmp__[1024]; \
snprintf(__log_tmp__, 1024, b,##c); \
fprintf(stderr, "%s:%s:%i %s: %s: %s\n", __FILE__, __FUNCTION__, __LINE__, current_test, a, __log_tmp__); \
} while(0)
#define err(b,c...) \
do { \
mylog("ERROR",b,##c); \
exit(EXIT_FAILURE); \
} while(0)
int test1(char *arg)
{
cseproto_t *msg = NULL, *decoded = NULL;
cseproto_item_t *varint_item = NULL;
uint64_t varint = 0xDECAF;
cseproto_item_t *svarint_item = NULL;
int64_t svarint = 0xDEADBEEFDECAFBADLL;
cseproto_item_t *fixed32_item = NULL;
uint32_t fixed32 = 0xDEADBEEF;
cseproto_item_t *fixed64_item = NULL;
uint64_t fixed64 = 0xDEADBEEFDECAFBADLL;
cseproto_item_t *float32_item = NULL;
float float32 = 1.23456789;
cseproto_item_t *float64_item = NULL;
double float64 = 1.23456789;
cseproto_item_t *string_item = NULL;
char *string = "this is a test 2";
uint8_t *encoded_data = NULL;
size_t encoded_data_len = 0, decoded_data_len = 0;
uint32_t i = 0;
FILE *fh = NULL;
msg = cseproto_create(7);
//mylog("LOG", "buckets: %i", msg->bucket_count);
if(!msg)
err("failed to create cseproto struct");
//mylog("LOG", "buckets: %i", msg->bucket_count);
varint_item = cseproto_create_item(0, CSE_WIRETYPE_VARINT, sizeof(varint), &varint);
if(!varint_item)
err("failed to create varint item");
if(!cseproto_add_item(msg, varint_item))
err("failed to add varint item to message");
svarint_item = cseproto_create_item(1, CSE_WIRETYPE_SVARINT, sizeof(svarint), &svarint);
if(!svarint_item)
err("failed to create svarint item");
if(!cseproto_add_item(msg, svarint_item))
err("failed to add svarint item to message");
fixed32_item = cseproto_create_item(2, CSE_WIRETYPE_32BIT, sizeof(fixed32), &fixed32);
if(!fixed32_item)
err("failed to create fixed32 item");
if(!cseproto_add_item(msg, fixed32_item))
err("failed to add fixed32 item to message");
fixed64_item = cseproto_create_item(3, CSE_WIRETYPE_64BIT, sizeof(fixed64), &fixed64);
if(!fixed64_item)
err("failed to create fixed64 item");
if(!cseproto_add_item(msg, fixed64_item))
err("failed to add fixed64 item to message");
float32_item = cseproto_create_item(4, CSE_WIRETYPE_32BIT, sizeof(float32), &float32);
if(!float32_item)
err("failed to create float32 item");
if(!cseproto_add_item(msg, float32_item))
err("failed to add float32 item to message");
float64_item = cseproto_create_item(5, CSE_WIRETYPE_64BIT, sizeof(float64), &float64);
if(!float64_item)
err("failed to create float64 item");
if(!cseproto_add_item(msg, float64_item))
err("failed to add float64 item to message");
string_item = cseproto_create_item(6, CSE_WIRETYPE_LENDELIM, strlen(string), string);
if(!string_item)
err("failed to create string item");
if(!cseproto_add_item(msg, string_item))
err("failed to add string item to message");
//mylog("LOG", "message size: %i", cseproto_message_size(msg));
//mylog("LOG", "buckets: %i", msg->bucket_count);
encoded_data_len = cseproto_encode(msg, &encoded_data);
if(!encoded_data_len)
err("failed to encode message");
fh = fopen("test1.out", "w");
if(!fh)
err("failed to open test1.out: %s", strerror(errno));
fwrite(encoded_data, encoded_data_len, 1, fh);
fclose(fh);
decoded = cseproto_create(7);
if(!decoded)
err("failed to create message struct");
decoded_data_len = cseproto_decode_data(decoded, encoded_data_len, encoded_data);
if(decoded_data_len != encoded_data_len)
err("decode failed, encoded len:%i decoded len:%i", encoded_data_len, decoded_data_len);
//mylog("LOG", "message size: %i", cseproto_message_size(msg));
for(i = 0; i < decoded->bucket_count; ++i) {
cseproto_item_t *item = decoded->buckets[i].head;
//mylog("LOG", "item[%i]: ptr:%p", i, item);
switch(item->wiretype) {
case CSE_WIRETYPE_VARINT: // uint[32,64]_t, bool, enum
mylog("LOG", "item[%i]: va:%llx", i, item->v.uint64);
break;
case CSE_WIRETYPE_SVARINT: // int[32,64]_t
mylog("LOG", "item[%i]: sva:%llx", i, item->v.int64);
break;
case CSE_WIRETYPE_64BIT: // double, [su]fixed64_t
mylog("LOG", "item[%i]: 64:%f", i, item->v.float64);
mylog("LOG", "item[%i]: 64:%llx", i, item->v.uint64);
break;
case CSE_WIRETYPE_32BIT: // float, [su]fixed32_t
mylog("LOG", "item[%i]: 32:%f", i, item->v.float32);
mylog("LOG", "item[%i]: 32:%x", i, item->v.uint32);
break;
case CSE_WIRETYPE_LENDELIM: { // strings, binary data, embeded messages
uint8_t buf[item->data_len+1];
memset(buf, 0, item->data_len+1);
memcpy(buf, item->v.data, item->data_len);
mylog("LOG", "item[%i]: ld:%s", i, buf);
} break;
default:
mylog("ERR", "item[%i]: unknown type :(", i);
}
}
return 1;
}
int test2(char *arg)
{
FILE *fh = NULL;
uint8_t *encoded_data = 0;
uint32_t encoded_data_len = 0, decoded_data_len = 0;
cseproto_t *decoded = NULL;
uint32_t i = 0;
fh = fopen("test1.out", "r");
if(!fh)
err("failed to open test1.out: %s", strerror(errno));
fseek(fh, 0, SEEK_END);
encoded_data_len = ftell(fh);
fseek(fh, 0, SEEK_SET);
encoded_data = calloc(1, encoded_data_len);
if(!encoded_data)
err("failed to allocate encoded data");
fread(encoded_data, encoded_data_len, 1, fh);
fclose(fh);
decoded = cseproto_create(7);
if(!decoded)
err("failed to create message struct");
decoded_data_len = cseproto_decode_data(decoded, encoded_data_len, encoded_data);
if(decoded_data_len != encoded_data_len)
err("decode failed, encoded len:%i decoded len:%i", encoded_data_len, decoded_data_len);
for(i = 0; i < decoded->bucket_count; ++i) {
cseproto_item_t *item = decoded->buckets[i].head;
//mylog("LOG", "item[%i]: ptr:%p", i, item);
switch(item->wiretype) {
case CSE_WIRETYPE_VARINT: // uint[32,64]_t, bool, enum
mylog("LOG", "item[%i]: va:%llx", i, item->v.uint64);
break;
case CSE_WIRETYPE_SVARINT: // int[32,64]_t
mylog("LOG", "item[%i]: sva:%llx", i, item->v.int64);
break;
case CSE_WIRETYPE_64BIT: // double, [su]fixed64_t
mylog("LOG", "item[%i]: 64:%f", i, item->v.float64);
mylog("LOG", "item[%i]: 64:%llx", i, item->v.uint64);
break;
case CSE_WIRETYPE_32BIT: // float, [su]fixed32_t
mylog("LOG", "item[%i]: 32:%f", i, item->v.float32);
mylog("LOG", "item[%i]: 32:%x", i, item->v.uint32);
break;
case CSE_WIRETYPE_LENDELIM: { // strings, binary data, embeded messages
uint8_t buf[item->data_len+1];
memset(buf, 0, item->data_len+1);
memcpy(buf, item->v.data, item->data_len);
mylog("LOG", "item[%i]: ld:%s", i, buf);
} break;
default:
mylog("ERR", "item[%i]: unknown type :(", i);
}
}
return 1;
}
struct {
char *name;
int (*proc)(char *arg);
} tests[] = {
{ "test1", test1 },
{ "test2", test2 },
{ NULL, NULL },
};
int run(char *name, char *arg)
{
int32_t i = 0;
for(i = 0; tests[i].name; ++i) {
if(strcmp(name, tests[i].name)==0) {
current_test = name;
return tests[i].proc(arg);
}
}
return -1;
}
int main(int argc, char **argv)
{
int32_t ret = -1;
if(argc < 2) {
printf("useage %s <testname> <arg>\n", argv[0]);
return -1;
}
ret = run(argv[1], argc > 2 ? argv[2] : NULL);
if(ret == -1) {
printf("test %s doesn't exist\n", argv[1]);
return -1;
}
else if(ret == 0) {
printf("test %s failed\n", argv[1]);
return -1;
}
else {
printf("test %s succedded\n", argv[1]);
return 0;
}
return -1;
}