https://github.com/hf/cupcake
A simple message container and implementation.
https://github.com/hf/cupcake
Last synced: 5 months ago
JSON representation
A simple message container and implementation.
- Host: GitHub
- URL: https://github.com/hf/cupcake
- Owner: hf
- License: mit
- Created: 2017-12-08T15:06:23.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-12-08T15:07:16.000Z (over 8 years ago)
- Last Synced: 2025-07-20T05:53:28.526Z (12 months ago)
- Size: 1.95 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Cupcake
=======
Cupcake is a simple binary message format, and an implementation in Rust.
## Motivation
There are a lot of ways to serialize a message. You can concatenate bytes. You
can use JSON (no!). You can use protocol buffers; or the latest fad flat
buffers. You can use MessagePack, BSON, CBOR... The list goes on...
However, all of these formats have their uses, mostly in business-level code.
They become difficult to use as a container for more generic messages. They
usually have some form of "parsing" or non-trivial computational overhead in
accessing parts of the message. Not all are good with binary data (JSON!).
Cupcake aims to solve these issues and be a container format of sorts. You
should put your JSON in a Cupcake, but a Cupcake is not a JSON!
## Spec
Yes. In a README. That simple.
### Version 1
#### Definitions
- byte: 8 bits, smallest addressable value
- magic: cupcake magic bytes, `0xF9 0xC9`
- version: cupcake version, a single byte, fixed value `0x01`
- tag: user defined tag value, a single byte
- slice: a string of bytes, up to 255 bytes long
- slices: a group of slices, up to 255 slices per message
- slice-size: a single byte, describing the size of a slice
- extension: a string of bytes, up to 4294967296 (2^32) bytes long
- extension-size: a string of 4 bytes, describing the size of the extension
#### Layout
A Cupcake message is laid out like so:
```
0: [0xF9]
1: [0xC9]
2: [0x01]
3: [tag]
4: [slices]
5: [extension-size-3]
6: [extension-size-2]
7: [extension-size-1]
8: [extension-size-0]
9: { [slice-size:0] ... [slice-size:255] }
9 + slices: { slice:0 } ... { slice:255 }
9 + slices + sum(slice-size): { extension }
```
Where `[name]` corresponds to a single byte; `{ name }` corresponds to a
sequence of bytes.
#### Validation
A Cupcake message (`msg` of length `n`) is valid if and only if:
1. `n >= 9`
2. `0xF9 == msg[0]`
3. `0xC9 == msg[1]`
4. `0x01 == msg[2]`
5. `let total_slice_size = sum(msg[9 + i]) where i in (0 upto msg[4])`
6. `let extension_size = (msg[5] << (8*3)) | (msg[6] << (8*2)) | (msg[7] << (8*1)) | (msg[8] << (8*0))`
7. `n == 9 + total_slice_size + extension_size`
#### Access
A Cupcake message (`msg` of length `n`) can be accessed only if valid, with the
following formulas:
**Access the i-th slice**
Assumes that `i < slices`.
```
slice_i_offset := 9 + msg[4] + (sum(msg[9 + j]) where j in (0 upto i))
slice_i_length := msg[9 + i]
```
**Access the extension data**
```
extension_offset := 9 + msg[4] + (sum(msg[9 + i]) where i in (0 upto msg[4]))
extension_length := (msg[5] << (8*3)) | (msg[6] << (8*2)) | (msg[7] << (8*1)) | (msg[8] << (8*0))
```
## License
This distribution is Copyright © 2017 Stojan Dimitrovski. It is licensed
under the MIT license. You can find the full text under `LICENSE`.