an atproto pds written in F# (.NET 9) 馃
pds
fsharp
giraffe
dotnet
atproto
1# CAR Format Implementation Notes
2
3The **Content Addressable aRchives (CAR)** format is used to store content-addressable objects (IPLD blocks) as a sequence of bytes.
4It is the standard format for repository export (`sync.getRepo`) and block transfer (`sync.getBlocks`) in the AT Protocol.
5
6## 1. Format Overview (v1)
7
8A CAR file consists of a **Header** followed by a sequence of **Data** sections.
9
10```text
11|--------- Header --------| |--------------- Data Section 1 ---------------| |--------------- Data Section 2 ---------------| ...
12[ varint | DAG-CBOR block ] [ varint | CID bytes | Block Data bytes ] [ varint | CID bytes | Block Data bytes ] ...
13```
14
15### LEB128 Varints
16
17All length prefixes in CAR are encoded as **unsigned LEB128 (UVarint)** integers.
18
19- Used to prefix the Header block.
20- Used to prefix each Data section.
21
22## 2. Header
23
24The header is a single DAG-CBOR encoded block describing the archive.
25
26**Encoding:**
27
281. Construct the CBOR map: `{ "version": 1, "roots": [<cid>, ...] }`.
292. Encode as DAG-CBOR bytes.
303. Prefix with the length of those bytes (as UVarint).
31
32## 3. Data Sections
33
34Following the header, the file contains a concatenated sequence of data sections. Each section represents one IPLD block.
35
36```text
37[ Section Length (UVarint) ] [ CID (raw bytes) ] [ Binary Data ]
38```
39
40- **Section Length**: The total length of the *CID bytes* + *Binary Data*.
41- **CID**: The raw binary representation of the block's CID (usually CIDv1 + DAG-CBOR + SHA2-256).
42- **Binary Data**: The actual content of the block.
43
44The Section Length *includes* the length of the CID.
45
46This is slightly different from some other framing formats where length might only cover the payload.
47
48## 4. References
49
50- [IPLD CARv1 Specification](https://ipld.io/specs/transport/car/carv1/)