commit a796450e1d22e39c829d7a0059abef2113bd22be
parent 4527d2284d23c8b76f71553dbddc98c45f10ff81
Author: nolash <dev@holbrook.no>
Date: Sun, 11 Apr 2021 14:53:44 +0200
Package with so sources
Diffstat:
14 files changed, 424 insertions(+), 0 deletions(-)
diff --git a/MANIFEST.in b/MANIFEST.in
@@ -0,0 +1 @@
+include aux/src/*.h
diff --git a/aux/src/bits.c b/aux/src/bits.c
@@ -0,0 +1,30 @@
+
+int intbits_le(int len, char *n) {
+ char ri = 0;
+ char ry = 0;
+ char i = 0;
+
+ if (len == 0) {
+ return 0;
+ }
+
+ for (int b = 0; b < len; b++) {
+ for (i = 0; i < 8; i++) {
+ if (((1 << i) & *(n + b)) > 0) {
+ ri = i + 1;
+ ry = b;
+ }
+ }
+ }
+
+ if (ri == 0 && ry == 0) {
+ ri = 1;
+ }
+
+ return ri + (ry * 8);
+}
+
+int intbytes_le(int len, char *n) {
+ int r = intbits_le(len, n);
+ return (r - 1) / 8 + 1;
+}
diff --git a/aux/src/bits.h b/aux/src/bits.h
@@ -0,0 +1,7 @@
+#ifndef LASH_BITS_H_
+#define LASH_BITS_H_
+
+char intbits_le(int len, char *n);
+char intbytes_le(int len, char *n);
+
+#endif
diff --git a/aux/src/decode.c b/aux/src/decode.c
@@ -0,0 +1,111 @@
+#include <string.h>
+
+#include "endian.h"
+#include "rlp.h"
+
+static int process_state_token(rlp_encoder_t *encoder) {
+ int len = 0;
+ int lenlen = 0;
+ int r;
+ unsigned char token;
+
+ token = *encoder->ptr;
+
+ if (token >= 0xf7) {
+ lenlen = token - 0xf7;
+ encoder->ptr++;
+ len = 0;
+ memcpy(&len, encoder->ptr, lenlen);
+ if (lenlen > 1 && is_le()) {
+ to_endian(CONVERT_LITTLEENDIAN, lenlen, &len);
+ }
+ encoder->list_ptr[encoder->depth] = (char*)&len;
+ encoder->ptr += lenlen;
+
+ r = encoder->depth;
+ encoder->depth++;
+ encoder->state = RLP_LIST;
+
+ } else if (token >= 0xc0) {
+ len = token - 0xc0;
+ if (is_le()) {
+ to_endian(CONVERT_LITTLEENDIAN, sizeof(len), &len);
+ }
+ encoder->list_ptr[encoder->depth] = (char*)&len;
+ encoder->ptr++;
+
+ r = encoder->depth;
+ encoder->depth++;
+ encoder->state = RLP_LIST;
+ } else if (token >= 0xb7) {
+ lenlen = token - 0xb7;
+ encoder->ptr++;
+ len = 0;
+ memcpy(&len, encoder->ptr, lenlen);
+ if (lenlen > 1 && is_le()) {
+ to_endian(CONVERT_LITTLEENDIAN, lenlen, &len);
+ }
+ encoder->ptr += lenlen;
+
+ encoder->list_ptr[encoder->depth] = encoder->ptr;
+ r = encoder->depth;
+ encoder->ptr += len;
+ encoder->depth--;
+ encoder->state = RLP_STRING;
+ } else if (token >= 0x80) {
+ len = token - 0x80;
+ encoder->ptr++;
+
+ encoder->list_ptr[encoder->depth] = encoder->ptr;
+ r = encoder->depth;
+ encoder->ptr += len;
+ encoder->depth--;
+ encoder->state = RLP_STRING;
+ } else {
+ encoder->list_ptr[encoder->depth] = encoder->ptr;
+ r = encoder->depth;
+ encoder->ptr++;
+ encoder->depth--;
+ encoder->state = RLP_STRING;
+ }
+
+ return r;
+}
+
+static int assert_complete(rlp_encoder_t *encoder) {
+ int r = 0;
+
+ if (encoder->ptr - encoder->buf < encoder->size) {
+ encoder->state = RLP_INCOMPLETE;
+ r = -1;
+ } else if (encoder->ptr - encoder->buf > encoder->size) {
+ encoder->state = RLP_OVERFLOW;
+ r = -1;
+ } else {
+ encoder->state = RLP_END;
+ }
+ return r;
+}
+
+int rlp_next(rlp_encoder_t *encoder, int *zlen, char **zdest) {
+ int r;
+
+ if (encoder->depth == -1) {
+ return assert_complete(encoder);
+ }
+
+ r = process_state_token(encoder);
+
+ switch (encoder->state) {
+ case RLP_LIST:
+ *zlen = *((int*)encoder->list_ptr[r]);
+ break;
+
+ case RLP_STRING:
+ *zlen = encoder->ptr - encoder->list_ptr[r];
+ break;
+ }
+ *zdest = encoder->list_ptr[r];
+
+ return 0;
+}
diff --git a/aux/src/decode.h b/aux/src/decode.h
diff --git a/aux/src/encode.c b/aux/src/encode.c
@@ -0,0 +1,85 @@
+#include <stdint.h>
+#include <string.h>
+
+#include "rlp.h"
+#include "bits.h"
+#include "endian.h"
+
+
+int rlp_add(rlp_encoder_t *encoder, int len, const char *data) {
+ char v;
+ int lenlen;
+ size_t r;
+
+ r = (size_t)encoder->ptr;
+
+ if (len == 0) {
+ *(encoder->ptr) = 0x80;
+ encoder->ptr++;
+ encoder->size++;
+ } else {
+ v = (char)*data;
+ if (len == 1 && v < 56) {
+ *(encoder->ptr) = v;
+ encoder->ptr++;
+ encoder->size++;
+ } else {
+ v = (char)*data;
+ if (len < 56) {
+ *(encoder->ptr) = len + 0x80;
+ encoder->ptr++;
+ memcpy(encoder->ptr, data, len);
+ encoder->ptr += len;
+ encoder->size++;
+ } else {
+ lenlen = intbytes_le(sizeof(int), (char*)&len);
+ *(encoder->ptr) = lenlen + 0xb7;
+ encoder->ptr++;
+ to_endian(CONVERT_BIGENDIAN, lenlen, &len);
+ memcpy(encoder->ptr, &len, lenlen);
+ to_endian(CONVERT_PLATFORM, lenlen, &len);
+ encoder->ptr += lenlen;
+ memcpy(encoder->ptr, data, len);
+ encoder->ptr += len;
+ encoder->size += 1 + lenlen;
+ }
+ }
+ }
+
+ encoder->size += len;
+
+ return (int)(r - (size_t)encoder->ptr);
+}
+
+int rlp_descend(rlp_encoder_t *encoder) {
+ encoder->depth++;
+ encoder->list_ptr[encoder->depth] = encoder->ptr;
+ return encoder->depth;
+}
+
+int rlp_ascend(rlp_encoder_t *encoder) {
+ size_t len;
+ char *ptr;
+ int lenlen;
+
+ ptr = encoder->list_ptr[encoder->depth];
+ len = encoder->ptr - ptr;
+ if (len < 56) {
+ memcpy(ptr + 1, ptr, len);
+ *(ptr) = 0xc0 + len;
+ encoder->ptr++;
+ encoder->size++;
+ } else {
+ lenlen = intbytes_le(sizeof(size_t), (char*)&len);
+ memcpy(ptr + 1 + lenlen, ptr, len);
+ *ptr = lenlen + 0xf7;
+ to_endian(CONVERT_BIGENDIAN, lenlen, &len);
+ memcpy(ptr+1, &len, lenlen);
+ to_endian(CONVERT_PLATFORM, lenlen, &len);
+ encoder->ptr += (lenlen + 1);
+ encoder->size + 1 + lenlen;
+ }
+ encoder->depth--;
+
+ return encoder->depth;
+}
diff --git a/aux/src/encode.h b/aux/src/encode.h
diff --git a/aux/src/endian.c b/aux/src/endian.c
@@ -0,0 +1,44 @@
+#include "endian.h"
+
+int is_le() {
+ short s = 42;
+ return *((unsigned char*)&s) == 42;
+}
+
+// convert unsigned integer to little-endian representation
+int to_endian(char direction, int l, void *n) {
+ union le un;
+
+ if (l == 1 || is_le() == direction) {
+ return 0;
+ }
+ switch(l) {
+ case sizeof(long long):
+ un.ll = (long long*)n;
+ break;
+ case sizeof(int):
+ un.i = (int*)n;
+ break;
+ case sizeof(short):
+ un.s = (short*)n;
+ break;
+ default:
+ un.c = (char*)n;
+ }
+ flip_endian(l, &un);
+
+ return 0;
+}
+
+void flip_endian(int l, union le *n) {
+ int i;
+ char t;
+ char *ne;
+
+ ne = (n->c)+(l-1);
+ for (i = 0; i < l/2; i++) {
+ t = *(n->c+i);
+ *((n->c)+i) = *(ne-i);
+ *(ne-i) = t;
+ }
+}
diff --git a/aux/src/endian.h b/aux/src/endian.h
@@ -0,0 +1,20 @@
+#ifndef LASH_ENDIAN_H_
+#define LASH_ENDIAN_H_
+
+#define CONVERT_BIGENDIAN 0x00
+#define CONVERT_LITTLEENDIAN 0x01
+#define CONVERT_PLATFORM is_le()
+
+union le {
+ short *s;
+ int *i;
+ long long *ll;
+ char *c;
+};
+
+int le(int l, void *n);
+int is_le();
+int to_endian(char direction, int l, void *n);
+void flip_endian(int l, union le *n);
+
+#endif // LASH_ENDIAN_H_
diff --git a/aux/src/rlp.c b/aux/src/rlp.c
@@ -0,0 +1,32 @@
+#include <stdlib.h>
+
+#include "rlp.h"
+
+int rlp_init(rlp_encoder_t *encoder, int buffer_capacity, char *content) {
+ encoder->depth = 0;
+ if (content != NULL) {
+ encoder->buf = content;
+ encoder->alloc = 0;
+ encoder->state = RLP_DECODE;
+ encoder->size = buffer_capacity;
+ } else {
+ encoder->buf = malloc(buffer_capacity);
+ encoder->alloc = 1;
+ encoder->state = RLP_ENCODE;
+ encoder->size = 0;
+ }
+ encoder->ptr = encoder->buf;
+}
+
+void rlp_free(rlp_encoder_t *encoder) {
+ if (encoder->alloc) {
+ free(encoder->buf);
+ }
+ encoder->ptr = NULL;
+}
+
+int rlp_get(rlp_encoder_t *encoder, int *zl, char **zdest) {
+ *zdest = encoder->buf;
+ *zl = encoder->size;
+ return 0;
+}
diff --git a/aux/src/rlp.h b/aux/src/rlp.h
@@ -0,0 +1,47 @@
+#ifndef RLP_T_
+#define RLP_T_
+
+#include <stdlib.h>
+
+#ifndef RLP_MAX_LIST_DEPTH
+#define RLP_MAX_LIST_DEPTH 1024
+#endif
+
+#define RLP_SUCCESS 0
+#define RLP_FAILURE -1
+
+
+enum rlp_state {
+ RLP_DECODE,
+ RLP_ENCODE,
+ RLP_LIST,
+ RLP_STRING,
+ RLP_END,
+ RLP_OVERFLOW,
+ RLP_INCOMPLETE,
+};
+
+
+typedef struct rlp_encoder {
+ char *buf;
+ char alloc;
+ int depth;
+ int size;
+ enum rlp_state state;
+ char *list_ptr[RLP_MAX_LIST_DEPTH];
+ char *ptr;
+} rlp_encoder_t;
+
+
+int rlp_init(rlp_encoder_t *encoder, int buffer_capacity, char *content);
+void rlp_free(rlp_encoder_t *encoder);
+
+int rlp_descend(rlp_encoder_t *encoder);
+int rlp_ascend(rlp_encoder_t *encoder);
+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/rlpstream/__init__.py b/rlpstream/__init__.py
@@ -0,0 +1,9 @@
+# standard imports
+import ctypes
+import ctypes.util
+
+LIBRLP_RLP_MAX_LIST_DEPTH = 1024
+
+__path_librlp = ctypes.util.find_library('rlp')
+librlp = ctypes.CDLL(__path_librlp)
+
diff --git a/setup.cfg b/setup.cfg
@@ -0,0 +1,26 @@
+[metadata]
+name = rlpstream
+version = 0.0.01a1
+description = Python wrapper for librlp
+author = Louis Holbrook
+author_email = dev@holbrook.no
+url = https://gitlab.com/nolash/rlpstream
+
+classifiers =
+ Programming Language :: Python :: 3
+ Operating System :: OS Independent
+ Development Status :: 3 - Alpha
+ Environment :: Console
+ Intended Audience :: Developers
+ License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
+ Topic :: Internet
+# Topic :: Blockchain :: EVM
+license = GPL3
+licence_files =
+ LICENSE.txt
+
+[options]
+python_requires = >= 3.8
+
+packages =
+ rlpstream
diff --git a/setup.py b/setup.py
@@ -0,0 +1,12 @@
+from distutils.core import setup, Extension
+
+rlp = Extension('rlp',
+ sources = ['aux/src/rlp.c', 'aux/src/endian.c', 'aux/src/bits.c', 'aux/src/encode.c', 'aux/src/decode.c'],
+ )
+
+setup(
+ name='rlpstream',
+ version = '0.0.1a1',
+ ext_modules = [rlp],
+ packages=['rlpstream'],
+ )