Skip to content
Course contents

Write a Tagged Binary Encoder

Build the format from lesson 3 — varints, tags, length prefixes — then use it to reproduce the silent data-loss bug and fix it.

stretch1 hr hands-onruns in this tab

This is the longest lab in the course, and the only one where the final test reproduces a production bug rather than checking a function.

Bytes are numbers 0–255 in a plain array, so you can print your output and read it. The wire format per field:

[tag varint][wire type byte][payload]

wire type 0   varint payload, no length prefix
wire type 1   length varint, then that many bytes of UTF-8

What to implement

writeVarint / readVarint — seven bits of data per byte, high bit as a continuation flag. Get the boundaries right: 127 is one byte, 128 is two.

encode(record, schema) — write present fields in ascending tag order. A test decodes your output as text and asserts that no field name appears in it; that is the property the whole format exists for.

decode(bytes, schema) — return { record, unknown }. A field whose tag is not in your schema must be skipped using its wire type and length, and kept in unknown rather than thrown away.

update(bytes, schema, changes) — decode, apply changes, re-encode, preserving unknown fields.