librlp

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

decode.c (1886B)


      1 #include <string.h>
      2 
      3 #include "endian.h"
      4 #include "rlp.h"
      5 
      6 static int process_state_token(rlp_encoder_t *encoder) {
      7 	int len = 0;
      8 	int lenlen = 0;
      9 	unsigned char token;
     10 
     11 	token = *encoder->ptr;
     12 
     13 	if (encoder->ptr == encoder->list_ptr[encoder->depth]) {
     14 		encoder->depth--;
     15 		encoder->state = RLP_LIST_ASCEND;
     16 		len = 0;
     17 
     18 	} else if (token >= 0xf7) {
     19 		lenlen = token - 0xf7;
     20 		encoder->ptr++;
     21 		len = 0;
     22 		memcpy(&len, encoder->ptr, lenlen);
     23 		if (lenlen > 1 && is_le()) {
     24 			to_endian(CONVERT_LITTLEENDIAN, lenlen, &len);
     25 		}
     26 		encoder->depth++;
     27 		encoder->ptr += lenlen;
     28 		encoder->buf = encoder->ptr;
     29 		encoder->list_ptr[encoder->depth] = encoder->buf + len;
     30 
     31 		encoder->state = RLP_LIST_DESCEND;
     32 
     33 	} else if (token >= 0xc0) {
     34 		len = token - 0xc0;
     35 		if (is_le()) {
     36 			to_endian(CONVERT_LITTLEENDIAN, sizeof(len), &len);
     37 		}
     38 		encoder->depth++;
     39 		encoder->ptr++;
     40 		encoder->buf = encoder->ptr;
     41 		encoder->list_ptr[encoder->depth] = encoder->buf + len;
     42 
     43 		encoder->state = RLP_LIST_DESCEND;
     44 
     45 	} else if (token >= 0xb7) {
     46 		lenlen = token - 0xb7;
     47 		encoder->ptr++;
     48 		len = 0;
     49 		memcpy(&len, encoder->ptr, lenlen);
     50 		if (lenlen > 1 && is_le()) {
     51 			to_endian(CONVERT_LITTLEENDIAN, lenlen, &len);
     52 		}
     53 		encoder->ptr += lenlen;
     54 		
     55 		encoder->buf = encoder->ptr;
     56 		encoder->ptr += len;
     57 		encoder->state = RLP_STRING;
     58 
     59 	} else if (token >= 0x80) {
     60 		len = token - 0x80;
     61 		encoder->ptr++;
     62 
     63 		encoder->buf = encoder->ptr;
     64 		encoder->ptr += len;
     65 		encoder->state = RLP_STRING;
     66 
     67 	} else {
     68 		encoder->list_ptr[encoder->depth] = encoder->ptr;
     69 		encoder->buf = encoder->ptr;
     70 		encoder->ptr++;
     71 		len = 1;
     72 		encoder->state = RLP_STRING;
     73 	}
     74 	
     75 	return len;
     76 }
     77 
     78 int rlp_next(rlp_encoder_t *encoder, int *zlen, char **zdest) {
     79 	int r;
     80 	
     81 	if (encoder->list_ptr[0] == encoder->ptr) {
     82 		encoder->state = RLP_END;
     83 		return -1;
     84 	}
     85 
     86 	*zlen = process_state_token(encoder);
     87 	*zdest = encoder->buf;
     88 
     89 	return 0;
     90 }