source: imaps-frontend/node_modules/@parcel/watcher/src/watchman/BSER.cc@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 7.8 KB
Line 
1#include <stdint.h>
2#include "./BSER.hh"
3
4BSERType decodeType(std::istream &iss) {
5 int8_t type;
6 iss.read(reinterpret_cast<char*>(&type), sizeof(type));
7 return (BSERType) type;
8}
9
10void expectType(std::istream &iss, BSERType expected) {
11 BSERType got = decodeType(iss);
12 if (got != expected) {
13 throw std::runtime_error("Unexpected BSER type");
14 }
15}
16
17void encodeType(std::ostream &oss, BSERType type) {
18 int8_t t = (int8_t)type;
19 oss.write(reinterpret_cast<char*>(&t), sizeof(t));
20}
21
22template<typename T>
23class Value : public BSERValue {
24public:
25 T value;
26 Value(T val) {
27 value = val;
28 }
29
30 Value() {}
31};
32
33class BSERInteger : public Value<int64_t> {
34public:
35 BSERInteger(int64_t value) : Value(value) {}
36 BSERInteger(std::istream &iss) {
37 int8_t int8;
38 int16_t int16;
39 int32_t int32;
40 int64_t int64;
41
42 BSERType type = decodeType(iss);
43
44 switch (type) {
45 case BSER_INT8:
46 iss.read(reinterpret_cast<char*>(&int8), sizeof(int8));
47 value = int8;
48 break;
49 case BSER_INT16:
50 iss.read(reinterpret_cast<char*>(&int16), sizeof(int16));
51 value = int16;
52 break;
53 case BSER_INT32:
54 iss.read(reinterpret_cast<char*>(&int32), sizeof(int32));
55 value = int32;
56 break;
57 case BSER_INT64:
58 iss.read(reinterpret_cast<char*>(&int64), sizeof(int64));
59 value = int64;
60 break;
61 default:
62 throw std::runtime_error("Invalid BSER int type");
63 }
64 }
65
66 int64_t intValue() override {
67 return value;
68 }
69
70 void encode(std::ostream &oss) override {
71 if (value <= INT8_MAX) {
72 encodeType(oss, BSER_INT8);
73 int8_t v = (int8_t)value;
74 oss.write(reinterpret_cast<char*>(&v), sizeof(v));
75 } else if (value <= INT16_MAX) {
76 encodeType(oss, BSER_INT16);
77 int16_t v = (int16_t)value;
78 oss.write(reinterpret_cast<char*>(&v), sizeof(v));
79 } else if (value <= INT32_MAX) {
80 encodeType(oss, BSER_INT32);
81 int32_t v = (int32_t)value;
82 oss.write(reinterpret_cast<char*>(&v), sizeof(v));
83 } else {
84 encodeType(oss, BSER_INT64);
85 oss.write(reinterpret_cast<char*>(&value), sizeof(value));
86 }
87 }
88};
89
90class BSERArray : public Value<BSER::Array> {
91public:
92 BSERArray() : Value() {}
93 BSERArray(BSER::Array value) : Value(value) {}
94 BSERArray(std::istream &iss) {
95 expectType(iss, BSER_ARRAY);
96 int64_t len = BSERInteger(iss).intValue();
97 for (int64_t i = 0; i < len; i++) {
98 value.push_back(BSER(iss));
99 }
100 }
101
102 BSER::Array arrayValue() override {
103 return value;
104 }
105
106 void encode(std::ostream &oss) override {
107 encodeType(oss, BSER_ARRAY);
108 BSERInteger(value.size()).encode(oss);
109 for (auto it = value.begin(); it != value.end(); it++) {
110 it->encode(oss);
111 }
112 }
113};
114
115class BSERString : public Value<std::string> {
116public:
117 BSERString(std::string value) : Value(value) {}
118 BSERString(std::istream &iss) {
119 expectType(iss, BSER_STRING);
120 int64_t len = BSERInteger(iss).intValue();
121 value.resize(len);
122 iss.read(&value[0], len);
123 }
124
125 std::string stringValue() override {
126 return value;
127 }
128
129 void encode(std::ostream &oss) override {
130 encodeType(oss, BSER_STRING);
131 BSERInteger(value.size()).encode(oss);
132 oss << value;
133 }
134};
135
136class BSERObject : public Value<BSER::Object> {
137public:
138 BSERObject() : Value() {}
139 BSERObject(BSER::Object value) : Value(value) {}
140 BSERObject(std::istream &iss) {
141 expectType(iss, BSER_OBJECT);
142 int64_t len = BSERInteger(iss).intValue();
143 for (int64_t i = 0; i < len; i++) {
144 auto key = BSERString(iss).stringValue();
145 auto val = BSER(iss);
146 value.emplace(key, val);
147 }
148 }
149
150 BSER::Object objectValue() override {
151 return value;
152 }
153
154 void encode(std::ostream &oss) override {
155 encodeType(oss, BSER_OBJECT);
156 BSERInteger(value.size()).encode(oss);
157 for (auto it = value.begin(); it != value.end(); it++) {
158 BSERString(it->first).encode(oss);
159 it->second.encode(oss);
160 }
161 }
162};
163
164class BSERDouble : public Value<double> {
165public:
166 BSERDouble(double value) : Value(value) {}
167 BSERDouble(std::istream &iss) {
168 expectType(iss, BSER_REAL);
169 iss.read(reinterpret_cast<char*>(&value), sizeof(value));
170 }
171
172 double doubleValue() override {
173 return value;
174 }
175
176 void encode(std::ostream &oss) override {
177 encodeType(oss, BSER_REAL);
178 oss.write(reinterpret_cast<char*>(&value), sizeof(value));
179 }
180};
181
182class BSERBoolean : public Value<bool> {
183public:
184 BSERBoolean(bool value) : Value(value) {}
185 bool boolValue() override { return value; }
186 void encode(std::ostream &oss) override {
187 int8_t t = value == true ? BSER_BOOL_TRUE : BSER_BOOL_FALSE;
188 oss.write(reinterpret_cast<char*>(&t), sizeof(t));
189 }
190};
191
192class BSERNull : public Value<bool> {
193public:
194 BSERNull() : Value(false) {}
195 void encode(std::ostream &oss) override {
196 encodeType(oss, BSER_NULL);
197 }
198};
199
200std::shared_ptr<BSERArray> decodeTemplate(std::istream &iss) {
201 expectType(iss, BSER_TEMPLATE);
202 auto keys = BSERArray(iss).arrayValue();
203 auto len = BSERInteger(iss).intValue();
204 std::shared_ptr<BSERArray> arr = std::make_shared<BSERArray>();
205 for (int64_t i = 0; i < len; i++) {
206 BSER::Object obj;
207 for (auto it = keys.begin(); it != keys.end(); it++) {
208 if (iss.peek() == 0x0c) {
209 iss.ignore(1);
210 continue;
211 }
212
213 auto val = BSER(iss);
214 obj.emplace(it->stringValue(), val);
215 }
216 arr->value.push_back(obj);
217 }
218 return arr;
219}
220
221BSER::BSER(std::istream &iss) {
222 BSERType type = decodeType(iss);
223 iss.unget();
224
225 switch (type) {
226 case BSER_ARRAY:
227 m_ptr = std::make_shared<BSERArray>(iss);
228 break;
229 case BSER_OBJECT:
230 m_ptr = std::make_shared<BSERObject>(iss);
231 break;
232 case BSER_STRING:
233 m_ptr = std::make_shared<BSERString>(iss);
234 break;
235 case BSER_INT8:
236 case BSER_INT16:
237 case BSER_INT32:
238 case BSER_INT64:
239 m_ptr = std::make_shared<BSERInteger>(iss);
240 break;
241 case BSER_REAL:
242 m_ptr = std::make_shared<BSERDouble>(iss);
243 break;
244 case BSER_BOOL_TRUE:
245 iss.ignore(1);
246 m_ptr = std::make_shared<BSERBoolean>(true);
247 break;
248 case BSER_BOOL_FALSE:
249 iss.ignore(1);
250 m_ptr = std::make_shared<BSERBoolean>(false);
251 break;
252 case BSER_NULL:
253 iss.ignore(1);
254 m_ptr = std::make_shared<BSERNull>();
255 break;
256 case BSER_TEMPLATE:
257 m_ptr = decodeTemplate(iss);
258 break;
259 default:
260 throw std::runtime_error("unknown BSER type");
261 }
262}
263
264BSER::BSER() : m_ptr(std::make_shared<BSERNull>()) {}
265BSER::BSER(BSER::Array value) : m_ptr(std::make_shared<BSERArray>(value)) {}
266BSER::BSER(BSER::Object value) : m_ptr(std::make_shared<BSERObject>(value)) {}
267BSER::BSER(const char *value) : m_ptr(std::make_shared<BSERString>(value)) {}
268BSER::BSER(std::string value) : m_ptr(std::make_shared<BSERString>(value)) {}
269BSER::BSER(int64_t value) : m_ptr(std::make_shared<BSERInteger>(value)) {}
270BSER::BSER(double value) : m_ptr(std::make_shared<BSERDouble>(value)) {}
271BSER::BSER(bool value) : m_ptr(std::make_shared<BSERBoolean>(value)) {}
272
273BSER::Array BSER::arrayValue() { return m_ptr->arrayValue(); }
274BSER::Object BSER::objectValue() { return m_ptr->objectValue(); }
275std::string BSER::stringValue() { return m_ptr->stringValue(); }
276int64_t BSER::intValue() { return m_ptr->intValue(); }
277double BSER::doubleValue() { return m_ptr->doubleValue(); }
278bool BSER::boolValue() { return m_ptr->boolValue(); }
279void BSER::encode(std::ostream &oss) {
280 m_ptr->encode(oss);
281}
282
283int64_t BSER::decodeLength(std::istream &iss) {
284 char pdu[2];
285 if (!iss.read(pdu, 2) || pdu[0] != 0 || pdu[1] != 1) {
286 throw std::runtime_error("Invalid BSER");
287 }
288
289 return BSERInteger(iss).intValue();
290}
291
292std::string BSER::encode() {
293 std::ostringstream oss(std::ios_base::binary);
294 encode(oss);
295
296 std::ostringstream res(std::ios_base::binary);
297 res.write("\x00\x01", 2);
298
299 BSERInteger(oss.str().size()).encode(res);
300 res << oss.str();
301 return res.str();
302}
Note: See TracBrowser for help on using the repository browser.