package bitcoinml

  1. Overview
  2. Docs

Source file varint.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
open Stdint;;
open Bytes;;

let parse_varint bits =
	let parse_tag_byte bits =
		match%bitstring bits with
		| {| tag : 1*8 : string; rest : -1 : bitstring |} -> (Uint8.of_bytes_little_endian (of_string tag) 0, rest)
	in
	let parse_value bits stringize =
		match%bitstring bits with
		| {| value : stringize * 8 : string; rest : -1 : bitstring |} -> 
			match stringize with
			| 8 -> (Uint64.of_bytes_little_endian (of_string value) 0, rest)
			| 4 -> (Uint32.to_uint64 (Uint32.of_bytes_little_endian (of_string value) 0), rest)
			| 2 -> (Uint16.to_uint64 (Uint16.of_bytes_little_endian (of_string value) 0), rest)
			| _ -> failwith "Varint parse error"
	in
	let tag, rest = parse_tag_byte bits in
		match Uint8.to_int tag with
		| 0xFF -> parse_value rest 8
		| 0xFE -> parse_value rest 4
		| 0xFD -> parse_value rest 2
		| x -> (Uint64.of_uint8 tag, rest)
;;


let bitstring_of_varint i = 
	match i with
	| i when i < 0xFDL -> [%bitstring {| Int64.to_int i : 1*8 : littleendian |}]
	| i when i < 0xFFFFL -> [%bitstring {| 0xFD : 1*8; Int64.to_int i : 2*8 : littleendian |}]
	| i when i < 0xFFFFFFFFL -> [%bitstring {| 0xFE : 1*8; Int64.to_int32 i : 4*8 : littleendian |}]
	| i -> [%bitstring {| 0xFF : 1*8; i : 8*8 : littleendian |}]
;;


let encoding_length i = match Uint64.to_int64 i with
| i when i < 0xFDL -> 1
| i when i < 0xFFFFL -> 3
| i when i < 0xFFFFFFFFL -> 5
| i -> 9
;;