Coverage Report

Created: 2025-12-14 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/mcpack2pb/parser-inl.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
// mcpack2pb - Make protobuf be front-end of mcpack/compack
19
20
// Date: Mon Oct 19 17:17:36 CST 2015
21
22
#ifndef MCPACK2PB_MCPACK_PARSER_INL_H
23
#define MCPACK2PB_MCPACK_PARSER_INL_H
24
25
namespace mcpack2pb {
26
27
// Binary head before items of array/object except isomorphic array.
28
struct ItemsHead {
29
    uint32_t item_count;
30
} __attribute__((__packed__));
31
32
0
inline size_t InputStream::popn(size_t n) {
33
0
    const size_t saved_n = n;
34
0
    do {
35
0
        if (_size >= (int64_t)n) {
36
0
            _data = (const char*)_data + n;
37
0
            _size -= n;
38
0
            _popped_bytes += saved_n;
39
0
            return saved_n;
40
0
        }
41
0
        n -= _size;
42
0
    } while (_zc_stream->Next(&_data, &_size));
43
0
    _data = NULL;
44
0
    _size = 0;
45
0
    _popped_bytes += saved_n - n;
46
0
    return saved_n - n;
47
0
}
48
    
49
0
inline size_t InputStream::cutn(void* out, size_t n) {
50
0
    const size_t saved_n = n;
51
0
    do {
52
0
        if (_size >= (int64_t)n) {
53
0
            memcpy(out, _data, n);
54
0
            _data = (const char*)_data + n;
55
0
            _size -= n;
56
0
            _popped_bytes += saved_n;
57
0
            return saved_n;
58
0
        }
59
0
        if (_size) {
60
0
            memcpy(out, _data, _size);
61
0
            out = (char*)out + _size;
62
0
            n -= _size;
63
0
        }
64
0
    } while (_zc_stream->Next(&_data, &_size));
65
0
    _data = NULL;
66
0
    _size = 0;
67
0
    _popped_bytes += saved_n - n;
68
0
    return saved_n - n;
69
0
}
70
71
template <typename T>
72
0
inline size_t InputStream::cut_packed_pod(T* packed_pod) {
73
0
    if (_size >= (int)sizeof(T)) {
74
0
        *packed_pod = *(T*)_data;
75
0
        _data = (const char*)_data + sizeof(T);
76
0
        _size -= sizeof(T);
77
0
        _popped_bytes += sizeof(T);
78
0
        return sizeof(T);
79
0
    }
80
0
    return cutn(packed_pod, sizeof(T));
81
0
}
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<mcpack2pb::ItemsHead>(mcpack2pb::ItemsHead*)
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<mcpack2pb::IsoItemsHead>(mcpack2pb::IsoItemsHead*)
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<mcpack2pb::FieldFixedHead>(mcpack2pb::FieldFixedHead*)
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<mcpack2pb::FieldShortHead>(mcpack2pb::FieldShortHead*)
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<mcpack2pb::FieldLongHead>(mcpack2pb::FieldLongHead*)
82
83
template <typename T>
84
0
inline T InputStream::cut_packed_pod() {
85
0
    T packed_pod;
86
0
    if (_size >= (int)sizeof(T)) {
87
0
        packed_pod = *(T*)_data;
88
0
        _data = (const char*)_data + sizeof(T);
89
0
        _size -= sizeof(T);
90
0
        _popped_bytes += sizeof(T);
91
0
        return packed_pod;
92
0
    }
93
0
    cutn(&packed_pod, sizeof(T));
94
0
    return packed_pod;
95
0
}
Unexecuted instantiation: signed char mcpack2pb::InputStream::cut_packed_pod<signed char>()
Unexecuted instantiation: short mcpack2pb::InputStream::cut_packed_pod<short>()
Unexecuted instantiation: int mcpack2pb::InputStream::cut_packed_pod<int>()
Unexecuted instantiation: long mcpack2pb::InputStream::cut_packed_pod<long>()
Unexecuted instantiation: unsigned char mcpack2pb::InputStream::cut_packed_pod<unsigned char>()
Unexecuted instantiation: unsigned short mcpack2pb::InputStream::cut_packed_pod<unsigned short>()
Unexecuted instantiation: unsigned int mcpack2pb::InputStream::cut_packed_pod<unsigned int>()
Unexecuted instantiation: unsigned long mcpack2pb::InputStream::cut_packed_pod<unsigned long>()
Unexecuted instantiation: bool mcpack2pb::InputStream::cut_packed_pod<bool>()
Unexecuted instantiation: float mcpack2pb::InputStream::cut_packed_pod<float>()
Unexecuted instantiation: double mcpack2pb::InputStream::cut_packed_pod<double>()
96
    
97
0
inline butil::StringPiece InputStream::ref_cut(std::string* aux, size_t n) {
98
0
    if (_size >= (int64_t)n) {
99
0
        butil::StringPiece ret((const char*)_data, n);
100
0
        _data = (const char*)_data + n;
101
0
        _size -= n;
102
0
        _popped_bytes += n;
103
0
        return ret;
104
0
    }
105
0
    aux->resize(n);
106
0
    size_t m = cutn(&(*aux)[0], n);
107
0
    if (m != n) {
108
0
        aux->resize(m);
109
0
    }
110
0
    return *aux;
111
0
}
112
113
0
inline uint8_t InputStream::peek1() {
114
0
    if (_size > 0) {
115
0
        return *(const uint8_t*)_data;
116
0
    }
117
0
    while (_zc_stream->Next(&_data, &_size)) {
118
0
        if (_size > 0) {
119
0
            return *(const uint8_t*)_data;
120
0
        }
121
0
    }
122
0
    return 0;
123
0
}
124
125
// Binary head before items of isomorphic array.
126
struct IsoItemsHead {
127
    uint8_t type;
128
} __attribute__((__packed__));
129
130
0
inline ObjectIterator UnparsedValue::as_object() {
131
0
    return ObjectIterator(_stream, _size);
132
0
}
133
134
0
inline ArrayIterator UnparsedValue::as_array() {
135
0
    return ArrayIterator(_stream, _size);
136
0
}
137
138
0
inline ISOArrayIterator UnparsedValue::as_iso_array() {
139
0
    return ISOArrayIterator(_stream, _size);
140
0
}
141
142
0
inline void ObjectIterator::init(InputStream* stream, size_t size) {
143
0
    _field_count = 0;
144
0
    _stream = stream;
145
0
    _expected_popped_bytes = _stream->popped_bytes() + sizeof(ItemsHead);
146
0
    _expected_popped_end = _stream->popped_bytes() + size;
147
0
    ItemsHead items_head;
148
0
    if (_stream->cut_packed_pod(&items_head) != sizeof(ItemsHead)) {
149
0
        CHECK(false) << "buffer(size=" << size << ") is not enough";
150
0
        return set_bad();
151
0
    }
152
0
    _field_count = items_head.item_count;
153
0
    operator++();
154
0
}
155
156
0
inline void ArrayIterator::init(InputStream* stream, size_t size) {
157
0
    _item_count = 0;
158
0
    _stream = stream;
159
0
    _expected_popped_bytes = _stream->popped_bytes() + sizeof(ItemsHead);
160
0
    _expected_popped_end = _stream->popped_bytes() + size;
161
0
    ItemsHead items_head;
162
0
    if (_stream->cut_packed_pod(&items_head) != sizeof(ItemsHead)) {
163
0
        CHECK(false) << "buffer(size=" << size << ") is not enough";
164
0
        return set_bad();
165
0
    }
166
0
    _item_count = items_head.item_count;
167
0
    operator++();
168
0
}
169
170
0
inline void ISOArrayIterator::init(InputStream* stream, size_t size) {
171
0
    _buf_index = 0;
172
0
    _buf_count = 0;
173
0
    _stream = stream;
174
0
    _item_type = (PrimitiveFieldType)0;
175
0
    _item_size = 0;
176
0
    _item_count = 0;
177
0
    _left_item_count = 0;
178
0
    IsoItemsHead items_head;
179
0
    if (_stream->cut_packed_pod(&items_head) != sizeof(IsoItemsHead)) {
180
0
        CHECK(false) << "Not enough data";
181
0
        return set_bad();
182
0
    }
183
0
    _item_type = (PrimitiveFieldType)items_head.type;
184
0
    _item_size = get_primitive_type_size(_item_type);
185
0
    if (!_item_size) {
186
0
        CHECK(false) << "type=" << type2str(_item_type)
187
0
                   << " in primitive isoarray is not primitive";
188
0
        return set_bad();
189
0
    }
190
0
    const size_t items_full_size = size - sizeof(IsoItemsHead);
191
0
    _item_count = items_full_size / _item_size;
192
0
    if (_item_count * _item_size != items_full_size) {
193
0
        CHECK(false) << "inconsistent item_count(" << _item_count
194
0
                   << ") and value_size(" << items_full_size
195
0
                   << "), item_size=" << _item_size;
196
0
        return set_bad();
197
0
    }
198
0
    _left_item_count = _item_count;
199
0
    operator++();
200
0
}
201
202
0
inline void ISOArrayIterator::operator++() {
203
0
    if (_buf_index + 1 < _buf_count) {
204
0
        ++_buf_index;
205
0
        return;
206
0
    }
207
0
    // Iterate all items in isomorphic array. We have to do this
208
0
    // right here because the items are lacking of headings.
209
0
    // Call on_primitives in batch to reduce overhead.
210
0
    if (_left_item_count == 0) {
211
0
        set_end();
212
0
        return;
213
0
    }
214
0
    _buf_count = std::min((uint32_t)sizeof(_item_buf) / _item_size, _left_item_count);
215
0
    _buf_index = 0;
216
0
    if (_stream->cutn(_item_buf, _buf_count * _item_size) !=
217
0
        _buf_count * _item_size) {
218
0
        CHECK(false) << "Not enough data";
219
0
        return set_bad();
220
0
    }
221
0
    _left_item_count -= _buf_count;
222
0
}
223
224
template <typename T>
225
0
inline T ISOArrayIterator::as_integer() const {
226
0
    const void* ptr = (_item_buf + _buf_index * _item_size);
227
0
    switch ((PrimitiveFieldType)_item_type) {
228
0
    case PRIMITIVE_FIELD_INT8:
229
0
        return *static_cast<const int8_t*>(ptr);
230
0
    case PRIMITIVE_FIELD_INT16:
231
0
        return *static_cast<const int16_t*>(ptr);
232
0
    case PRIMITIVE_FIELD_INT32:
233
0
        return *static_cast<const int32_t*>(ptr);
234
0
    case PRIMITIVE_FIELD_INT64:
235
0
        return *static_cast<const int64_t*>(ptr);
236
0
    case PRIMITIVE_FIELD_UINT8:
237
0
        return *static_cast<const uint8_t*>(ptr);
238
0
    case PRIMITIVE_FIELD_UINT16:
239
0
        return *static_cast<const uint16_t*>(ptr);
240
0
    case PRIMITIVE_FIELD_UINT32:
241
0
        return *static_cast<const uint32_t*>(ptr);
242
0
    case PRIMITIVE_FIELD_UINT64:
243
0
        return *static_cast<const uint64_t*>(ptr);
244
0
    case PRIMITIVE_FIELD_BOOL:
245
0
        return *static_cast<const bool*>(ptr);
246
0
    case PRIMITIVE_FIELD_FLOAT:
247
0
        return 0;
248
0
    case PRIMITIVE_FIELD_DOUBLE:
249
0
        return 0;
250
0
    }
251
0
    return 0;
252
0
}
Unexecuted instantiation: long mcpack2pb::ISOArrayIterator::as_integer<long>() const
Unexecuted instantiation: unsigned long mcpack2pb::ISOArrayIterator::as_integer<unsigned long>() const
Unexecuted instantiation: int mcpack2pb::ISOArrayIterator::as_integer<int>() const
Unexecuted instantiation: unsigned int mcpack2pb::ISOArrayIterator::as_integer<unsigned int>() const
Unexecuted instantiation: bool mcpack2pb::ISOArrayIterator::as_integer<bool>() const
253
254
template <typename T>
255
0
inline T ISOArrayIterator::as_fp() const {
256
0
    const void* ptr = (_item_buf + _buf_index * _item_size);
257
0
    if (_item_type == PRIMITIVE_FIELD_FLOAT) {
258
0
        return *static_cast<const float*>(ptr);
259
0
    } else if (_item_type == PRIMITIVE_FIELD_DOUBLE) {
260
0
        return *static_cast<const double*>(ptr);
261
0
    }
262
0
    return T();
263
0
}
Unexecuted instantiation: float mcpack2pb::ISOArrayIterator::as_fp<float>() const
Unexecuted instantiation: double mcpack2pb::ISOArrayIterator::as_fp<double>() const
264
265
}  // namespace mcpack2pb
266
267
#endif  // MCPACK2PB_MCPACK_PARSER_INL_H