1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 namespace IceInternal
6 {
7     public sealed class Protocol
8     {
9         //
10         // Size of the Ice protocol header
11         //
12         // Magic number (4 bytes)
13         // Protocol version major (Byte)
14         // Protocol version minor (Byte)
15         // Encoding version major (Byte)
16         // Encoding version minor (Byte)
17         // Message type (Byte)
18         // Compression status (Byte)
19         // Message size (Int)
20         //
21         internal const int headerSize = 14;
22 
23         //
24         // The magic number at the front of each message
25         //
26         internal static readonly byte[] magic = new byte[] { 0x49, 0x63, 0x65, 0x50 }; // 'I', 'c', 'e', 'P'
27 
28         //
29         // The current Ice protocol and encoding version
30         //
31         internal const byte protocolMajor = 1;
32         internal const byte protocolMinor = 0;
33         internal const byte protocolEncodingMajor = 1;
34         internal const byte protocolEncodingMinor = 0;
35 
36         internal const byte encodingMajor = 1;
37         internal const byte encodingMinor = 1;
38 
39         public const byte OPTIONAL_END_MARKER           = 0xFF;
40 
41         public const byte FLAG_HAS_TYPE_ID_STRING       = (1<<0);
42         public const byte FLAG_HAS_TYPE_ID_INDEX        = (1<<1);
43         public const byte FLAG_HAS_TYPE_ID_COMPACT      = (1<<1 | 1<<0);
44         public const byte FLAG_HAS_OPTIONAL_MEMBERS     = (1<<2);
45         public const byte FLAG_HAS_INDIRECTION_TABLE    = (1<<3);
46         public const byte FLAG_HAS_SLICE_SIZE           = (1<<4);
47         public const byte FLAG_IS_LAST_SLICE            = (1<<5);
48 
49         //
50         // The Ice protocol message types
51         //
52         internal const byte requestMsg = 0;
53         internal const byte requestBatchMsg = 1;
54         internal const byte replyMsg = 2;
55         internal const byte validateConnectionMsg = 3;
56         internal const byte closeConnectionMsg = 4;
57 
58         internal static readonly byte[] requestHdr = new byte[]
59         {
60             magic[0], magic[1], magic[2], magic[3],
61             protocolMajor, protocolMinor,
62             protocolEncodingMajor, protocolEncodingMinor,
63             requestMsg,
64             0, // Compression status.
65             0, 0, 0, 0, // Message size (placeholder).
66             0, 0, 0, 0  // Request ID (placeholder).
67         };
68 
69         internal static readonly byte[] requestBatchHdr = new byte[]
70         {
71             magic[0], magic[1], magic[2], magic[3],
72             protocolMajor, protocolMinor,
73             protocolEncodingMajor, protocolEncodingMinor,
74             requestBatchMsg,
75             0, // Compression status.
76             0, 0, 0, 0, // Message size (placeholder).
77             0, 0, 0, 0  // Number of requests in batch (placeholder).
78         };
79 
80         internal static readonly byte[] replyHdr = new byte[]
81         {
82             magic[0], magic[1], magic[2], magic[3],
83             protocolMajor, protocolMinor,
84             protocolEncodingMajor, protocolEncodingMinor,
85             replyMsg,
86             0, // Compression status.
87             0, 0, 0, 0 // Message size (placeholder).
88         };
89 
90         internal static void
checkSupportedProtocol(Ice.ProtocolVersion v)91         checkSupportedProtocol(Ice.ProtocolVersion v)
92         {
93             if(v.major != protocolMajor || v.minor > protocolMinor)
94             {
95                 throw new Ice.UnsupportedProtocolException("", v, Ice.Util.currentProtocol);
96             }
97         }
98 
99         public static void
checkSupportedProtocolEncoding(Ice.EncodingVersion v)100         checkSupportedProtocolEncoding(Ice.EncodingVersion v)
101         {
102             if(v.major != protocolEncodingMajor || v.minor > protocolEncodingMinor)
103             {
104                 throw new Ice.UnsupportedEncodingException("", v, Ice.Util.currentProtocolEncoding);
105             }
106         }
107 
108         internal static void
checkSupportedEncoding(Ice.EncodingVersion v)109         checkSupportedEncoding(Ice.EncodingVersion v)
110         {
111             if(v.major != encodingMajor || v.minor > encodingMinor)
112             {
113                 throw new Ice.UnsupportedEncodingException("", v, Ice.Util.currentEncoding);
114             }
115         }
116 
117         //
118         // Either return the given protocol if not compatible, or the greatest
119         // supported protocol otherwise.
120         //
121         internal static Ice.ProtocolVersion
getCompatibleProtocol(Ice.ProtocolVersion v)122         getCompatibleProtocol(Ice.ProtocolVersion v)
123         {
124             if(v.major != Ice.Util.currentProtocol.major)
125             {
126                 return v; // Unsupported protocol, return as is.
127             }
128             else if(v.minor < Ice.Util.currentProtocol.minor)
129             {
130                 return v; // Supported protocol.
131             }
132             else
133             {
134                 //
135                 // Unsupported but compatible, use the currently supported
136                 // protocol, that's the best we can do.
137                 //
138                 return Ice.Util.currentProtocol;
139             }
140         }
141 
142         //
143         // Either return the given encoding if not compatible, or the greatest
144         // supported encoding otherwise.
145         //
146         internal static Ice.EncodingVersion
getCompatibleEncoding(Ice.EncodingVersion v)147         getCompatibleEncoding(Ice.EncodingVersion v)
148         {
149             if(v.major != Ice.Util.currentEncoding.major)
150             {
151                 return v; // Unsupported encoding, return as is.
152             }
153             else if(v.minor < Ice.Util.currentEncoding.minor)
154             {
155                 return v; // Supported encoding.
156             }
157             else
158             {
159                 //
160                 // Unsupported but compatible, use the currently supported
161                 // encoding, that's the best we can do.
162                 //
163                 return Ice.Util.currentEncoding;
164             }
165         }
166 
167         internal static bool
isSupported(Ice.ProtocolVersion version, Ice.ProtocolVersion supported)168         isSupported(Ice.ProtocolVersion version, Ice.ProtocolVersion supported)
169         {
170             return version.major == supported.major && version.minor <= supported.minor;
171         }
172 
173         internal static bool
isSupported(Ice.EncodingVersion version, Ice.EncodingVersion supported)174         isSupported(Ice.EncodingVersion version, Ice.EncodingVersion supported)
175         {
176             return version.major == supported.major && version.minor <= supported.minor;
177         }
178 
Protocol()179         private Protocol()
180         {
181         }
182     }
183 
184 }
185