2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.CORBA / IIOPMessage.cs
1 // System.Runtime.Remoting.Channels.CORBA.IIOPMessage.cs
2 //
3 // Author:
4 //      DietmarMaurer (dietmar@ximian.com)
5 //
6 // (C) 2002 Ximian, Inc.  http://www.ximian.com
7
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Runtime.Serialization.Formatters;
30 using System.Runtime.Serialization;
31 using System.Reflection;
32 using System.Collections;
33 using System.IO;
34 using System.Runtime.Remoting.Messaging;
35
36 namespace System.Runtime.Remoting.Channels.CORBA {
37
38         public sealed class IIOPMessage 
39         {
40                 public enum MessageType : byte {
41                         Request = 0,
42                         Response = 1,
43                         Exception = 2,
44                         Unknown = 3
45                 }
46                 
47                 public IIOPMessage ()
48                 {
49                 }
50                 
51                 public static void SendExceptionMessage (Stream network_stream, string message)
52                 {
53                         // we use the uri field to encode the message text
54                         SendMessageStream (network_stream, null, MessageType.Exception, message);
55                 }
56                 
57                 public static void SendMessageStream (Stream network_stream, MemoryStream data, 
58                                                       MessageType msg_type, string uri)
59                 {
60                         int data_len = 0;
61                         
62                         if (data != null)
63                                 data_len = (int)data.Length;
64
65                         int uri_len = 0;
66
67                         if (uri != null)
68                                 uri_len = uri.Length;
69
70                         int header_len = 12 + uri_len * 2;
71                         int msg_len = data_len + header_len;
72                         
73                         byte [] buffer = new byte [msg_len];
74
75                         // magic header signature
76                         buffer [0] = 255;
77                         buffer [1] = 0;
78                         buffer [2] = 255;
79                         buffer [3] = (byte) msg_type;
80
81                         // data length
82                         buffer [4] = (byte) data_len;
83                         buffer [5] = (byte) (data_len >> 8);
84                         buffer [6] = (byte) (data_len >> 16);
85                         buffer [7] = (byte) (data_len >> 24);
86
87                         // uri length
88                         buffer [8] = (byte) uri_len;
89                         buffer [9] = (byte) (uri_len >> 8);
90                         buffer [10] = (byte) (uri_len >> 16);
91                         buffer [11] = (byte) (uri_len >> 24);
92
93                         // uri
94                         for (int i = 0; i < uri_len; i++) {
95                                 buffer [12 + i*2] = (byte) uri [i];
96                                 buffer [13 + i*2] = (byte) (uri [i] >> 8);
97                         }
98
99                         if (data_len > 0) {
100                                 byte [] data_buffer = data.GetBuffer ();
101                                 for (int i = 0; i < data_len; i++)
102                                         buffer [i + header_len] = data_buffer [i];
103                         }
104                         
105                         network_stream.Write (buffer, 0, msg_len);
106                 }
107                 
108                 public static MemoryStream ReceiveMessageStream (Stream network_stream,
109                                                                  out MessageType msg_type,
110                                                                  out string uri)
111                 {
112                         int data_len = 0;
113                         int uri_len = 0;
114                         msg_type = MessageType.Unknown;
115                         uri = null;
116                         
117                         // search for message header (255, 0, 255, msg_type, msg_len)
118                         while (true) {
119                                 while (true) {
120                                         int x = network_stream.ReadByte ();
121                                         if (x != 255)
122                                                 continue;
123                                         x = network_stream.ReadByte ();
124                                         if (x != 0)
125                                                 continue;
126                                         x = network_stream.ReadByte ();
127                                         if (x != 255)
128                                                 continue;
129                                         break;
130                                 }
131
132                                 msg_type = (MessageType)network_stream.ReadByte ();
133                                 
134                                 byte [] buffer = new byte [8];
135                                 
136                                 int bytes_read = network_stream.Read (buffer, 0, 8);
137                                 if (bytes_read != 8)
138                                         continue;
139                                 
140                                 data_len = (buffer [0] | (buffer [1] << 8) |
141                                             (buffer [2] << 16) | (buffer [3] << 24));
142                                 
143                                 uri_len = (buffer [4] | (buffer [5] << 8) |
144                                            (buffer [6] << 16) | (buffer [7] << 24));
145                                 
146                                 if (uri_len > 0) {
147                                         byte [] uri_buffer = new byte [uri_len * 2];
148                                         bytes_read = network_stream.Read (uri_buffer, 0, uri_len * 2);
149                                         if (bytes_read != (uri_len * 2))
150                                                 continue;
151                                         char [] uri_array = new char [uri_len];
152                                         for (int i = 0; i < uri_len; i++) {
153                                                 uri_array [i] = (char) (uri_buffer [i * 2] | (uri_buffer [(i * 2) + 1] << 8));
154                                         }
155                                         uri = new string (uri_array);
156                                 }
157                                 break;
158                         }
159
160                         if (msg_type == MessageType.Exception)
161                                 throw new RemotingException ("\n" + uri + "\n" + "Rethrown at:\n");
162                         
163                         byte [] stream_buffer = new byte [data_len];
164                         if ((network_stream.Read (stream_buffer, 0, data_len)) != data_len)
165                                 throw new Exception ("packet size error");
166                         
167                         return new MemoryStream (stream_buffer, false);
168                 }               
169         }
170 }