Skip to content

Commit

Permalink
Add roundtrip tool and needed functions (some are stubs)
Browse files Browse the repository at this point in the history
  • Loading branch information
aperezdc committed Mar 31, 2015
1 parent 9cbad89 commit b3a4de3
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 3 deletions.
14 changes: 11 additions & 3 deletions Makefile
@@ -1,27 +1,35 @@
CFLAGS += -std=c99
hipack_PATH ?= .
hipack_OBJS = ${hipack_PATH}/hipack-parser.o \
${hipack_PATH}/hipack-writer.o \
${hipack_PATH}/hipack-string.o \
${hipack_PATH}/hipack-alloc.o \
${hipack_PATH}/hipack-list.o \
${hipack_PATH}/hipack-dict.o
${hipack_PATH}/hipack-dict.o \
${hipack_PATH}/hipack-misc.o
hipack = ${hipack_PATH}/libhipack.a

hipack: ${hipack}
hipack-clean:
${RM} ${hipack} ${hipack_OBJS}
${RM} ${hipack_PATH}/tools/*.o ${hipack_PATH}/tools/hipack-parse
${RM} ${hipack_PATH}/tools/*.o \
${hipack_PATH}/tools/hipack-parse \
${hipack_PATH}/tools/hipack-roundtrip

${hipack_OBJS}: ${hipack_PATH}/hipack.h
${hipack}: ${hipack_OBJS}
${AR} rcu ${hipack} ${hipack_OBJS}

hipack-tools: \
${hipack_PATH}/tools/hipack-parse
${hipack_PATH}/tools/hipack-parse \
${hipack_PATH}/tools/hipack-roundtrip

${hipack_PATH}/tools/hipack-parse: \
${hipack_PATH}/tools/hipack-parse.o ${hipack}

${hipack_PATH}/tools/hipack-roundtrip: \
${hipack_PATH}/tools/hipack-roundtrip.o ${hipack}

hipack-check: ${hipack_PATH}/tools/hipack-parse
@${hipack_PATH}/tools/run-tests

Expand Down
73 changes: 73 additions & 0 deletions hipack-misc.c
@@ -0,0 +1,73 @@
/*
* hipack-misc.c
* Copyright (C) 2015 Adrian Perez <aperez@igalia.com>
*
* Distributed under terms of the MIT license.
*/

#include "hipack.h"
#include <math.h>


bool
hipack_value_equal (const hipack_value_t *a,
const hipack_value_t *b)
{
assert (a);
assert (b);

if (a->type != b->type)
return false;

switch (a->type) {
case HIPACK_INTEGER:
return a->v_integer == b->v_integer;
case HIPACK_BOOL:
return a->v_bool == b->v_bool;
case HIPACK_FLOAT:
return fabs(b->v_float - a->v_float) < 1e-15;
case HIPACK_STRING:
return hipack_string_equal (a->v_string, b->v_string);
case HIPACK_LIST:
return hipack_list_equal (a->v_list, b->v_list);
case HIPACK_DICT:
return hipack_dict_equal (a->v_dict, b->v_dict);
default:
assert (false); // Unreachable.
}
}


bool
hipack_list_equal (const hipack_list_t *a,
const hipack_list_t *b)
{
assert (a);
assert (b);

if (a->size != b->size)
return false;

for (uint32_t i = 0; i < a->size; i++)
if (!hipack_value_equal (&a->data[i], &b->data[i]))
return false;

return true;
}


bool
hipack_dict_equal (const hipack_dict_t *a,
const hipack_dict_t *b)
{
assert (a);
assert (b);

if (a->count != b->count)
return false;

return false;
}



146 changes: 146 additions & 0 deletions hipack-writer.c
@@ -0,0 +1,146 @@
/*
* hipack-writer.c
* Copyright (C) 2015 Adrian Perez <aperez@igalia.com>
*
* Distributed under terms of the MIT license.
*/

#include "hipack.h"


static inline bool
writechar (hipack_writer_t *writer, int ch)
{
assert (ch != HIPACK_IO_ERROR);
assert (ch != HIPACK_IO_EOF);

assert (writer->putchar);

int ret = (*writer->putchar) (writer->putchar_data, ch);
assert (ret != HIPACK_IO_EOF);
return ret == HIPACK_IO_ERROR;
}


