Coverage Report

Created: 2026-01-09 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/brpc/src/mcpack2pb/mcpack2pb.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_MCPACK2PB_H
23
#define MCPACK2PB_MCPACK_MCPACK2PB_H
24
25
#include <google/protobuf/message.h>
26
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
27
#include "butil/containers/flat_map.h"
28
#include "butil/iobuf.h"
29
#include "mcpack2pb/parser.h"
30
#include "mcpack2pb/serializer.h"
31
32
namespace mcpack2pb {
33
34
typedef bool (*SetFieldFn)(::google::protobuf::Message* msg,
35
                           UnparsedValue& value);
36
37
// Mapping from filed name to its parsing&setting function.
38
typedef butil::FlatMap<butil::StringPiece, SetFieldFn> FieldMap;
39
40
enum SerializationFormat {
41
    FORMAT_COMPACK,
42
    FORMAT_MCPACK_V2
43
};
44
45
struct MessageHandler {
46
    // Parse `msg' from `input' as a mcpack_v2 or compack object.
47
    // Returns number of bytes consumed.
48
    size_t (*parse)(::google::protobuf::Message* msg,
49
                    ::google::protobuf::io::ZeroCopyInputStream* input);
50
51
    // Parse `msg' from `input' as a mcpack_v2 or compack object removed with header.
52
    // Returns true on success.
53
    bool (*parse_body)(::google::protobuf::Message* msg,
54
                       ::google::protobuf::io::ZeroCopyInputStream* input,
55
                       size_t size);
56
    
57
    // Serialize `msg' as a mcpack_v2 or compack object into `output'.
58
    // The serialization format is decided by `format'.
59
    // Returns true on success.
60
    bool (*serialize)(const ::google::protobuf::Message& msg,
61
                      ::google::protobuf::io::ZeroCopyOutputStream* output,
62
                      SerializationFormat format);
63
64
    // Serialize `msg' as a mcpack_v2 or compack object without header into
65
    // `serializer'. The serialization format is decided by `format'.
66
    // Returns true on success.
67
    void (*serialize_body)(const ::google::protobuf::Message& msg,
68
                           Serializer& serializer,
69
                           SerializationFormat format);
70
71
    // -------------------
72
    //  Helper functions
73
    // -------------------
74
75
    // Parse `msg' from IOBuf or array which may contain more data than just
76
    // the message.
77
    // Returns bytes parsed, 0 on error.
78
    size_t parse_from_iobuf_prefix(::google::protobuf::Message* msg,
79
                                   const ::butil::IOBuf& buf);
80
    size_t parse_from_array_prefix(::google::protobuf::Message* msg,
81
                                   const void* data, int size);
82
    // Parse `msg' from IOBuf or array which may just contain the message.
83
    // Returns true on success.
84
    bool parse_from_iobuf(::google::protobuf::Message* msg,
85
                          const ::butil::IOBuf& buf);
86
    bool parse_from_array(::google::protobuf::Message* msg,
87
                          const void* data, int size);
88
    // Serialize `msg' to IOBuf or string.
89
    // Returns true on success.
90
    bool serialize_to_iobuf(const ::google::protobuf::Message& msg,
91
                            ::butil::IOBuf* buf, SerializationFormat format);
92
93
    // TODO(gejun): serialize_to_string is not supported because OutputStream
94
    // requires the embedded zero-copy stream to return permanent memory blocks
95
    // to support reserve() however the string inside StringOutputStream may
96
    // be resized and invalidates previous returned memory blocks.
97
};
98
99
static const MessageHandler INVALID_MESSAGE_HANDLER = {NULL, NULL, NULL, NULL};
100
101
// if the *.pb.cc and *.pb.h was generated by mcpack2pb. This function will be
102
// called with the mcpack/compack parser and serializer BEFORE main().
103
void register_message_handler_or_die(const std::string& full_name,
104
                                     const MessageHandler& handler);
105
106
// Find the registered parser/serializer by `full_name'
107
// e.g. "example.SampleMessage".
108
// If the handler was not registered, function pointers inside are NULL.
109
MessageHandler find_message_handler(const std::string& full_name);
110
111
// inline impl.
112
inline size_t MessageHandler::parse_from_iobuf_prefix(
113
0
    ::google::protobuf::Message* msg, const ::butil::IOBuf& buf) {
114
0
    if (parse == NULL) {
115
0
        LOG(ERROR) << "`parse' is NULL";
116
0
        return 0;
117
0
    }
118
0
    ::butil::IOBufAsZeroCopyInputStream zc_stream(buf);
119
0
    return parse(msg, &zc_stream);
120
0
}
121
122
inline bool MessageHandler::parse_from_iobuf(
123
0
    ::google::protobuf::Message* msg, const ::butil::IOBuf& buf) {
124
0
    if (parse == NULL) {
125
0
        LOG(ERROR) << "`parse' is NULL";
126
0
        return 0;
127
0
    }
128
0
    ::butil::IOBufAsZeroCopyInputStream zc_stream(buf);
129
0
    return parse(msg, &zc_stream) == buf.size();
130
0
}
131
132
inline size_t MessageHandler::parse_from_array_prefix(
133
0
    ::google::protobuf::Message* msg, const void* data, int size) {
134
0
    if (parse == NULL) {
135
0
        LOG(ERROR) << "`parse' is NULL";
136
0
        return 0;
137
0
    }
138
0
    ::google::protobuf::io::ArrayInputStream zc_stream(data, size);
139
0
    return parse(msg, &zc_stream);
140
0
}
141
142
inline bool MessageHandler::parse_from_array(
143
0
    ::google::protobuf::Message* msg, const void* data, int size) {
144
0
    if (parse == NULL) {
145
0
        LOG(ERROR) << "`parse' is NULL";
146
0
        return 0;
147
0
    }
148
0
    ::google::protobuf::io::ArrayInputStream zc_stream(data, size);
149
0
    return (int)parse(msg, &zc_stream) == size;
150
0
}
151
152
inline bool MessageHandler::serialize_to_iobuf(
153
    const ::google::protobuf::Message& msg,
154
0
    ::butil::IOBuf* buf, SerializationFormat format) {
155
0
    if (serialize == NULL) {
156
0
        LOG(ERROR) << "`serialize' is NULL";
157
0
        return false;
158
0
    }
159
0
    ::butil::IOBufAsZeroCopyOutputStream zc_stream(buf);
160
0
    return serialize(msg, &zc_stream, format);
161
0
}
162
163
} // namespace mcpack2pb
164
165
#endif // MCPACK2PB_MCPACK_MCPACK2PB_H