1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

encoding: add an encoding.leb128 module with tests (#17880)

This commit is contained in:
Surman The Dead 2023-04-05 10:53:25 +02:00 committed by GitHub
parent b2cf6d0af4
commit 39b3a0ca17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 2220 additions and 0 deletions

View File

@ -0,0 +1,129 @@
module leb128
// encode_i32 encodes the `value` as leb128 encoded byte array
pub fn encode_i32(value i32) []u8 {
mut result := []u8{cap: 4}
mut val := value
mut i := 0
for {
mut b := u8(val & 0x7f)
val >>= 7
if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
result << b
break
}
result << b | 0x80
i++
}
return result
}
// encode_i64 encodes the `value` as leb128 encoded byte array
pub fn encode_i64(value i64) []u8 {
mut result := []u8{cap: 8}
mut val := value
for {
mut b := u8(val & 0x7f)
val >>= 7
if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
result << b
break
}
result << b | 0x80
}
return result
}
// encode_u64 encodes the `value` as leb128 encoded byte array
pub fn encode_u64(value u64) []u8 {
mut result := []u8{cap: 8}
mut val := value
for {
mut b := u8(val & 0x7f)
val >>= 7
if val == 0 {
result << b
break
}
result << b | 0x80
}
return result
}
// encode_u32 encodes the `value` as leb128 encoded byte array
pub fn encode_u32(value u32) []u8 {
mut result := []u8{cap: 4}
mut val := value
for {
mut b := u8(val & 0x7f)
val >>= 7
if val == 0 {
result << b
break
}
result << b | 0x80
}
return result
}
// decode_i32 decodes an i32 from the given leb128 encoded array `value`
pub fn decode_i32(value []u8) i32 {
mut result := int(0)
mut shift := 0
for b in value {
result |= b & 0x7f << shift
shift += 7
if b & 0x80 == 0 {
if shift < 32 && b & 0x40 != 0 {
result |= ~0 << shift
}
break
}
}
return result
}
// decode_i64 decodes an i64 from the given leb128 encoded array `value`
pub fn decode_i64(value []u8) i64 {
mut result := u64(0)
mut shift := 0
for b in value {
result |= u64(b & 0x7f) << shift
shift += 7
if b & 0x80 == 0 {
if shift < 64 && b & 0x40 != 0 {
result |= ~u64(0) << shift
}
break
}
}
return i64(result)
}
// decode_u64 decodes an u64 from the given leb128 encoded array `value`
pub fn decode_u64(value []u8) u64 {
mut result := u64(0)
mut shift := 0
for b in value {
result |= u64(b & 0x7f) << shift
if b & 0x80 == 0 {
break
}
shift += 7
}
return result
}
// decode_u32 decodes an u32 from the given leb128 encoded array `value`
pub fn decode_u32(value []u8) u32 {
mut result := u32(0)
mut shift := 0
for b in value {
result |= u32(b & 0x7f) << shift
if b & 0x80 == 0 {
break
}
shift += 7
}
return result
}

File diff suppressed because it is too large Load Diff