Line data Source code
1 : /***************************************************************************\
2 : * Name : serialize library for protobuf *
3 : * Description : encoding in protobuf *
4 : * Author : antonin.kriz@gmail.com *
5 : * ------------------------------------------------------------------------- *
6 : * This is free software; you can redistribute it and/or modify it under the *
7 : * terms of the MIT license. A copy of the license can be found in the file *
8 : * "LICENSE" at the root of this distribution. *
9 : \***************************************************************************/
10 :
11 : #pragma once
12 :
13 : #include <cstdint>
14 : #include <stdexcept>
15 :
16 : namespace spb::pb::detail
17 : {
18 : enum class tag_type : uint32_t
19 : {
20 : invalid = 0
21 : };
22 :
23 : //- https://protobuf.dev/programming-guides/encoding/
24 : enum class wire_type : uint8_t
25 : {
26 : //- int32, int64, uint32, uint64, sint32, sint64, bool, enum
27 : varint = 0,
28 : //- fixed64, sfixed64, double
29 : fixed64 = 1,
30 : //- string, bytes, embedded messages, packed repeated fields
31 : length_delimited = 2,
32 : //- not used
33 : StartGroup = 3,
34 : //- not used
35 : EndGroup = 4,
36 : //- fixed32, sfixed32, float
37 : fixed32 = 5
38 : };
39 :
40 : //- type1, type2 and packed flag
41 : enum scalar_encoder : uint8_t
42 : {
43 : none = 0,
44 : //- int32, int64, uint32, uint64, bool
45 : varint = 0x01,
46 : //- zigzag int32 or int64
47 : svarint = 0x02,
48 : //- 4 bytes
49 : i32 = 0x03,
50 : //- 8 bytes
51 : i64 = 0x04,
52 : //- packed array
53 : packed = 0x08
54 : };
55 :
56 : struct serialize_mode
57 : {
58 : scalar_encoder encoder = {};
59 : scalar_encoder encoder2 = {};
60 : size_t max_count = 0;
61 : size_t max_size = 0;
62 : };
63 :
64 : constexpr auto make_packed(scalar_encoder a) noexcept -> scalar_encoder
65 : {
66 : return scalar_encoder(a | scalar_encoder::packed);
67 : }
68 :
69 : constexpr auto is_packed(scalar_encoder a) noexcept -> bool
70 : {
71 : return (a & scalar_encoder::packed) == scalar_encoder::packed;
72 : }
73 :
74 : constexpr auto reset_packed(serialize_mode a) noexcept -> serialize_mode
75 : {
76 : a.encoder = scalar_encoder(a.encoder & ~scalar_encoder::packed);
77 : return a;
78 : }
79 :
80 4487 : constexpr auto encoder_type(scalar_encoder a) noexcept -> scalar_encoder
81 : {
82 4487 : return scalar_encoder(a & 0x07);
83 : }
84 :
85 4487 : constexpr auto to_wire_type(scalar_encoder a) noexcept -> wire_type
86 : {
87 4487 : switch (encoder_type(a))
88 : {
89 1240 : case scalar_encoder::i32:
90 1240 : return wire_type::fixed32;
91 987 : case scalar_encoder::i64:
92 987 : return wire_type::fixed64;
93 2260 : default:
94 2260 : return wire_type::varint;
95 : }
96 : }
97 :
98 970 : inline void check_size(size_t size, size_t max_size)
99 : {
100 970 : if (size > max_size) [[unlikely]]
101 132 : throw std::length_error("field is too large");
102 838 : }
103 :
104 : } // namespace spb::pb::detail
|