OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [CORBA/] [GIOP/] [MessageHeader.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* MessageHeader.java -- GIOP message header.
2
   Copyright (C) 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.CORBA.GIOP;
40
 
41
import gnu.CORBA.Minor;
42
import gnu.CORBA.Version;
43
import gnu.CORBA.CDR.BigEndianInputStream;
44
import gnu.CORBA.CDR.BigEndianOutputStream;
45
import gnu.CORBA.CDR.LittleEndianInputStream;
46
import gnu.CORBA.CDR.LittleEndianOutputStream;
47
import gnu.CORBA.CDR.AbstractDataInput;
48
import gnu.CORBA.CDR.AbstractDataOutput;
49
 
50
import org.omg.CORBA.MARSHAL;
51
import org.omg.CORBA.portable.IDLEntity;
52
 
53
import java.io.ByteArrayOutputStream;
54
import java.io.IOException;
55
import java.io.InputStream;
56
import java.io.OutputStream;
57
import java.net.Socket;
58
import java.util.Arrays;
59
 
60
/**
61
 * The GIOP message header.
62
 *
63
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
64
 */
65
public class MessageHeader
66
  implements IDLEntity
67
{
68
  /**
69
   * Use serialVersionUID for interoperability.
70
   */
71
  private static final long serialVersionUID = 1;
72
 
73
  /**
74
   * Request message.
75
   */
76
  public static final byte REQUEST = 0;
77
 
78
  /**
79
   * Reply message
80
   */
81
  public static final byte REPLY = 1;
82
 
83
  /**
84
   * Cancel request message.
85
   */
86
  public static final byte CANCEL_REQUEST = 2;
87
 
88
  /**
89
   * Locate request message, used to check the server ability to process
90
   * requests for the object reference. This message is also used to get the
91
   * address where the object reference should be sent.
92
   */
93
  public static final byte LOCATE_REQUEST = 3;
94
 
95
  /**
96
   * Locate reply message, sent in response to the {@link #LocateRequest}
97
   * message.
98
   */
99
  public static final byte LOCATE_REPLY = 4;
100
 
101
  /**
102
   * Instruction to close the connection.
103
   */
104
  public static final byte CLOSE_CONNECTION = 5;
105
 
106
  /**
107
   * Error report.
108
   */
109
  public static final byte MESSAGE_ERROR = 6;
110
 
111
  /**
112
   * The fragment messge, following the previous message that has more fragments
113
   * flag set. Added in GIOP 1.1
114
   */
115
  public static final byte FRAGMENT = 7;
116
 
117
  /**
118
   * This must always be "GIOP".
119
   */
120
  public static final byte[] MAGIC = new byte[] { 'G', 'I', 'O', 'P' };
121
 
122
  /**
123
   * The message type names.
124
   */
125
  protected static String[] types = new String[] { "Request", "Reply",
126
    "Cancel", "Locate request", "Locate reply", "Close connection", "Error",
127
    "Fragment" };
128
 
129
  /**
130
   * The GIOP version. Initialised to 1.0 .
131
   */
132
  public Version version;
133
 
134
  /**
135
   * The flags field, introduced since GIOP 1.1.
136
   */
137
  public byte flags = 0;
138
 
139
  /**
140
   * The message type.
141
   */
142
  public byte message_type = REQUEST;
143
 
144
  /**
145
   * The message size, excluding the message header.
146
   */
147
  public int message_size = 0;
148
 
149
  /**
150
   * Create an empty message header, corresponding version 1.0.
151
   */
152
  public MessageHeader()
153
  {
154
    version = new Version(1, 0);
155
  }
156
 
157
  /**
158
   * Create an empty message header, corresponding the given version.
159
   *
160
   * @param major the major message header version.
161
   * @param minor the minot message header version.
162
   */
163
  public MessageHeader(int major, int minor)
164
  {
165
    version = new Version(major, minor);
166
  }
167
 
168
  /**
169
   * Checks if the message is encoded in the Big Endian, most significant byte
170
   * first.
171
   */
172
  public boolean isBigEndian()
173
  {
174
    return (flags & 0x1) == 0;
175
  }
176
 
177
  /**
178
   * Checks if the message is partial, and more subsequent fragments follow.
179
   */
180
  public boolean moreFragmentsFollow()
181
  {
182
    return (flags & 0x2) != 0;
183
  }
184
 
185
  /**
186
   * Set the encoding to use.
187
   *
188
   * @param use_big_endian if true (default), the Big Endian encoding is used.
189
   * If false, the Little Endian encoding is used.
190
   */
191
  public void setBigEndian(boolean use_big_endian)
192
  {
193
    if (use_big_endian)
194
      flags = (byte) (flags & ~1);
195
    else
196
      flags = (byte) (flags | 1);
197
  }
198
 
199
  /**
200
   * Get the size of the message header itself. So far, it is always 12 bytes.
201
   */
202
  public int getHeaderSize()
203
  {
204
    return 12;
205
  }
206
 
207
  /**
208
   * Get the message type as string.
209
   *
210
   * @param type the message type as int (the field {@link message_type}).
211
   *
212
   * @return the message type as string.
213
   */
214
  public String getTypeString(int type)
215
  {
216
    try
217
      {
218
        return types[type];
219
      }
220
    catch (ArrayIndexOutOfBoundsException ex)
221
      {
222
        return "unknown type (" + type + ")";
223
      }
224
  }
225
 
226
  /**
227
   * Creates reply header, matching the message header version number.
228
   *
229
   * @return one of {@link gnu.CORBA.GIOP.v1_0.ReplyHeader},
230
   * {@link gnu.CORBA.GIOP.v1_2.ReplyHeader}, etc - depending on the version
231
   * number in this header.
232
   */
233
  public ReplyHeader create_reply_header()
234
  {
235
    if (version.since_inclusive(1, 2))
236
      return new gnu.CORBA.GIOP.v1_2.ReplyHeader();
237
    else
238
      return new gnu.CORBA.GIOP.v1_0.ReplyHeader();
239
  }
240
 
241
  /**
242
   * Creates request header, matching the message header version number.
243
   *
244
   * @return one of {@link gnu.CORBA.GIOP.v1_0.RequestHeader},
245
   * {@link gnu.CORBA.GIOP.v1_2.RequestHeader}, etc - depending on the version
246
   * number in this header.
247
   */
248
  public RequestHeader create_request_header()
249
  {
250
    if (version.since_inclusive(1, 2))
251
      return new gnu.CORBA.GIOP.v1_2.RequestHeader();
252
    else
253
      return new gnu.CORBA.GIOP.v1_0.RequestHeader();
254
  }
255
 
256
  /**
257
   * Create the cancel header, matching the message header version number.
258
   */
259
  public CancelHeader create_cancel_header()
260
  {
261
    return new gnu.CORBA.GIOP.v1_0.CancelHeader();
262
  }
263
 
264
  /**
265
   * Create the error message.
266
   */
267
  public ErrorMessage create_error_message()
268
  {
269
    return new ErrorMessage(version);
270
  }
271
 
272
  /**
273
   * Read the header from the stream.
274
   *
275
   * @param istream a stream to read from.
276
   *
277
   * @throws MARSHAL if this is not a GIOP 1.0 header.
278
   */
279
  public void read(java.io.InputStream istream)
280
    throws MARSHAL
281
  {
282
    try
283
      {
284
        byte[] xMagic = new byte[MAGIC.length];
285
        istream.read(xMagic);
286
        if (!Arrays.equals(xMagic, MAGIC))
287
          {
288
            MARSHAL m = new MARSHAL("Not a GIOP message");
289
            m.minor = Minor.Giop;
290
            throw m;
291
          }
292
 
293
        version = Version.read_version(istream);
294
 
295
        AbstractDataInput din;
296
 
297
        flags = (byte) istream.read();
298
 
299
        // This checks the bit in the byte we have just received.
300
        if (isBigEndian())
301
          din = new BigEndianInputStream(istream);
302
        else
303
          din = new LittleEndianInputStream(istream);
304
 
305
        message_type = (byte) din.read();
306
 
307
        message_size = din.readInt();
308
      }
309
    catch (IOException ex)
310
      {
311
        MARSHAL t = new MARSHAL();
312
        t.minor = Minor.Header;
313
        t.initCause(ex);
314
        throw t;
315
      }
316
  }
317
 
318
  /**
319
   * Get the short string summary of the message.
320
   *
321
   * @return a short message summary.
322
   */
323
  public String toString()
324
  {
325
    return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little")
326
      + " endian, " + getTypeString(message_type) + ", " + message_size
327
      + " bytes. ";
328
  }
329
 
330
  /**
331
   * Write the header to stream.
332
   *
333
   * @param out a stream to write into.
334
   */
335
  public void write(java.io.OutputStream out)
336
  {
337
    try
338
      {
339
        AbstractDataOutput dout;
340
 
341
        if (isBigEndian())
342
          dout = new BigEndianOutputStream(out);
343
        else
344
          dout = new LittleEndianOutputStream(out);
345
 
346
        // Write magic sequence.
347
        dout.write(MAGIC);
348
 
349
        // Write version number.
350
        version.write((OutputStream) dout);
351
        dout.write(flags);
352
        dout.write(message_type);
353
        dout.writeInt(message_size);
354
      }
355
    catch (IOException ex)
356
      {
357
        MARSHAL t = new MARSHAL();
358
        t.minor = Minor.Header;
359
        t.initCause(ex);
360
        throw t;
361
      }
362
  }
363
 
364
  /**
365
   * Read data, followed by the message header. Handle fragmented messages.
366
   *
367
   * @param source the data source to read from.
368
   * @param service the socket on that the time outs are set. Can be null (no
369
   * timeouts are set).
370
   * @param to_read the timeout while reading the message.
371
   * @param to_pause the timeout for pauses between the message parts.
372
   */
373
  public byte[] readMessage(InputStream source, Socket service, int to_read,
374
    int to_pause)
375
  {
376
    try
377
      {
378
        byte[] r = new byte[message_size];
379
 
380
        int n = 0;
381
        if (service != null)
382
          service.setSoTimeout(to_read);
383
 
384
        reading: while (n < r.length)
385
          {
386
            n += source.read(r, n, r.length - n);
387
          }
388
        if (service != null)
389
          service.setSoTimeout(to_pause);
390
 
391
        // Read the message remainder if the message is fragmented.
392
        if (moreFragmentsFollow())
393
          {
394
            ByteArrayOutputStream buffer = new ByteArrayOutputStream(
395
              2 * r.length);
396
            buffer.write(r);
397
 
398
            if (r.length < 10)
399
              // Increase the buffer size if the default value (size of the
400
              // previous message) is really too small.
401
              r = new byte[1024];
402
 
403
            MessageHeader h2 = new MessageHeader();
404
 
405
            do
406
              {
407
                h2.read(source);
408
 
409
                int dn;
410
 
411
                n = 0;
412
                reading: while (n < h2.message_size)
413
                  {
414
                    dn = source.read(r, 0, h2.message_size - n);
415
 
416
                    if (n == 0 && service != null)
417
                      service.setSoTimeout(to_read);
418
 
419
                    if (n == 0 && version.since_inclusive(1, 2))
420
                      {
421
                        // Skip the four byte request id.
422
                        buffer.write(r, 4, dn - 4);
423
                      }
424
                    else
425
                      buffer.write(r, 0, dn);
426
                    n = +dn;
427
                  }
428
 
429
                if (service != null)
430
                  service.setSoTimeout(to_pause);
431
              }
432
            while (h2.moreFragmentsFollow());
433
            return buffer.toByteArray();
434
          }
435
        else
436
          return r;
437
      }
438
    catch (IOException ioex)
439
      {
440
        MARSHAL m = new MARSHAL("Unable to read the message continuation.");
441
        m.minor = Minor.Header;
442
        m.initCause(ioex);
443
        throw m;
444
      }
445
  }
446
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.