added sml_value_write, refactored sml_value_parse

This commit is contained in:
Juri Glass 2011-07-14 21:39:33 +02:00
parent 2126e8f4ce
commit f3dfe21ec5
2 changed files with 98 additions and 65 deletions

View file

@ -22,11 +22,12 @@
#include <stdio.h>
sml_value *sml_value_parse(sml_buffer *buf) {
int max = 1;
int type = sml_buf_get_next_type(buf);
unsigned char byte = sml_buf_get_current_byte(buf);
sml_value *value = (sml_value *) malloc(sizeof(sml_value));
value->type = type;
value->type = type;
switch (type) {
case SML_TYPE_OCTET_STRING:
@ -36,63 +37,14 @@ sml_value *sml_value_parse(sml_buffer *buf) {
value->data.boolean = sml_boolean_parse(buf);
break;
case SML_TYPE_UNSIGNED:
switch (byte & SML_LENGTH_FIELD) {
case SML_TYPE_NUMBER_8:
value->data.uint8 = sml_u8_parse(buf);
value->type |= SML_TYPE_NUMBER_8;
break;
case SML_TYPE_NUMBER_16:
value->data.uint16 = sml_u16_parse(buf);
value->type |= SML_TYPE_NUMBER_16;
break;
case SML_TYPE_NUMBER_16 + 1:
case SML_TYPE_NUMBER_32:
value->data.uint32 = sml_u32_parse(buf);
value->type |= SML_TYPE_NUMBER_32;
break;
case SML_TYPE_NUMBER_32 + 1:
case SML_TYPE_NUMBER_32 + 2:
case SML_TYPE_NUMBER_32 + 3:
case SML_TYPE_NUMBER_64:
value->data.uint64 = sml_u64_parse(buf);
value->type |= SML_TYPE_NUMBER_64;
break;
default:
buf->error = 1;
break;
}
break;
case SML_TYPE_INTEGER:
//switch (byte & SML_LENGTH_FIELD) {
// Integer 59 00 00 00 00 00 01 20 09 could'nt be evaluated cause (byte & SML_LENGTH_FIELD)=9
// but 8 is maximum :( -> now it's working
// TODO: check if same problem exists for other SML_TYPEs too
switch ((byte & SML_LENGTH_FIELD)-1) {
case SML_TYPE_NUMBER_8:
value->data.int8 = sml_i8_parse(buf);
value->type |= SML_TYPE_NUMBER_8;
break;
case SML_TYPE_NUMBER_16:
value->data.int16 = sml_i16_parse(buf);
value->type |= SML_TYPE_NUMBER_16;
break;
case SML_TYPE_NUMBER_16 + 1:
case SML_TYPE_NUMBER_32:
value->data.int32 = sml_i32_parse(buf);
value->type |= SML_TYPE_NUMBER_32;
break;
case SML_TYPE_NUMBER_32 + 1:
case SML_TYPE_NUMBER_32 + 2:
case SML_TYPE_NUMBER_32 + 3:
case SML_TYPE_NUMBER_64:
value->data.int64 = sml_i64_parse(buf);
value->type |= SML_TYPE_NUMBER_64;
break;
default:
buf->error = 1;
break;
// get maximal size, if not all bytes are used (example: only 6 bytes for a u64)
while (max < ((byte & SML_LENGTH_FIELD) - 1)) {
max <<= 1;
}
value->data.uint8 = sml_number_parse(buf, type, max);
value->type |= max;
break;
default:
buf->error = 1;
@ -107,19 +59,34 @@ sml_value *sml_value_parse(sml_buffer *buf) {
}
void sml_value_write(sml_value *value, sml_buffer *buf) {
if (value->type == SML_TYPE_BOOLEAN) {
sml_boolean_write(value->data.boolean, buf);
}
if (value == 0) {
sml_buf_optional_write(buf);
return;
}
switch (value->type & SML_TYPE_FIELD) {
case SML_TYPE_OCTET_STRING:
sml_octet_string_write(value->data.bytes, buf);
break;
case SML_TYPE_BOOLEAN:
sml_boolean_write(value->data.boolean, buf);
break;
case SML_TYPE_UNSIGNED:
case SML_TYPE_INTEGER:
sml_number_write(value->data.uint8, (value->type & SML_TYPE_FIELD),
(value->type & SML_LENGTH_FIELD), buf);
break;
}
}
sml_value *sml_value_init() {
sml_value *value = (sml_value *) malloc(sizeof(sml_value));
memset(value, 0, sizeof(value));
return value;
sml_value *value = (sml_value *) malloc(sizeof(sml_value));
memset(value, 0, sizeof(value));
return value;
}
void sml_value_free(sml_value *value) {
if (value) {
if (value) {
switch (value->type) {
case SML_TYPE_OCTET_STRING:
sml_octet_string_free(value->data.bytes);
@ -131,7 +98,7 @@ void sml_value_free(sml_value *value) {
sml_number_free(value->data.int8);
break;
}
free(value);
}
free(value);
}
}

View file

@ -55,8 +55,74 @@ TEST(sml_value, parse_boolean) {
TEST_ASSERT_FALSE(*(v->data.boolean));
}
TEST(sml_value, parse_unsigned32) {
hex2binary("6500000001", sml_buf_get_current_buf(buf));
sml_value *v = sml_value_parse(buf);
TEST_ASSERT_NOT_NULL(v);
TEST_ASSERT_EQUAL(1, *(v->data.uint32));
TEST_ASSERT_EQUAL((SML_TYPE_UNSIGNED | SML_TYPE_NUMBER_32), v->type);
}
TEST(sml_value, parse_integer64_fewer_bytes) {
hex2binary("58FFFFFFFFFFFF0F", sml_buf_get_current_buf(buf));
sml_value *v = sml_value_parse(buf);
TEST_ASSERT_EQUAL(-241, *(v->data.int64));
TEST_ASSERT_EQUAL((SML_TYPE_INTEGER | SML_TYPE_NUMBER_64), v->type);
}
TEST(sml_value, write_octet_string) {
sml_value *v = sml_value_init();
v->type = SML_TYPE_OCTET_STRING;
v->data.bytes = sml_octet_string_init((unsigned char *)"Hallo", 5);
sml_value_write(v, buf);
expected_buf(buf, "0648616C6C6F", 6);
}
TEST(sml_value, write_boolean) {
sml_value *v = sml_value_init();
v->type = SML_TYPE_BOOLEAN;
v->data.boolean = sml_boolean_init(SML_BOOLEAN_FALSE);
sml_value_write(v, buf);
expected_buf(buf, "4200", 2);
}
TEST(sml_value, write_unsigned32) {
sml_value *v = sml_value_init();
v->type = SML_TYPE_UNSIGNED | SML_TYPE_NUMBER_32;
v->data.uint32 = sml_u32_init(42);
sml_value_write(v, buf);
expected_buf(buf, "650000002A", 5);
}
TEST(sml_value, write_integer16) {
sml_value *v = sml_value_init();
v->type = SML_TYPE_INTEGER | SML_TYPE_NUMBER_16;
v->data.int16 = sml_i16_init(-5);
sml_value_write(v, buf);
expected_buf(buf, "53FFFB", 3);
}
TEST(sml_value, write_optional) {
sml_value_write(0, buf);
expected_buf(buf, "01", 1);
}
TEST_GROUP_RUNNER(sml_value) {
RUN_TEST_CASE(sml_value, init);
RUN_TEST_CASE(sml_value, parse_octet_string);
RUN_TEST_CASE(sml_value, parse_boolean);
RUN_TEST_CASE(sml_value, parse_unsigned32);
RUN_TEST_CASE(sml_value, parse_integer64_fewer_bytes);
RUN_TEST_CASE(sml_value, write_octet_string);
RUN_TEST_CASE(sml_value, write_boolean);
RUN_TEST_CASE(sml_value, write_unsigned32);
RUN_TEST_CASE(sml_value, write_integer16);
RUN_TEST_CASE(sml_value, write_optional);
}