librlp

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

encode.c (1826B)


      1 #include <stdint.h>
      2 #include <string.h>
      3 
      4 #include "rlp.h"
      5 #include "bits.h"
      6 #include "endian.h"
      7 
      8 
      9 int rlp_add(rlp_encoder_t *encoder, int len, const char *data) {
     10 	char v;
     11 	int lenlen;
     12 	size_t r;
     13 
     14 	r = (size_t)encoder->ptr;
     15 
     16 	if (len == 0) {
     17 		*(encoder->ptr) = 0x80;
     18 		encoder->ptr++;
     19 		encoder->size++;
     20 	} else {
     21 		v = (char)*data;
     22 		if (len == 1 && v < 56) {
     23 			*(encoder->ptr) = v;
     24 			encoder->ptr++;
     25 			encoder->size++;
     26 		} else {
     27 			v = (char)*data;
     28 			if (len < 56) {
     29 				*(encoder->ptr) = len + 0x80;
     30 				encoder->ptr++;
     31 				memcpy(encoder->ptr, data, len);
     32 				encoder->ptr += len;
     33 				encoder->size++;
     34 			} else {
     35 				lenlen = intbytes_le(sizeof(int), (char*)&len);
     36 				*(encoder->ptr) = lenlen + 0xb7;
     37 				encoder->ptr++;
     38 				to_endian(CONVERT_BIGENDIAN, lenlen, &len);
     39 				memcpy(encoder->ptr, &len, lenlen);
     40 				to_endian(CONVERT_PLATFORM, lenlen, &len);
     41 				encoder->ptr += lenlen;
     42 				memcpy(encoder->ptr, data, len); 
     43 				encoder->ptr += len;
     44 				encoder->size += 1 + lenlen;
     45 			}
     46 		}
     47 	}
     48 
     49 	encoder->size += len;
     50 	
     51 	return (int)(r - (size_t)encoder->ptr);
     52 }
     53 
     54 int rlp_descend(rlp_encoder_t *encoder) {
     55 	encoder->depth++;
     56 	encoder->list_ptr[encoder->depth] = encoder->ptr;
     57 	return encoder->depth;
     58 }
     59 
     60 int rlp_ascend(rlp_encoder_t *encoder) {
     61 	size_t len;
     62 	char *ptr;
     63 	int lenlen;
     64 
     65 	ptr = encoder->list_ptr[encoder->depth];
     66 	len = encoder->ptr - ptr;
     67 	if (len < 56) {
     68 		memcpy(ptr + 1, ptr, len);
     69 		*(ptr) = 0xc0 + len;
     70 		encoder->ptr++;
     71 		encoder->size++;
     72 	} else {
     73 		lenlen = intbytes_le(sizeof(size_t), (char*)&len);
     74 		memcpy(ptr + 1 + lenlen, ptr, len);
     75 		*ptr = lenlen + 0xf7;
     76 		to_endian(CONVERT_BIGENDIAN, lenlen, &len);
     77 		memcpy(ptr+1, &len, lenlen);
     78 		to_endian(CONVERT_PLATFORM, lenlen, &len);
     79 		encoder->ptr += (lenlen + 1);
     80 		encoder->size + 1 + lenlen;
     81 	}
     82 	encoder->depth--;
     83 
     84 	return encoder->depth;
     85 }