///|
/// Encode a UInt64 using protobuf's unsigned base-128 varint format.
pub fn encode_varint_u64(value : UInt64) -> Bytes {
let out : Array[Byte] = []
for v = value {
if v < 128UL {
out.push(v.to_byte())
break
} else {
out.push(((v & 0x7fUL) | 0x80UL).to_byte())
continue v >> 7
}
}
Bytes::from_array(out)
}
///|
/// Encode a UInt32/UInt as a protobuf varint.
pub fn encode_varint_uint(value : UInt) -> Bytes {
encode_varint_u64(value.to_uint64())
}
///|
/// Decode a UInt64 varint from `input` starting at `offset`.
pub fn decode_varint_u64(input : Bytes, offset? : Int = 0) -> DecodeU64Result {
let bytes = input.to_array()
if offset < 0 || offset > bytes.length() {
return U64Err(UnexpectedEof)
}
let mut result : UInt64 = 0UL
let mut shift = 0
let mut index = offset
while index < bytes.length() {
let b = bytes[index].to_uint64()
let payload = b & 0x7fUL
if shift >= 64 || (shift == 63 && payload > 1UL) {
return U64Err(VarintOverflow)
}
result = result | (payload << shift)
index = index + 1
if (b & 0x80UL) == 0UL {
return U64Ok(result, index)
}
shift = shift + 7
if index - offset >= 10 {
return U64Err(VarintOverflow)
}
}
U64Err(UnexpectedEof)
}