1
+ #pragma MIME application/bson
2
+
3
+ #include <type/time.pat>
4
+
5
+ enum Type : u8 {
6
+ Double = 0x01,
7
+ String = 0x02,
8
+ EmbeddedDocument = 0x03,
9
+ Array = 0x04,
10
+ Binary = 0x05,
11
+ Undefined = 0x06,
12
+ ObjectId = 0x07,
13
+ Boolean = 0x08,
14
+ UTCDatetime = 0x09,
15
+ Null = 0x0A,
16
+ Regex = 0x0B,
17
+ DBPointer = 0x0C,
18
+ JavaScript = 0x0D,
19
+ Symbol = 0x0E,
20
+ JavaScriptWithScope = 0x0F,
21
+ Int32 = 0x10,
22
+ Timestamp = 0x11,
23
+ Int64 = 0x12,
24
+ Decimal128 = 0x13,
25
+
26
+ MinKey = 0xFF,
27
+ MaxKey = 0x7F
28
+ };
29
+
30
+ enum Subtype : u8 {
31
+ GenericBinarySubtype = 0x00,
32
+ Function = 0x01,
33
+ BinaryOld = 0x02,
34
+ UUIDOld = 0x03,
35
+ UUID = 0x04,
36
+ MD5 = 0x05,
37
+ EncryptedBSONValue = 0x06,
38
+ CompressedBSONColumn = 0x07,
39
+ UserDefined = 0x80
40
+ };
41
+
42
+ struct Binary {
43
+ s32 length;
44
+ Subtype subtype;
45
+ u8 data[length];
46
+ };
47
+
48
+ struct String {
49
+ u32 length [[hidden]];
50
+ char value[length];
51
+ } [[sealed, format("format_string")]];
52
+
53
+ struct CString {
54
+ char value[];
55
+ } [[sealed, format("format_string")]];
56
+
57
+ fn format_string(auto string) {
58
+ return string.value;
59
+ };
60
+
61
+ struct ObjectId {
62
+ type::time32_t timestamp;
63
+ u8 randomValue[5];
64
+ u24 counter;
65
+ };
66
+
67
+ struct DBPointer {
68
+ String name;
69
+ ObjectId value;
70
+ };
71
+
72
+
73
+ using Document;
74
+
75
+ struct Element {
76
+ Type type;
77
+
78
+ CString name;
79
+
80
+ if (type == Type::Double) {
81
+ double value;
82
+ } else if (type == Type::String) {
83
+ String value;
84
+ } else if (type == Type::EmbeddedDocument) {
85
+ Document value;
86
+ } else if (type == Type::Array) {
87
+ Document value;
88
+ } else if (type == Type::Binary) {
89
+ Binary value;
90
+ } else if (type == Type::Undefined) {
91
+ /* undefined */
92
+ } else if (type == Type::ObjectId) {
93
+ ObjectId value;
94
+ } else if (type == Type::Boolean) {
95
+ bool value;
96
+ } else if (type == Type::UTCDatetime) {
97
+ type::time64_t value;
98
+ } else if (type == Type::Null) {
99
+ /* null */
100
+ } else if (type == Type::Regex) {
101
+ CString regexPattern;
102
+ CString regexOptions;
103
+ } else if (type == Type::DBPointer) {
104
+ DBPointer value;
105
+ } else if (type == Type::JavaScript) {
106
+ String value;
107
+ } else if (type == Type::Symbol) {
108
+ String value;
109
+ } else if (type == Type::JavaScriptWithScope) {
110
+ String value;
111
+ } else if (type == Type::Int32) {
112
+ s32 value;
113
+ } else if (type == Type::Timestamp) {
114
+ u64 value;
115
+ } else if (type == Type::Int64) {
116
+ s64 value;
117
+ } else if (type == Type::Decimal128) {
118
+ u128 value;
119
+ }
120
+ };
121
+
122
+ struct Document {
123
+ s32 listLength;
124
+ Element elements[while($ < ((addressof(this) + listLength) - 1))];
125
+ padding[1];
126
+ };
127
+
128
+ Document document @ 0x00;
0 commit comments