Coverage Report

Created: 2025-12-14 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/butil/raw_pack.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
#ifndef BUTIL_RAW_PACK_H
19
#define BUTIL_RAW_PACK_H
20
21
#include "butil/sys_byteorder.h"
22
23
namespace butil {
24
25
// -------------------------------------------------------------------------
26
// NOTE: RawPacker/RawUnpacker is used for packing/unpacking low-level and
27
// hard-to-change header. If the fields are likely to be changed in future,
28
// use protobuf.
29
// -------------------------------------------------------------------------
30
31
// This utility class packs 32-bit and 64-bit integers into binary data 
32
// that can be unpacked by RawUnpacker. Notice that the packed data is 
33
// schemaless and user must match pack..() methods with same-width 
34
// unpack..() methods to get the integers back.
35
// Example:
36
//   char buf[16];  // 4 + 8 + 4 bytes.
37
//   butil::RawPacker(buf).pack32(a).pack64(b).pack32(c);  // buf holds packed data
38
//
39
//   ... network ...
40
//
41
//   // positional correspondence with pack..()
42
//   butil::Unpacker(buf2).unpack32(a).unpack64(b).unpack32(c);
43
class RawPacker {
44
public:
45
    // Notice: User must guarantee `stream' is as long as the packed data.
46
0
    explicit RawPacker(void* stream) : _stream((char*)stream) {}
47
0
    ~RawPacker() {}
48
49
    // Not using operator<< because some values may be packed differently from
50
    // its type.
51
0
    RawPacker& pack32(uint32_t host_value) {
52
0
        *(uint32_t*)_stream = HostToNet32(host_value);
53
0
        _stream += 4;
54
0
        return *this;
55
0
    }
56
57
0
    RawPacker& pack64(uint64_t host_value) {
58
0
        uint32_t *p = (uint32_t*)_stream;
59
0
        p[0] = HostToNet32(host_value >> 32);
60
0
        p[1] = HostToNet32(host_value & 0xFFFFFFFF);
61
0
        _stream += 8;
62
0
        return *this;
63
0
    }
64
65
private:
66
    char* _stream;
67
};
68
69
// This utility class unpacks 32-bit and 64-bit integers from binary data
70
// packed by RawPacker.
71
class RawUnpacker {
72
public:
73
0
    explicit RawUnpacker(const void* stream) : _stream((const char*)stream) {}
74
0
    ~RawUnpacker() {}
75
76
0
    RawUnpacker& unpack32(uint32_t & host_value) {
77
0
        host_value = NetToHost32(*(const uint32_t*)_stream);
78
0
        _stream += 4;
79
0
        return *this;
80
0
    }
81
82
0
    RawUnpacker& unpack64(uint64_t & host_value) {
83
0
        const uint32_t *p = (const uint32_t*)_stream;
84
0
        host_value = (((uint64_t)NetToHost32(p[0])) << 32) | NetToHost32(p[1]);
85
0
        _stream += 8;
86
0
        return *this;
87
0
    }
88
89
private:
90
    const char* _stream;
91
};
92
93
}  // namespace butil
94
95
#endif  // BUTIL_RAW_PACK_H