1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #ifndef ICE_PROTOCOL_H
6 #define ICE_PROTOCOL_H
7
8 #include <Ice/Config.h>
9 #include <Ice/Version.h>
10
11 namespace IceInternal
12 {
13
14 //
15 // Size of the Ice protocol header
16 //
17 // Magic number (4 Bytes)
18 // Protocol version major (Byte)
19 // Protocol version minor (Byte)
20 // Encoding version major (Byte)
21 // Encoding version minor (Byte)
22 // Message type (Byte)
23 // Compression status (Byte)
24 // Message size (Int)
25 //
26 const ::Ice::Int headerSize = 14;
27
28 //
29 // The magic number at the front of each message
30 //
31 extern const ::Ice::Byte magic[4];
32
33 //
34 // The current Ice protocol, protocol encoding and encoding version
35 //
36 const ::Ice::Byte protocolMajor = 1;
37 const ::Ice::Byte protocolMinor = 0;
38 const ::Ice::Byte protocolEncodingMajor = 1;
39 const ::Ice::Byte protocolEncodingMinor = 0;
40
41 const ::Ice::Byte encodingMajor = 1;
42 const ::Ice::Byte encodingMinor = 1;
43
44 //
45 // The Ice protocol message types
46 //
47 const ::Ice::Byte requestMsg = 0;
48 const ::Ice::Byte requestBatchMsg = 1;
49 const ::Ice::Byte replyMsg = 2;
50 const ::Ice::Byte validateConnectionMsg = 3;
51 const ::Ice::Byte closeConnectionMsg = 4;
52
53 //
54 // The request header, batch request header and reply header.
55 //
56 extern const ::Ice::Byte requestHdr[headerSize + sizeof(Ice::Int)];
57 extern const ::Ice::Byte requestBatchHdr[headerSize + sizeof(Ice::Int)];
58 extern const ::Ice::Byte replyHdr[headerSize];
59
60 //
61 // IPv4/IPv6 support enumeration.
62 //
63 enum ProtocolSupport
64 {
65 EnableIPv4,
66 EnableIPv6,
67 EnableBoth
68 };
69
70 ICE_API void stringToMajorMinor(const ::std::string&, Ice::Byte&, Ice::Byte&);
71
72 template<typename T> std::string
versionToString(const T & v)73 versionToString(const T& v)
74 {
75 std::ostringstream os;
76 os << v;
77 return os.str();
78 }
79
80 template<typename T> T
stringToVersion(const::std::string & str)81 stringToVersion(const ::std::string& str)
82 {
83 T v;
84 stringToMajorMinor(str, v.major, v.minor);
85 return v;
86 }
87
88 template<typename T> bool
isSupported(const T & version,const T & supported)89 isSupported(const T& version, const T& supported)
90 {
91 return version.major == supported.major && version.minor <= supported.minor;
92 }
93
94 ICE_API void throwUnsupportedProtocolException(const char*, int, const Ice::ProtocolVersion&,
95 const Ice::ProtocolVersion&);
96 ICE_API void throwUnsupportedEncodingException(const char*, int, const Ice::EncodingVersion&,
97 const Ice::EncodingVersion&);
98
99 const ::Ice::Byte OPTIONAL_END_MARKER = 0xFF;
100
101 const ::Ice::Byte FLAG_HAS_TYPE_ID_STRING = (1<<0);
102 const ::Ice::Byte FLAG_HAS_TYPE_ID_INDEX = (1<<1);
103 const ::Ice::Byte FLAG_HAS_TYPE_ID_COMPACT = (1<<0) | (1<<1);
104 const ::Ice::Byte FLAG_HAS_OPTIONAL_MEMBERS = (1<<2);
105 const ::Ice::Byte FLAG_HAS_INDIRECTION_TABLE = (1<<3);
106 const ::Ice::Byte FLAG_HAS_SLICE_SIZE = (1<<4);
107 const ::Ice::Byte FLAG_IS_LAST_SLICE = (1<<5);
108
109 }
110
111 namespace Ice
112 {
113
114 /** Identifies protocol version 1.0. */
115 ICE_API extern const ProtocolVersion Protocol_1_0;
116
117 /** Identifies encoding version 1.0. */
118 ICE_API extern const EncodingVersion Encoding_1_0;
119
120 /** Identifies encoding version 1.1. */
121 ICE_API extern const EncodingVersion Encoding_1_1;
122
123 /** Identifies the latest protocol version. */
124 ICE_API extern const ProtocolVersion currentProtocol;
125
126 /** Identifies the latest protocol encoding version. */
127 ICE_API extern const EncodingVersion currentProtocolEncoding;
128
129 /** Identifies the latest encoding version. */
130 ICE_API extern const EncodingVersion currentEncoding;
131
132 /**
133 * Converts a protocol version into a string.
134 * @param v The protocol version.
135 * @return A string representing the protocol version.
136 */
137 inline ::std::string
protocolVersionToString(const Ice::ProtocolVersion & v)138 protocolVersionToString(const Ice::ProtocolVersion& v)
139 {
140 return IceInternal::versionToString<ProtocolVersion>(v);
141 }
142
143 /**
144 * Converts a string into a protocol version.
145 * @param v The string containing a stringified protocol version.
146 * @return The protocol version.
147 * @throws VersionParseException If the given string is not in the X.Y format.
148 */
149 inline ::Ice::ProtocolVersion
stringToProtocolVersion(const::std::string & v)150 stringToProtocolVersion(const ::std::string& v)
151 {
152 return IceInternal::stringToVersion<ProtocolVersion>(v);
153 }
154
155 /**
156 * Converts an encoding version into a string.
157 * @param v The encoding version.
158 * @return A string representing the encoding version.
159 */
160 inline ::std::string
encodingVersionToString(const Ice::EncodingVersion & v)161 encodingVersionToString(const Ice::EncodingVersion& v)
162 {
163 return IceInternal::versionToString<EncodingVersion>(v);
164 }
165
166 /**
167 * Converts a string into an encoding version.
168 * @param v The string containing a stringified encoding version.
169 * @return The encoding version.
170 * @throws VersionParseException If the given string is not in the X.Y format.
171 */
172 inline ::Ice::EncodingVersion
stringToEncodingVersion(const::std::string & v)173 stringToEncodingVersion(const ::std::string& v)
174 {
175 return IceInternal::stringToVersion<EncodingVersion>(v);
176 }
177
178 inline std::ostream&
179 operator<<(std::ostream& out, const ProtocolVersion& version)
180 {
181 return out << static_cast<int>(version.major) << "." << static_cast<int>(version.minor);
182 }
183
184 inline std::ostream&
185 operator<<(std::ostream& out, const EncodingVersion& version)
186 {
187 return out << static_cast<int>(version.major) << "." << static_cast<int>(version.minor);
188 }
189
190 }
191
192 namespace IceInternal
193 {
194
195 inline void
checkSupportedProtocol(const Ice::ProtocolVersion & v)196 checkSupportedProtocol(const Ice::ProtocolVersion& v)
197 {
198 if(!isSupported(v, Ice::currentProtocol))
199 {
200 throwUnsupportedProtocolException(__FILE__, __LINE__, v, Ice::currentProtocol);
201 }
202 }
203
204 inline void
checkSupportedProtocolEncoding(const Ice::EncodingVersion & v)205 checkSupportedProtocolEncoding(const Ice::EncodingVersion& v)
206 {
207 if(!isSupported(v, Ice::currentProtocolEncoding))
208 {
209 throwUnsupportedEncodingException(__FILE__, __LINE__, v, Ice::currentProtocolEncoding);
210 }
211 }
212
213 inline void
checkSupportedEncoding(const Ice::EncodingVersion & v)214 checkSupportedEncoding(const Ice::EncodingVersion& v)
215 {
216 if(!isSupported(v, Ice::currentEncoding))
217 {
218 throwUnsupportedEncodingException(__FILE__, __LINE__, v, Ice::currentEncoding);
219 }
220 }
221
222 //
223 // Either return the given protocol if not compatible, or the greatest
224 // supported protocol otherwise.
225 //
226 inline const Ice::ProtocolVersion
getCompatibleProtocol(const Ice::ProtocolVersion & v)227 getCompatibleProtocol(const Ice::ProtocolVersion& v)
228 {
229 if(v.major != Ice::currentProtocol.major)
230 {
231 return v; // Unsupported protocol, return as is.
232 }
233 else if(v.minor < Ice::currentProtocol.minor)
234 {
235 return v; // Supported protocol.
236 }
237 else
238 {
239 //
240 // Unsupported but compatible, use the currently supported
241 // protocol, that's the best we can do.
242 //
243 return Ice::currentProtocol;
244 }
245 }
246
247 //
248 // Either return the given encoding if not compatible, or the greatest
249 // supported encoding otherwise.
250 //
251 inline const Ice::EncodingVersion&
getCompatibleEncoding(const Ice::EncodingVersion & v)252 getCompatibleEncoding(const Ice::EncodingVersion& v)
253 {
254 if(v.major != Ice::currentEncoding.major)
255 {
256 return v; // Unsupported encoding, return as is.
257 }
258 else if(v.minor < Ice::currentEncoding.minor)
259 {
260 return v; // Supported encoding.
261 }
262 else
263 {
264 //
265 // Unsupported but compatible, use the currently supported
266 // encoding, that's the best we can do.
267 //
268 return Ice::currentEncoding;
269 }
270 }
271
272 }
273
274 #endif
275