Coverage Report

Created: 2025-11-11 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/butil/binary_printer.cpp
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
// Date: Thu Nov 22 13:57:56 CST 2012
19
20
#include <inttypes.h>
21
#include "butil/iobuf.h"
22
#include "butil/binary_printer.h"
23
24
namespace butil {
25
26
static char s_binary_char_map[] = {
27
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
28
    'A', 'B', 'C', 'D', 'E', 'F'
29
};
30
31
template <typename Appender>
32
class BinaryCharPrinter {
33
public:
34
    static const size_t BUF_SIZE = 127;
35
0
    explicit BinaryCharPrinter(Appender* a) : _n(0), _appender(a) {}
Unexecuted instantiation: butil::BinaryCharPrinter<butil::OStreamAppender>::BinaryCharPrinter(butil::OStreamAppender*)
Unexecuted instantiation: butil::BinaryCharPrinter<butil::StringAppender>::BinaryCharPrinter(butil::StringAppender*)
36
0
    ~BinaryCharPrinter() { Flush(); }
Unexecuted instantiation: butil::BinaryCharPrinter<butil::OStreamAppender>::~BinaryCharPrinter()
Unexecuted instantiation: butil::BinaryCharPrinter<butil::StringAppender>::~BinaryCharPrinter()
37
    void PushChar(unsigned char c);
38
    void Flush();
39
private:
40
    uint32_t _n;
41
    Appender* _appender;
42
    char _buf[BUF_SIZE];
43
};
44
45
template <typename Appender>
46
0
void BinaryCharPrinter<Appender>::Flush() {
47
0
    if (_n > 0) {
48
0
        _appender->Append(_buf, _n);
49
0
        _n = 0;
50
0
    }
51
0
}
Unexecuted instantiation: butil::BinaryCharPrinter<butil::OStreamAppender>::Flush()
Unexecuted instantiation: butil::BinaryCharPrinter<butil::StringAppender>::Flush()
52
53
template <typename Appender>
54
0
void BinaryCharPrinter<Appender>::PushChar(unsigned char c) {
55
0
    if (_n > BUF_SIZE - 3) {
56
0
        _appender->Append(_buf, _n);
57
0
        _n = 0;
58
0
    }
59
0
    if (c >= 32 && c <= 126) { // displayable ascii characters
60
0
        if (c != '\\') {
61
0
            _buf[_n++] = c;
62
0
        } else {
63
0
            _buf[_n++] = '\\';
64
0
            _buf[_n++] = '\\';
65
0
        }
66
0
    } else {
67
0
        _buf[_n++] = '\\';
68
0
        switch (c) {
69
0
        case '\b': _buf[_n++] = 'b'; break;
70
0
        case '\t': _buf[_n++] = 't'; break;
71
0
        case '\n': _buf[_n++] = 'n'; break;
72
0
        case '\r': _buf[_n++] = 'r'; break;
73
0
        default: 
74
0
            _buf[_n++] = s_binary_char_map[c >> 4];
75
0
            _buf[_n++] = s_binary_char_map[c & 0xF];
76
0
            break;
77
0
        }
78
0
    }
79
0
}
Unexecuted instantiation: butil::BinaryCharPrinter<butil::OStreamAppender>::PushChar(unsigned char)
Unexecuted instantiation: butil::BinaryCharPrinter<butil::StringAppender>::PushChar(unsigned char)
80
81
class OStreamAppender {
82
public:
83
0
    OStreamAppender(std::ostream& os) : _os(&os) {}
84
0
    void Append(const char* b, size_t n) { _os->write(b, n); }
85
private:
86
    std::ostream* _os;
87
};
88
89
class StringAppender {
90
public:
91
0
    StringAppender(std::string* str) : _str(str) {}
92
0
    void Append(const char* b, size_t n) { _str->append(b, n); }
93
private:
94
    std::string* _str;
95
};
96
97
template <typename Appender>
98
0
static void PrintIOBuf(Appender* appender, const IOBuf& b, size_t max_length) {
99
0
    BinaryCharPrinter<Appender> printer(appender);
100
0
    const size_t n = b.backing_block_num();
101
0
    size_t nw = 0;
102
0
    for (size_t i = 0; i < n; ++i) {
103
0
        StringPiece blk = b.backing_block(i);
104
0
        for (size_t j = 0; j < blk.size(); ++j) {
105
0
            if (nw >= max_length) {
106
0
                printer.Flush();
107
0
                char buf[48];
108
0
                int len = snprintf(buf, sizeof(buf), "...<skipping %" PRIu64 " bytes>",
109
0
                        (uint64_t)(b.size() - nw));
110
0
                appender->Append(buf, len);
111
0
                return;
112
0
            }
113
0
            ++nw;
114
0
            printer.PushChar(blk[j]);
115
0
        }
116
0
    }
117
0
}
Unexecuted instantiation: binary_printer.cpp:void butil::PrintIOBuf<butil::OStreamAppender>(butil::OStreamAppender*, butil::IOBuf const&, unsigned long)
Unexecuted instantiation: binary_printer.cpp:void butil::PrintIOBuf<butil::StringAppender>(butil::StringAppender*, butil::IOBuf const&, unsigned long)
118
119
template <typename Appender>
120
0
static void PrintString(Appender* appender, const StringPiece& s, size_t max_length) {
121
0
    BinaryCharPrinter<Appender> printer(appender);
122
0
    for (size_t i = 0; i < s.size(); ++i) {
123
0
        if (i >= max_length) {
124
0
            printer.Flush();
125
0
            char buf[48];
126
0
            int len = snprintf(buf, sizeof(buf), "...<skipping %" PRIu64 " bytes>",
127
0
                               (uint64_t)(s.size() - i));
128
0
            appender->Append(buf, len);
129
0
            return;
130
0
        }
131
0
        printer.PushChar(s[i]);
132
0
    }
133
0
}
Unexecuted instantiation: binary_printer.cpp:void butil::PrintString<butil::OStreamAppender>(butil::OStreamAppender*, butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned long)
Unexecuted instantiation: binary_printer.cpp:void butil::PrintString<butil::StringAppender>(butil::StringAppender*, butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned long)
134
135
0
void ToPrintable::Print(std::ostream& os) const {
136
0
    OStreamAppender appender(os);
137
0
    if (_iobuf) {
138
0
        PrintIOBuf(&appender, *_iobuf, _max_length);
139
0
    } else if (!_str.empty()) {
140
0
        PrintString(&appender, _str, _max_length);
141
0
    }
142
0
}
143
144
0
std::string ToPrintableString(const IOBuf& data, size_t max_length) {
145
0
    std::string result;
146
0
    StringAppender appender(&result);
147
0
    PrintIOBuf(&appender, data, max_length);
148
0
    return result;
149
0
}
150
151
0
std::string ToPrintableString(const StringPiece& data, size_t max_length) {
152
0
    std::string result;
153
0
    StringAppender appender(&result);
154
0
    PrintString(&appender, data, max_length);
155
0
    return result;
156
0
}
157
158
0
std::string ToPrintableString(const void* data, size_t n, size_t max_length) {
159
0
    std::string result;
160
0
    StringAppender appender(&result);
161
0
    PrintString(&appender, StringPiece((const char*)data, n), max_length);
162
0
    return result;
163
0
}
164
165
} // namespace butil