librlp

C library for the Recursive Length Prefix (RLP) serialization format
git clone git://git.defalsify.org/librlp.git
Log | Files | Refs | LICENSE

commit 7d40a4322f39977483a1a87c0b88e26dbe7072cb
parent f356053b1490a28f8a6027f6276b0adaac374282
Author: nolash <dev@holbrook.no>
Date:   Sun, 11 Apr 2021 11:16:51 +0200

Add short string decoder

Diffstat:
MMakefile | 8++++----
Msrc/decode.c | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Asrc/decode.h | 0
Msrc/encode.c | 4++--
Msrc/rlp.c | 5++---
Msrc/rlp.h | 1+
Mtests/check_decoder.c | 60+++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mtests/check_encoder.c | 8++++----
8 files changed, 126 insertions(+), 17 deletions(-)

diff --git a/Makefile b/Makefile @@ -9,14 +9,14 @@ build_lib: build gcc -I./src -fPIC -shared -o librlp.so -Wl,-soname,librlp.so.0.0.1 src/encode.o src/decode.o src/bits.o src/endian.o -tests_build: build +build_test: build gcc -I./src -g3 tests/check_rlp.c src/rlp.o src/bits.o src/encode.o src/decode.o src/endian.o -o tests/check_rlp -lcheck gcc -I./src -g3 tests/check_encoder.c src/rlp.o src/bits.o src/encode.o src/decode.o src/endian.o -o tests/check_encoder -lcheck gcc -I./src -g3 tests/check_bits.c src/rlp.o src/bits.o src/encode.o src/decode.o src/endian.o -o tests/check_bits -lcheck gcc -I./src -g3 tests/check_vectors.c src/rlp.o src/bits.o src/encode.o src/decode.o src/endian.o -o tests/check_vectors -lcheck gcc -I./src -g3 tests/check_decoder.c src/rlp.o src/bits.o src/encode.o src/decode.o src/endian.o -o tests/check_decoder -lcheck -check: tests_build +check: build_test tests/check_rlp tests/check_encoder tests/check_decoder @@ -27,8 +27,8 @@ check: tests_build rm -v tests/check_rlp rm -v tests/check_encoder rm -v tests/check_decoder - rm -v tests/check_bits - rm -v tests/check_vectors + #rm -v tests/check_bits + #rm -v tests/check_vectors rm -v src/*.o .PHONY test: check diff --git a/src/decode.c b/src/decode.c @@ -1,5 +1,60 @@ +#include "endian.h" #include "rlp.h" -int rlp_next(rlp_encoder_t *encoder) { +static int process_state_token(rlp_encoder_t *encoder) { + int len; + int lenlen; + int r; + unsigned char token; + token = *encoder->ptr; + + if (token >= 0xc0) { + } else if (token >= 0x80) { + len = token - 0x80; + encoder->ptr++; + encoder->list_ptr[encoder->depth] = encoder->ptr; + r = encoder->depth; + encoder->depth--; + encoder->ptr += len; + } else { + encoder->list_ptr[encoder->depth] = encoder->ptr; + r = encoder->depth; + encoder->depth--; + encoder->ptr++; + } + + return r; } + +int rlp_next(rlp_encoder_t *encoder, int *zlen, char **zdest) { + int r; + + //if (encoder->ptr - encoder->buf == encoder->size) { + if (encoder->depth == -1) { + return -1; + } + + r = process_state_token(encoder); + + *zlen = encoder->ptr - encoder->list_ptr[r]; + *zdest = encoder->list_ptr[r]; + + return 0; +} + +// encoder->depth++; +// encoder->state = RLP_LIST; +// if (token < 0xf7) { +// len = token - 0xc0; +// encoder->list_ptr[encoder->depth] = encoder->ptr + len; +// } else { +// lenlen = token - 0xf7; +// len = 0; +// memcpy(&len, encoder->ptr, lenlen); +// if (is_le()) { +// len = to_endian(CONVERT_LITTLEENDIAN, lenlen, &len); +// } +// encoder->ptr += lenlen; +// encoder->list_ptr[encoder->depth] = encoder->ptr + len; +// } diff --git a/src/decode.h b/src/decode.h diff --git a/src/encode.c b/src/encode.c @@ -54,7 +54,7 @@ int rlp_add(rlp_encoder_t *encoder, int len, const char *data) { int rlp_descend(rlp_encoder_t *encoder) { encoder->depth++; encoder->list_ptr[encoder->depth] = encoder->ptr; - return encoder->depth + 1; + return encoder->depth; } int rlp_ascend(rlp_encoder_t *encoder) { @@ -81,5 +81,5 @@ int rlp_ascend(rlp_encoder_t *encoder) { } encoder->depth--; - return encoder->depth + 1; + return encoder->depth; } diff --git a/src/rlp.c b/src/rlp.c @@ -3,20 +3,19 @@ #include "rlp.h" int rlp_init(rlp_encoder_t *encoder, int buffer_capacity, char *content) { - encoder->depth = -1; + encoder->depth = 0; if (content != NULL) { encoder->buf = content; encoder->alloc = 0; encoder->state = RLP_DECODE; - encoder->ptr = encoder->buf + buffer_capacity; encoder->size = buffer_capacity; } else { encoder->buf = malloc(buffer_capacity); encoder->alloc = 1; encoder->state = RLP_ENCODE; - encoder->ptr = encoder->buf; encoder->size = 0; } + encoder->ptr = encoder->buf; } void rlp_free(rlp_encoder_t *encoder) { diff --git a/src/rlp.h b/src/rlp.h @@ -37,5 +37,6 @@ int rlp_add(rlp_encoder_t *encoder, int len, const char *data); size_t rlp_length(rlp_encoder_t *encoder); int rlp_get(rlp_encoder_t *encoder, int *zl, char **zdest); +int rlp_next(rlp_encoder_t *encoder, int *zl, char **zdest); #endif diff --git a/tests/check_decoder.c b/tests/check_decoder.c @@ -5,12 +5,42 @@ #include "rlp.h" -START_TEST(rlp_decode_single) { - char s[5] = {0x84, 0x66, 0x6f, 0x6f, 0x0a}; +START_TEST(rlp_decode_single_test) { + char s = 42; + char buf; + char *zbuf = &buf; + int r; + int l; + + rlp_encoder_t encoder; + + rlp_init(&encoder, 1, &s); + r = rlp_next(&encoder, &l, &zbuf); + ck_assert_int_eq(r, 0); + ck_assert_int_eq(l, 1); + ck_assert_mem_eq(zbuf, &s, l); + + rlp_free(&encoder); + +} +END_TEST + +START_TEST(rlp_decode_short_string_test) { + int r; + char s[5] = {0x83, 0x66, 0x6f, 0x6f}; char target[] = "foo"; + + int l; + char buf[1024]; + char *zbuf = buf; + rlp_encoder_t encoder; rlp_init(&encoder, 5, s); + r = rlp_next(&encoder, &l, &zbuf); + ck_assert_int_eq(r, 0); + ck_assert_int_eq(l, 3); + ck_assert_mem_eq(zbuf, target, l); rlp_free(&encoder); @@ -18,13 +48,37 @@ START_TEST(rlp_decode_single) { END_TEST +START_TEST(rlp_decode_long_string_test) { + int l; + int r; + + char s[57]; + s[0] = 0xb7 + 56; + + char buf[1024]; + char *zbuf = buf; + + rlp_encoder_t encoder; + + rlp_init(&encoder, 57, s); + r = rlp_next(&encoder, &l, &zbuf); + ck_assert_int_eq(r, 0); + ck_assert_mem_eq(buf, s+1, l); + + rlp_free(&encoder); + +} +END_TEST + Suite *rlp_decode_suite(void) { Suite *s; TCase *tcb; s = suite_create("rlp_decode"); tcb = tcase_create("bytes"); - tcase_add_test(tcb, rlp_decode_single); + //tcase_add_test(tcb, rlp_decode_single_test); + tcase_add_test(tcb, rlp_decode_short_string_test); + //tcase_add_test(tcb, rlp_decode_string_test); suite_add_tcase(s, tcb); diff --git a/tests/check_encoder.c b/tests/check_encoder.c @@ -110,13 +110,13 @@ START_TEST(rlp_encode_list_descend_state_test) { ck_assert_ptr_eq(encoder.ptr, encoder.list_ptr[encoder.depth]); ptr_chk = encoder.ptr; ck_assert_int_eq(1, r); - ck_assert_int_eq(encoder.depth, 0); + ck_assert_int_eq(encoder.depth, 1); r = rlp_descend(&encoder); ck_assert_ptr_eq(encoder.ptr, encoder.list_ptr[encoder.depth]); ck_assert_ptr_eq(ptr_chk, encoder.list_ptr[encoder.depth-1]); ck_assert_int_eq(2, r); - ck_assert_int_eq(encoder.depth, 1); + ck_assert_int_eq(encoder.depth, 2); rlp_free(&encoder); } @@ -135,11 +135,11 @@ START_TEST(rlp_encode_list_roundtrip_state_test) { ck_assert_int_eq(r, 1); rlp_add(&encoder, 1, &one); rlp_add(&encoder, 1, &two); - ck_assert_int_eq(encoder.depth, 0); + ck_assert_int_eq(encoder.depth, 1); r = rlp_ascend(&encoder); ck_assert_int_eq(r, 0); - ck_assert_int_eq(encoder.depth, -1); + ck_assert_int_eq(encoder.depth, 0); rlp_free(&encoder); }