Action Engine
Loading...
Searching...
No Matches
int.h
1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef ACTIONENGINE_MSGPACK_INT_H
16#define ACTIONENGINE_MSGPACK_INT_H
17
18#include "actionengine/msgpack/core_helpers.h"
19
20namespace act::msgpack {
21
22inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
23 uint8_t* absl_nullable) {
24 const auto [pos, end, _] = data;
25 if (*pos == FormatSignature::kUInt8) {
26 if (end - pos < 2) {
27 return GetInsufficientDataError(data, "uint8_t");
28 }
29 return 2; // 1 byte for the signature + 1 byte for the value.
30 }
31
32 if (*pos > 0x7f) {
33 return GetInvalidFormatSignatureError(pos, "uint8_t", data.begin);
34 }
35
36 return 1;
37}
38
39inline absl::Status EgltMsgpackSerialize(uint8_t value,
40 const InsertInfo& insert) {
41 if (value <= 0x7f) {
42 insert.bytes->insert(insert.at, value);
43 return absl::OkStatus();
44 }
45 insert.bytes->insert(insert.at, {FormatSignature::kUInt8, value});
46 return absl::OkStatus();
47}
48
49inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
50 const LookupPointer& data, uint8_t* absl_nonnull output) {
51 const auto [pos, end, _] = data;
52 if (*pos <= 0x7f) {
53 *output = *pos;
54 return 1;
55 }
56
57 if (*pos == FormatSignature::kUInt8) {
58 if (end - pos < 2) {
59 return GetInsufficientDataError(data, "uint8_t");
60 }
61 *output = static_cast<uint8_t>(*(pos + 1));
62 return 2;
63 }
64
65 return GetInvalidFormatSignatureError(pos, "uint8_t", data.begin);
66}
67
68inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
69 int8_t* absl_nullable) {
70 const auto [pos, end, _] = data;
71 if (*pos == FormatSignature::kInt8) {
72 if (end - pos < 2) {
73 return GetInsufficientDataError(data, "int8_t");
74 }
75 return 2; // 1 byte for the signature + 1 byte for the value.
76 }
77
78 if (*pos <= 0x7f || *pos >= FormatSignature::kNegativeFixint) {
79 return 1; // Fixint, no additional bytes needed.
80 }
81
82 return GetInvalidFormatSignatureError(pos, "int8_t", data.begin);
83}
84
85inline absl::Status EgltMsgpackSerialize(int8_t value,
86 const InsertInfo& insert) {
87 if (value >= 0 && value <= 0x7f) {
88 insert.bytes->insert(insert.at, static_cast<Byte>(value));
89 return absl::OkStatus();
90 }
91 if (value < 0 && value >= -32) {
92 insert.bytes->insert(
93 insert.at,
94 static_cast<Byte>(FormatSignature::kNegativeFixint | (32 + value)));
95 return absl::OkStatus();
96 }
97
98 insert.bytes->insert(insert.at,
99 {FormatSignature::kInt8, static_cast<Byte>(value)});
100 return absl::OkStatus();
101}
102
103inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
104 const LookupPointer& data, int8_t* absl_nonnull output) {
105 const auto [pos, end, _] = data;
106 if (*pos <= 0x7f) {
107 *output = static_cast<int8_t>(*pos);
108 return 1;
109 }
110
111 if (*pos >= FormatSignature::kNegativeFixint) {
112 *output = static_cast<int8_t>(-32 + (*pos & 0x1F));
113 return 1;
114 }
115
116 if (*pos == FormatSignature::kInt8) {
117 if (end - pos < 2) {
118 return GetInsufficientDataError(data, "int8_t");
119 }
120 *output = static_cast<int8_t>(*(pos + 1));
121 return 2;
122 }
123
124 return GetInvalidFormatSignatureError(pos, "int8_t", data.begin);
125}
126
127inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
128 uint16_t* absl_nullable) {
129 const auto [pos, end, _] = data;
130 if (*pos == FormatSignature::kUInt16) {
131 if (end - pos < 3) {
132 return GetInsufficientDataError(data, "uint16_t");
133 }
134 return 3; // 1 byte for the signature + 2 bytes for the value.
135 }
136
137 if (const auto uint8_extent = GetExtent<uint8_t>(pos, end);
138 uint8_extent.ok()) {
139 return uint8_extent;
140 }
141
142 return GetInvalidFormatSignatureError(pos, "uint16_t", data.begin);
143}
144
145inline absl::Status EgltMsgpackSerialize(uint16_t value,
146 const InsertInfo& insert) {
147 if (value <= 0x7f) {
148 insert.bytes->insert(insert.at, static_cast<Byte>(value));
149 return absl::OkStatus();
150 }
151 if (value <= 0xff) {
152 insert.bytes->insert(insert.at,
153 {FormatSignature::kUInt8, static_cast<Byte>(value)});
154 return absl::OkStatus();
155 }
156 auto result = ToBigEndianBytes<uint16_t>(value, /*pad=*/1);
157 result[0] = FormatSignature::kUInt16;
158 insert.bytes->insert(insert.at, result.begin(), result.end());
159 return absl::OkStatus();
160}
161
162inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
163 const LookupPointer& data, uint16_t* absl_nonnull output) {
164 const auto [pos, end, _] = data;
165 if (auto deserialized = Deserialize<uint8_t>(data); deserialized.ok()) {
166 *output = deserialized->value;
167 return deserialized->extent;
168 }
169
170 if (auto deserialized = Deserialize<int8_t>(data); deserialized.ok()) {
171 if (deserialized->value < 0) {
172 return absl::InvalidArgumentError(
173 "Expected a uint16_t value, but found a negative int8_t value.");
174 }
175 *output = static_cast<uint16_t>(deserialized->value);
176 return deserialized->extent;
177 }
178
179 if (*pos == FormatSignature::kUInt16) {
180 if (end - pos < 3) {
181 return GetInsufficientDataError(data, "uint16_t");
182 }
183 *output = FromBigEndianBytes<uint16_t>(pos + 1);
184 return 3; // 1 byte for the signature + 2 bytes for the value.
185 }
186
187 return GetInvalidFormatSignatureError(pos, "uint16_t", data.begin);
188}
189
190inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
191 int16_t* absl_nullable) {
192 const auto [pos, end, _] = data;
193 if (*pos == FormatSignature::kInt16) {
194 if (end - pos < 3) {
195 return GetInsufficientDataError(data, "int16_t");
196 }
197 return 3; // 1 byte for the signature + 2 bytes for the value.
198 }
199
200 if (const auto uint8_extent = GetExtent<uint8_t>(pos, end);
201 uint8_extent.ok()) {
202 return uint8_extent;
203 }
204
205 if (const auto int8_extent = GetExtent<int8_t>(pos, end); int8_extent.ok()) {
206 return int8_extent;
207 }
208
209 return GetInvalidFormatSignatureError(pos, "int16_t", data.begin);
210}
211
212inline absl::Status EgltMsgpackSerialize(int16_t value,
213 const InsertInfo& insert) {
214 if (value >= -128 && value <= 127) {
215 return Serialize<int8_t>(static_cast<int8_t>(value), insert);
216 }
217 if (value >= 128 && value <= 255) {
218 return Serialize<uint8_t>(static_cast<uint8_t>(value), insert);
219 }
220 auto result = ToBigEndianBytes<int16_t>(value, /*pad=*/1);
221 result[0] = FormatSignature::kInt16;
222 insert.bytes->insert(insert.at, result.begin(), result.end());
223 return absl::OkStatus();
224}
225
226inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
227 const LookupPointer& data, int16_t* absl_nonnull output) {
228 const auto [pos, end, _] = data;
229 if (auto deserialized = Deserialize<uint8_t>(data); deserialized.ok()) {
230 *output = static_cast<int16_t>(deserialized->value);
231 return deserialized->extent;
232 }
233
234 if (auto deserialized = Deserialize<int8_t>(data); deserialized.ok()) {
235 *output = static_cast<int16_t>(deserialized->value);
236 return deserialized->extent;
237 }
238
239 if (*pos == FormatSignature::kInt16) {
240 if (end - pos < 3) {
241 return GetInsufficientDataError(data, "int16_t");
242 }
243 *output = FromBigEndianBytes<int16_t>(pos + 1);
244 return 3; // 1 byte for the signature + 2 bytes for the value.
245 }
246
247 return GetInvalidFormatSignatureError(pos, "int16_t", data.begin);
248}
249
250inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
251 uint32_t* absl_nullable) {
252 const auto [pos, end, _] = data;
253 if (*pos == FormatSignature::kUInt32) {
254 if (end - pos < 5) {
255 return GetInsufficientDataError(data, "uint32_t");
256 }
257 return 5; // 1 byte for the signature + 4 bytes for the value.
258 }
259
260 if (const auto uint16_extent = GetExtent<uint16_t>(pos, end);
261 uint16_extent.ok()) {
262 return uint16_extent;
263 }
264
265 return GetInvalidFormatSignatureError(pos, "uint32_t", data.begin);
266}
267
268inline absl::Status EgltMsgpackSerialize(uint32_t value,
269 const InsertInfo& insert) {
270 if (value <= 0xffff) {
271 return Serialize<uint16_t>(static_cast<uint16_t>(value), insert);
272 }
273 auto result = ToBigEndianBytes<uint32_t>(value, /*pad=*/1);
274 result[0] = FormatSignature::kUInt32;
275 insert.bytes->insert(insert.at, result.begin(), result.end());
276 return absl::OkStatus();
277}
278
279inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
280 const LookupPointer& data, uint32_t* absl_nonnull output) {
281 const auto [pos, end, _] = data;
282 if (auto deserialized = Deserialize<uint16_t>(data); deserialized.ok()) {
283 *output = static_cast<uint32_t>(deserialized->value);
284 return deserialized->extent;
285 }
286
287 if (auto deserialized = Deserialize<int16_t>(data); deserialized.ok()) {
288 if (deserialized->value < 0) {
289 return absl::InvalidArgumentError(
290 "Expected a uint32_t value, but found a negative int16_t value.");
291 }
292 *output = static_cast<uint32_t>(deserialized->value);
293 return deserialized->extent;
294 }
295
296 if (*pos == FormatSignature::kUInt32) {
297 if (end - pos < 5) {
298 return GetInsufficientDataError(data, "uint32_t");
299 }
300 *output = FromBigEndianBytes<uint32_t>(pos + 1);
301 return 5; // 1 byte for the signature + 4 bytes for the value.
302 }
303
304 return GetInvalidFormatSignatureError(pos, "uint32_t", data.begin);
305}
306
307inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
308 int32_t* absl_nullable) {
309 const auto [pos, end, _] = data;
310 if (*pos == FormatSignature::kInt32) {
311 if (end - pos < 5) {
312 return GetInsufficientDataError(data, "int32_t");
313 }
314 return 5; // 1 byte for the signature + 4 bytes for the value.
315 }
316
317 if (const auto uint16_extent = GetExtent<uint16_t>(pos, end);
318 uint16_extent.ok()) {
319 return uint16_extent;
320 }
321
322 if (const auto int16_extent = GetExtent<int16_t>(pos, end);
323 int16_extent.ok()) {
324 return int16_extent;
325 }
326
327 return GetInvalidFormatSignatureError(pos, "int32_t", data.begin);
328}
329
330inline absl::Status EgltMsgpackSerialize(int32_t value,
331 const InsertInfo& insert) {
332 if (value >= -32768 && value <= 32767) {
333 return Serialize<int16_t>(static_cast<int16_t>(value), insert);
334 }
335 if (value >= 0 && value <= 0xFFFF) {
336 return Serialize<uint16_t>(static_cast<uint16_t>(value), insert);
337 }
338 auto result = ToBigEndianBytes<int32_t>(value, /*pad=*/1);
339 result[0] = FormatSignature::kInt32;
340 insert.bytes->insert(insert.at, result.begin(), result.end());
341 return absl::OkStatus();
342}
343
344inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
345 const LookupPointer& data, int32_t* absl_nonnull output) {
346 const auto [pos, end, _] = data;
347
348 if (auto deserialized = Deserialize<uint16_t>(data); deserialized.ok()) {
349 *output = static_cast<int32_t>(deserialized->value);
350 return deserialized->extent;
351 }
352
353 if (auto deserialized = Deserialize<int16_t>(data); deserialized.ok()) {
354 *output = static_cast<int32_t>(deserialized->value);
355 return deserialized->extent;
356 }
357
358 if (*pos == FormatSignature::kInt32) {
359 if (end - pos < 5) {
360 return GetInsufficientDataError(data, "int32_t");
361 }
362 *output = FromBigEndianBytes<int32_t>(pos + 1);
363 return 5; // 1 byte for the signature + 4 bytes for the value.
364 }
365
366 return GetInvalidFormatSignatureError(pos, "int32_t", data.begin);
367}
368
369inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
370 uint64_t* absl_nullable) {
371 const auto [pos, end, _] = data;
372 if (*pos == FormatSignature::kUInt64) {
373 if (end - pos < 9) {
374 return GetInsufficientDataError(data, "uint64_t");
375 }
376 return 9; // 1 byte for the signature + 8 bytes for the value.
377 }
378
379 if (const auto uint32_extent = GetExtent<uint32_t>(pos, end);
380 uint32_extent.ok()) {
381 return uint32_extent;
382 }
383
384 return GetInvalidFormatSignatureError(pos, "uint64_t", data.begin);
385}
386
387inline absl::Status EgltMsgpackSerialize(uint64_t value,
388 const InsertInfo& insert) {
389 if (value <= 0xFFFFFFFF) {
390 return Serialize<uint32_t>(static_cast<uint32_t>(value), insert);
391 }
392 auto result = ToBigEndianBytes<uint64_t>(value, /*pad=*/1);
393 result[0] = FormatSignature::kUInt64;
394 insert.bytes->insert(insert.at, result.begin(), result.end());
395 return absl::OkStatus();
396}
397
398inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
399 const LookupPointer& data, uint64_t* absl_nonnull output) {
400 const auto [pos, end, _] = data;
401 if (auto deserialized = Deserialize<uint32_t>(data); deserialized.ok()) {
402 *output = static_cast<uint64_t>(deserialized->value);
403 return deserialized->extent;
404 }
405
406 if (auto deserialized = Deserialize<int32_t>(data); deserialized.ok()) {
407 if (deserialized->value < 0) {
408 return absl::InvalidArgumentError(
409 "Expected a uint64_t value, but found a negative int32_t value.");
410 }
411 *output = static_cast<uint64_t>(deserialized->value);
412 return deserialized->extent;
413 }
414
415 if (*pos == FormatSignature::kUInt64) {
416 if (end - pos < 9) {
417 return GetInsufficientDataError(data, "uint64_t");
418 }
419 *output = FromBigEndianBytes<uint64_t>(pos + 1);
420 return 9; // 1 byte for the signature + 8 bytes for the value.
421 }
422
423 return GetInvalidFormatSignatureError(pos, "uint64_t", data.begin);
424}
425
426inline absl::StatusOr<uint32_t> EgltMsgpackGetExtent(const LookupPointer& data,
427 int64_t* absl_nullable) {
428 const auto [pos, end, _] = data;
429 if (*pos == FormatSignature::kInt64) {
430 if (end - pos < 9) {
431 return GetInsufficientDataError(data, "int64_t");
432 }
433 return 9; // 1 byte for the signature + 8 bytes for the value.
434 }
435
436 if (const auto uint32_extent = GetExtent<uint32_t>(pos, end);
437 uint32_extent.ok()) {
438 return uint32_extent;
439 }
440
441 if (const auto int32_extent = GetExtent<int32_t>(pos, end);
442 int32_extent.ok()) {
443 return int32_extent;
444 }
445
446 return GetInvalidFormatSignatureError(pos, "int64_t", data.begin);
447}
448
449inline absl::Status EgltMsgpackSerialize(int64_t value,
450 const InsertInfo& insert) {
451 if (value >= -2147483648 && value <= 2147483647) {
452 return Serialize<int32_t>(static_cast<int32_t>(value), insert);
453 }
454 if (value >= 0 && value <= 0xFFFFFFFF) {
455 return Serialize<uint32_t>(static_cast<uint32_t>(value), insert);
456 }
457 auto result = ToBigEndianBytes<int64_t>(value, /*pad=*/1);
458 result[0] = FormatSignature::kInt64;
459 insert.bytes->insert(insert.at, result.begin(), result.end());
460 return absl::OkStatus();
461}
462
463inline absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
464 const LookupPointer& data, int64_t* absl_nonnull output) {
465 const auto [pos, end, _] = data;
466 if (auto deserialized = Deserialize<uint32_t>(data); deserialized.ok()) {
467 *output = static_cast<int64_t>(deserialized->value);
468 return deserialized->extent;
469 }
470
471 if (auto deserialized = Deserialize<int32_t>(data); deserialized.ok()) {
472 *output = static_cast<int64_t>(deserialized->value);
473 return deserialized->extent;
474 }
475
476 if (*pos == FormatSignature::kInt64) {
477 if (end - pos < 9) {
478 return GetInsufficientDataError(data, "int64_t");
479 }
480 *output = FromBigEndianBytes<int64_t>(pos + 1);
481 return 9; // 1 byte for the signature + 8 bytes for the value.
482 }
483
484 return GetInvalidFormatSignatureError(pos, "int64_t", data.begin);
485}
486
487} // namespace act::msgpack
488
489#endif // ACTIONENGINE_MSGPACK_INT_H