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 : using enum_type = int32_t;
19 :
20 : enum class tag_type : uint32_t
21 : {
22 : invalid = 0
23 : };
24 :
25 : //- https://protobuf.dev/programming-guides/encoding/
26 : enum class wire_type : uint8_t
27 : {
28 : //- int32, int64, uint32, uint64, sint32, sint64, bool, enum
29 : varint = 0,
30 : //- fixed64, sfixed64, double
31 : fixed64 = 1,
32 : //- string, bytes, embedded messages, packed repeated fields
33 : length_delimited = 2,
34 : //- not used
35 : StartGroup = 3,
36 : //- not used
37 : EndGroup = 4,
38 : //- fixed32, sfixed32, float
39 : fixed32 = 5
40 : };
41 :
42 : //- type1, type2 and packed flag
43 : enum scalar_encoder : uint8_t
44 : {
45 : none = 0,
46 : //- int32, int64, uint32, uint64, bool
47 : varint = 0x01,
48 : //- zigzag int32 or int64
49 : svarint = 0x02,
50 : //- 4 bytes
51 : i32 = 0x03,
52 : //- 8 bytes
53 : i64 = 0x04,
54 : //- packed array
55 : packed = 0x08
56 : };
57 :
58 : struct serialize_mode
59 : {
60 : scalar_encoder encoder = {};
61 : scalar_encoder encoder2 = {};
62 : size_t max_count = 0;
63 : size_t max_size = 0;
64 : };
65 :
66 : constexpr auto make_packed(scalar_encoder a) noexcept -> scalar_encoder
67 : {
68 : return scalar_encoder(a | scalar_encoder::packed);
69 : }
70 :
71 : constexpr auto is_packed(scalar_encoder a) noexcept -> bool
72 : {
73 : return (a & scalar_encoder::packed) == scalar_encoder::packed;
74 : }
75 :
76 : constexpr auto reset_packed(serialize_mode a) noexcept -> serialize_mode
77 : {
78 : a.encoder = scalar_encoder(a.encoder & ~scalar_encoder::packed);
79 : return a;
80 : }
81 :
82 4486 : constexpr auto encoder_type(scalar_encoder a) noexcept -> scalar_encoder
83 : {
84 4486 : return scalar_encoder(a & 0x07);
85 : }
86 :
87 4486 : constexpr auto to_wire_type(scalar_encoder a) noexcept -> wire_type
88 : {
89 4486 : switch (encoder_type(a))
90 : {
91 1240 : case scalar_encoder::i32:
92 1240 : return wire_type::fixed32;
93 987 : case scalar_encoder::i64:
94 987 : return wire_type::fixed64;
95 2259 : default:
96 2259 : return wire_type::varint;
97 : }
98 : }
99 :
100 970 : inline void check_size(size_t size, size_t max_size)
101 : {
102 970 : if (size > max_size) [[unlikely]]
103 132 : throw std::length_error("field is too large");
104 838 : }
105 :
106 : } // namespace spb::pb::detail
|