summaryrefslogtreecommitdiff
path: root/mcproto/encode.ha
blob: de3087132cf56e313c0754774b5c0db68f380a51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use endian;
use strings;
use uuid;

export fn encode_short(out: *[]u8, v: u16) void = {
	const buf: [2]u8 = [0...];
	endian::beputu16(buf, v);
	append(out, buf...);
};
export fn encode_int(out: *[]u8, v: u32) void = {
	const buf: [4]u8 = [0...];
	endian::beputu32(buf, v);
	append(out, buf...);
};
export fn encode_long(out: *[]u8, v: u64) void = {
	const buf: [8]u8 = [0...];
	endian::beputu64(buf, v);
	append(out, buf...);
};

export fn encode_bool(out: *[]u8, v: bool) void = {
	append(out, if (v) 1 else 0);
};

export fn encode_float(out: *[]u8, v: f32) void = {
	encode_int(out, *(&v: *u32));
};
export fn encode_double(out: *[]u8, v: f64) void = {
	encode_long(out, *(&v: *u64));
};

export fn encode_varint(out: *[]u8, v: i32) void = {
	let v = v: u32;

	for (true) {
		const continues = v & 0x7f != v;
		const high_bit: u8 = if (continues) 0x80 else 0x00;
		append(out, (v & 0x7f): u8 | high_bit);
		v >>= 7;
		if (!continues) return;
	};
};

export fn encode_string(out: *[]u8, string: str) void = {
	encode_varint(out, len(string): i32);
	append(out, strings::toutf8(string)...);
};

export fn encode_uuid(out: *[]u8, uuid: uuid::uuid) void = {
	append(out, uuid...);
};