mirror of
https://github.com/vlang/v.git
synced 2025-09-08 23:07:19 -04:00
68 lines
1.3 KiB
V
68 lines
1.3 KiB
V
// Copyright (c) 2022, 2024 blackshirt. All rights reserved.
|
|
// Use of this source code is governed by a MIT License
|
|
// that can be found in the LICENSE file.
|
|
module asn1
|
|
|
|
// base128_int_length calculates the length of bytes needed to store
|
|
// integer v encoded in base 128
|
|
fn base128_int_length(v i64) int {
|
|
if v == 0 {
|
|
return 1
|
|
}
|
|
|
|
mut n := v
|
|
mut ret := 0
|
|
|
|
for n > 0 {
|
|
ret += 1
|
|
n >>= 7
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
// encode_base128_int serializes integer to bytes array in base 128 integer.
|
|
fn encode_base128_int(mut dst []u8, n i64) []u8 {
|
|
l := base128_int_length(n)
|
|
|
|
for i := l - 1; i >= 0; i-- {
|
|
mut o := u8(n >> u32(i * 7))
|
|
o &= 0x7f
|
|
if i != 0 {
|
|
o |= 0x80
|
|
}
|
|
|
|
dst << o
|
|
}
|
|
|
|
return dst
|
|
}
|
|
|
|
// decode_base128_int read bytes as base 128 integer for current position `loc`.
|
|
// Its returns integer value and the next offset to read from.
|
|
fn decode_base128_int(bytes []u8, loc int) !(int, int) {
|
|
mut pos := loc
|
|
mut r64 := i64(0)
|
|
mut ret := 0
|
|
for s := 0; pos < bytes.len; s++ {
|
|
r64 <<= 7
|
|
b := bytes[pos]
|
|
|
|
if s == 0 && b == 0x80 {
|
|
return error('integer is not minimaly encoded')
|
|
}
|
|
|
|
r64 |= i64(b & 0x7f)
|
|
pos += 1
|
|
|
|
if b & 0x80 == 0 {
|
|
ret = int(r64)
|
|
if r64 > max_i32 {
|
|
return error('base 128 integer too large')
|
|
}
|
|
return ret, pos
|
|
}
|
|
}
|
|
return error('truncated base 128 integer')
|
|
}
|