[feature] add varint encoding/decoding
Signed-off-by: yenda <eric@status.im>
This commit is contained in:
parent
b542c7de26
commit
9b18f1d261
|
@ -0,0 +1,54 @@
|
|||
(ns ^{:doc "Implementation of varint based on https://github.com/chrisdickinson/varint"}
|
||||
status-im.utils.varint
|
||||
(:require [status-im.utils.ethereum.abi-spec :as abi-spec]
|
||||
[status-im.js-dependencies :as dependencies]))
|
||||
|
||||
(def utils dependencies/web3-utils)
|
||||
|
||||
(def most-significant-bit 0x80)
|
||||
(def biggest-int-per-byte 0x7F)
|
||||
(def biggest-int 2147483648) ;; 2^31
|
||||
|
||||
(defn encode [num]
|
||||
(loop [num num
|
||||
out []]
|
||||
(if (>= num 128)
|
||||
(recur (if (>= num biggest-int)
|
||||
(/ num 128)
|
||||
(bit-shift-right num 7))
|
||||
(conj out (bit-or (bit-and num 0xFF)
|
||||
most-significant-bit)))
|
||||
(conj out (bit-or num 0)))))
|
||||
|
||||
(defn encode-hex [num]
|
||||
(reduce (fn [hex current-bit]
|
||||
(str hex
|
||||
(.leftPad utils
|
||||
(abi-spec/number-to-hex current-bit)
|
||||
2)))
|
||||
""
|
||||
(encode num)))
|
||||
|
||||
(defn add-b-to-res
|
||||
[res b shift]
|
||||
(+ res (if (< shift 28)
|
||||
(bit-shift-left (bit-and b biggest-int-per-byte)
|
||||
shift)
|
||||
(* (bit-and b biggest-int-per-byte)
|
||||
shift shift))))
|
||||
|
||||
(defn decode [buf]
|
||||
(loop [res 0
|
||||
shift 0
|
||||
[b & rest-buf] buf]
|
||||
(if (>= b most-significant-bit)
|
||||
(recur (add-b-to-res res b shift)
|
||||
(+ shift 7)
|
||||
rest-buf)
|
||||
(add-b-to-res res b shift))))
|
||||
|
||||
(defn decode-hex [hex]
|
||||
(->> hex
|
||||
(partition 2)
|
||||
(mapv #(abi-spec/hex-to-number (apply str %)))
|
||||
decode))
|
|
@ -0,0 +1,28 @@
|
|||
(ns status-im.test.utils.varint
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.varint :as varint]))
|
||||
|
||||
(deftest encode
|
||||
(is (= (varint/encode-hex 0x0)
|
||||
"0"))
|
||||
(is (= (varint/encode-hex 0x70)
|
||||
"70"))
|
||||
(is (= (varint/encode-hex 0xe3)
|
||||
"e301")))
|
||||
|
||||
(deftest decode
|
||||
(is (= (varint/decode-hex "0")
|
||||
0x0))
|
||||
(is (= (varint/decode-hex "70")
|
||||
0x70))
|
||||
(is (= (varint/decode-hex "e301")
|
||||
0xe301)))
|
||||
|
||||
(defn test-roundtrip [n]
|
||||
(= (varint/decode-hex (varint/encode-hex n))
|
||||
n))
|
||||
|
||||
(deftest roundtrip
|
||||
(is (test-roundtrip 0))
|
||||
(is (test-roundtrip 23948))
|
||||
(is (test-roundtrip 2684453)))
|
Loading…
Reference in New Issue