#define CHECK_IO(statement) \
do { \
if (statement) return true; \
} while (0)


static inline bool
writedata (hipack_writer_t *writer,
const char *data,
uint32_t length)
{
if (length) {
assert (data);
while (length--) {
CHECK_IO (writechar (writer, *data++));
}
}
return false;
}


static inline int
mapdigit (unsigned n)
{
if (n < 10) {
return '0' + n;
}
if (n < 36) {
return 'A' + (n - 10);
}
assert (false);
return '?';
}


static inline bool
formatint (hipack_writer_t *writer,
int value,
uint8_t base)
{
assert (writer);
if (value >= base) {
CHECK_IO (formatint (writer, value / base, base));
}
CHECK_IO (writechar (writer, mapdigit (value % base)));
return false;
}


bool
hipack_write_bool (hipack_writer_t *writer,
const bool value)
{
assert (writer);
if (value) {
return writedata (writer, "True", 4);
} else {
return writedata (writer, "False", 5);
}
}


bool
hipack_write_string (hipack_writer_t *writer,
const hipack_string_t *hstr)
{
assert (writer);
assert (hstr);
CHECK_IO (writechar (writer, '"'));
for (uint32_t i = 0; i < hstr->size; i++) {
switch (hstr->data[i]) {
case 0x09: /* Horizontal tab. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (writechar (writer, 't'));
break;
case 0x0A: /* New line. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (writechar (writer, 'n'));
break;
case 0x0D: /* Carriage return. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (writechar (writer, 'r'));
break;
case 0x22: /* Double quote. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (writechar (writer, '"'));
break;
case 0x5C: /* Backslash. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (writechar (writer, '\\'));
break;
default:
if (hstr->data[i] < 0x20) {
/* ASCII non-printable character. */
CHECK_IO (writechar (writer, '\\'));
CHECK_IO (formatint (writer, (uint8_t) hstr->data[i], 16));
} else {
CHECK_IO (writechar (writer, hstr->data[i]));
}
}
}
CHECK_IO (writechar (writer, '"'));
return false;
}


bool
hipack_write (hipack_writer_t *writer,
const hipack_dict_t *message)
{
assert (writer);
assert (message);
}


int
hipack_stdio_putchar (void* fp, int ch)
{
assert (fp);
int ret = fputc (ch, (FILE*) fp);
return (ret == EOF) ? HIPACK_IO_ERROR : ch;
}
26 changes: 26 additions & 0 deletions hipack.h
Expand Up @@ -96,6 +96,8 @@ struct hipack_list {

extern hipack_list_t* hipack_list_new (uint32_t size);
extern void hipack_list_free (hipack_list_t *list);
extern bool hipack_list_equal (const hipack_list_t *a,
const hipack_list_t *b);


struct hipack_dict {
Expand All @@ -121,6 +123,8 @@ extern bool hipack_dict_get (const hipack_dict_t *dict,
const hipack_string_t *key,
hipack_value_t *value);

extern bool hipack_dict_equal (const hipack_dict_t *a,
const hipack_dict_t *b);


static inline hipack_type_t
Expand Down Expand Up @@ -157,6 +161,9 @@ HIPACK_TYPES (HIPACK_DEFINE_GET_VALUE)
#undef HIPACK_DEFINE_IS_TYPE
#undef HIPACK_DEFINE_GET_VALUE

extern bool hipack_value_equal (const hipack_value_t *a,
const hipack_value_t *b);

static inline void
hipack_value_free (hipack_value_t *value)
{
Expand Down Expand Up @@ -205,4 +212,23 @@ extern int hipack_stdio_getchar (void* fp);
extern hipack_dict_t* hipack_read (hipack_reader_t *reader);


typedef struct {
int (*putchar) (void*, int);
void *putchar_data;
} hipack_writer_t;


#define HIPACK_DEFINE_WRITE_VALUE(_type, name, type_tag) \
extern bool hipack_write_ ## name (hipack_writer_t *writer, \
const _type value);

HIPACK_TYPES (HIPACK_DEFINE_WRITE_VALUE)

#undef HIPACK_DEFINE_WRITE_VALUE

extern bool hipack_write (hipack_writer_t *writer,
const hipack_dict_t *message);
extern int hipack_stdio_putchar (void* fp, int ch);


#endif /* !HIPACK_H */

0 comments on commit b3a4de3

Please sign in to comment.