#how to decode varints?

1 messages · Page 1 of 1 (latest)

forest warren
#

Hi, I'm new to gleam and I'm doing the codecrafters kafka challenge with it.

One of the stages requires being able to parse variable-width ints from within a bit array. In the protobuf docs, it mentions how to do it:
https://protobuf.dev/programming-guides/encoding/#varints

I'm new to bit manipulation and was confused on a couple things:

  1. How would you do a logical shift in gleam? I only saw an arithmetic shift in stdlib, thus the only thing i thought of was pattern matching & discarding the first bit.
  2. Any way to reverse the sections in a bit array (little endian to big endian)? Or is it only possible to just do list.reverse() on a list of bitarrays?
  3. After all that, whats a way to concatenate all the sections to be interpreted as one int? is it appending all of them and then pattern matching it as
// given that we discard the msb for each section, each section is 7 bits
<<result:unit(7)-size(num_sections)>> = combined

thanks in advance!

grim niche
#

I think you are on the right track.

  1. I would use pattern matching for the shifting. In this case I don't think you need it for the task at hand but if you ever do.
fn logical_shift_left(bytes, steps) {
  case bytes {
    <<_shift:steps, rest:bits>> -> Ok(<<bits, 0:steps>>)
    _ -> Error("invalid match")
  }
}

You can see how easy you can transform the above to a circular shift instead.
2. For this task I would just use the list reverse option but there are other ways. For the general case you might use pattern matching:

fn reverse(binary) {
  let size = bit_array.byte_size(binary) * 8
  case binary {
     <<x:int-size(size)-little>> -> Ok(<<x:int-size(size)-big)
     _ -> Error("invalid match")
   }
}
  1. Yes, that is how I would do it. For the entire operation I would write a recursive function which takes a bit array and an accumulator. Pattern match on the msb bit and accumulate the 7 lsb into a list. Keep going until the msb is a 0. Then concatenate the list to a bit_string and use pattern matching to create the int. A bonus is that because you should prepend each 7-bits to the list of bit arrays, the list will already be correctly sorted for you.
forest warren
#

Okay great!