1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
// **********************************************************************
//
// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
//
// This copy of Ice Protobuf is licensed to you under the terms
// described in the ICE_PROTOBUF_LICENSE file included in this
// distribution.
//
// **********************************************************************
#ifndef STREAM_PROTOBUF_H
#define STREAM_PROTOBUF_H
#include <Ice/Ice.h>
#include <google/protobuf/message_lite.h>
#ifdef ICE_CPP11
#include <type_traits>
#endif
//
// Tell Ice how to marshal and unmarshal a protobuf message to/from a sequence<byte>
//
namespace Ice
{
#ifdef ICE_CPP11
//
// We'll use std::enable_if to give protobuf its own helper category (see below)
//
const StreamHelperCategory StreamHelperCategoryProtobuf = 100;
#else
//
// We just assume a single "custom" category: Unknown
//
const StreamHelperCategory StreamHelperCategoryProtobuf = StreamHelperCategoryUnknown;
#endif
#ifdef ICE_CPP11
template<typename T>
struct StreamableTraits<T, typename std::enable_if<std::is_base_of< ::google::protobuf::MessageLite, T>::value >::type>
{
static const StreamHelperCategory helper = StreamHelperCategoryProtobuf;
static const int minWireSize = 1;
static const bool fixedLength = false;
};
#else
//
// We use the default 'Unknown' StreamHelperCategory
//
#endif
template<typename T>
struct StreamHelper<T, StreamHelperCategoryProtobuf>
{
template<class S> static inline void
write(S* stream, const ::google::protobuf::MessageLite& v)
{
std::vector<Byte> data(v.ByteSize());
if(!v.IsInitialized())
{
throw MarshalException(__FILE__, __LINE__,
"message not fully initialized: " + v.InitializationErrorString());
}
Byte* r = v.SerializeWithCachedSizesToArray(&data[0]);
if(r != &data[0] + data.size())
{
throw MarshalException(__FILE__, __LINE__, "message modified during marshaling");
}
stream->write(&data[0], &data[0] + data.size());
}
template<class S> static inline void
read(S* stream, ::google::protobuf::MessageLite& v)
{
std::pair<const Byte*, const Byte*> data;
stream->read(data);
if(!v.ParseFromArray(data.first, static_cast<int>(data.second - data.first)))
{
throw MarshalException(__FILE__, __LINE__, "ParseFromArray failed");
}
}
};
//
// Use default marshaling/unmarshaling, with optionalFormat = OptionalFormatVSize
//
template<>
struct GetOptionalFormat<StreamHelperCategoryProtobuf, 1, false>
{
static const OptionalFormat value = OptionalFormatVSize;
};
}
#endif
|