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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [CORBA/] [GIOP/] [MessageHeader.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* 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 gnu.java.lang.CPStringBuilder;
51
 
52
import org.omg.CORBA.MARSHAL;
53
import org.omg.CORBA.portable.IDLEntity;
54
 
55
import java.io.ByteArrayOutputStream;
56
import java.io.EOFException;
57
import java.io.IOException;
58
import java.io.InputStream;
59
import java.io.OutputStream;
60
import java.net.Socket;
61
import java.util.Arrays;
62
 
63
/**
64
 * The GIOP message header.
65
 *
66
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
67
 */
68
public class MessageHeader
69
  implements IDLEntity
70
{
71
  /**
72
   * Use serialVersionUID for interoperability.
73
   */
74
  private static final long serialVersionUID = 1;
75
 
76
  /**
77
   * Request message.
78
   */
79
  public static final byte REQUEST = 0;
80
 
81
  /**
82
   * Reply message
83
   */
84
  public static final byte REPLY = 1;
85
 
86
  /**
87
   * Cancel request message.
88
   */
89
  public static final byte CANCEL_REQUEST = 2;
90
 
91
  /**
92
   * Locate request message, used to check the server ability to process
93
   * requests for the object reference. This message is also used to get the
94
   * address where the object reference should be sent.
95
   */
96
  public static final byte LOCATE_REQUEST = 3;
97
 
98
  /**
99
   * Locate reply message, sent in response to the {@link #LocateRequest}
100
   * message.
101
   */
102
  public static final byte LOCATE_REPLY = 4;
103
 
104
  /**
105
   * Instruction to close the connection.
106
   */
107
  public static final byte CLOSE_CONNECTION = 5;
108
 
109
  /**
110
   * Error report.
111
   */
112
  public static final byte MESSAGE_ERROR = 6;
113
 
114
  /**
115
   * The fragment messge, following the previous message that has more fragments
116
   * flag set. Added in GIOP 1.1
117
   */
118
  public static final byte FRAGMENT = 7;
119
 
120
  /**
121
   * This must always be "GIOP".
122
   */
123
  public static final byte[] MAGIC = new byte[] { 'G', 'I', 'O', 'P' };
124
 
125
  /**
126
   * The message type names.
127
   */
128
  protected static String[] types = new String[] { "Request", "Reply",
129
    "Cancel", "Locate request", "Locate reply", "Close connection", "Error",
130
    "Fragment" };
131
 
132
  /**
133
   * The GIOP version. Initialised to 1.0 .
134
   */
135
  public Version version;
136
 
137
  /**
138
   * The flags field, introduced since GIOP 1.1.
139
   */
140
  public byte flags = 0;
141
 
142
  /**
143
   * The message type.
144
   */
145
  public byte message_type = REQUEST;
146
 
147
  /**
148
   * The message size, excluding the message header.
149
   */
150
  public int message_size = 0;
151
 
152
  /**
153
   * Create an empty message header, corresponding version 1.0.
154
   */
155
  public MessageHeader()
156
  {
157
    version = new Version(1, 0);
158
  }
159
 
160
  /**
161
   * Create an empty message header, corresponding the given version.
162
   *
163
   * @param major the major message header version.
164
   * @param minor the minot message header version.
165
   */
166
  public MessageHeader(int major, int minor)
167
  {
168
    version = new Version(major, minor);
169
  }
170
 
171
  /**
172
   * Checks if the message is encoded in the Big Endian, most significant byte
173
   * first.
174
   */
175
  public boolean isBigEndian()
176
  {
177
    return (flags & 0x1) == 0;
178
  }
179
 
180
  /**
181
   * Checks if the message is partial, and more subsequent fragments follow.
182
   */
183
  public boolean moreFragmentsFollow()
184
  {
185
    return (flags & 0x2) != 0;
186
  }
187
 
188
  /**
189
   * Set the encoding to use.
190
   *
191
   * @param use_big_endian if true (default), the Big Endian encoding is used.
192
   * If false, the Little Endian encoding is used.
193
   */
194
  public void setBigEndian(boolean use_big_endian)
195
  {
196
    if (use_big_endian)
197
      flags = (byte) (flags & ~1);
198
    else
199
      flags = (byte) (flags | 1);
200
  }
201
 
202
  /**
203
   * Get the size of the message header itself. So far, it is always 12 bytes.
204
   */
205
  public int getHeaderSize()
206
  {
207
    return 12;
208
  }
209
 
210
  /**
211
   * Get the message type as string.
212
   *
213
   * @param type the message type as int (the field {@link message_type}).
214
   *
215
   * @return the message type as string.
216
   */
217
  public String getTypeString(int type)
218
  {
219
    try
220
      {
221
        return types[type];
222
      }
223
    catch (ArrayIndexOutOfBoundsException ex)
224
      {
225
        return "unknown type (" + type + ")";
226
      }
227
  }
228
 
229
  /**
230
   * Creates reply header, matching the message header version number.
231
   *
232
   * @return one of {@link gnu.CORBA.GIOP.v1_0.ReplyHeader},
233
   * {@link gnu.CORBA.GIOP.v1_2.ReplyHeader}, etc - depending on the version
234
   * number in this header.
235
   */
236
  public ReplyHeader create_reply_header()
237
  {
238
    if (version.since_inclusive(1, 2))
239
      return new gnu.CORBA.GIOP.v1_2.ReplyHeader();
240
    else
241
      return new gnu.CORBA.GIOP.v1_0.ReplyHeader();
242
  }
243
 
244
  /**
245
   * Creates request header, matching the message header version number.
246
   *
247
   * @return one of {@link gnu.CORBA.GIOP.v1_0.RequestHeader},
248
   * {@link gnu.CORBA.GIOP.v1_2.RequestHeader}, etc - depending on the version
249
   * number in this header.
250
   */
251
  public RequestHeader create_request_header()
252
  {
253
    if (version.since_inclusive(1, 2))
254
      return new gnu.CORBA.GIOP.v1_2.RequestHeader();
255
    else
256
      return new gnu.CORBA.GIOP.v1_0.RequestHeader();
257
  }
258
 
259
  /**
260
   * Create the cancel header, matching the message header version number.
261
   */
262
  public CancelHeader create_cancel_header()
263
  {
264
    return new gnu.CORBA.GIOP.v1_0.CancelHeader();
265
  }
266
 
267
  /**
268
   * Create the error message.
269
   */
270
  public ErrorMessage create_error_message()
271
  {
272
    return new ErrorMessage(version);
273
  }
274
 
275
  /**
276
   * Read the header from the stream.
277
   *
278
   * @param istream a stream to read from.
279
   * @throws MARSHAL if this is not a GIOP 1.0 header.
280
   */
281
  public void read(java.io.InputStream istream)
282
    throws MARSHAL, EOFException
283
  {
284
    try
285
      {
286
        byte[] xMagic = new byte[MAGIC.length];
287
        int r = istream.read(xMagic);
288
        int minor;
289
        if (! Arrays.equals(xMagic, MAGIC))
290
          {
291
            CPStringBuilder b = new CPStringBuilder();
292
            if (r == - 1)
293
              {
294
                b.append("Immediate EOF");
295
                minor = Minor.EOF;
296
              }
297
            else
298
              {
299
                minor = Minor.Giop;
300
                b.append(r + " bytes: ");
301
                for (int i = 0; i < xMagic.length; i++)
302
                  {
303
                    b.append(Integer.toHexString(xMagic[i] & 0xFF));
304
                    b.append(' ');
305
                  }
306
              }
307
            MARSHAL m = new MARSHAL("Not a GIOP message: " + b);
308
            m.minor = minor;
309
            throw m;
310
          }
311
 
312
        version = Version.read_version(istream);
313
 
314
        AbstractDataInput din;
315
 
316
        flags = (byte) istream.read();
317
 
318
        // This checks the bit in the byte we have just received.
319
        if (isBigEndian())
320
          din = new BigEndianInputStream(istream);
321
        else
322
          din = new LittleEndianInputStream(istream);
323
 
324
        message_type = (byte) din.read();
325
 
326
        message_size = din.readInt();
327
      }
328
    catch (IOException ex)
329
      {
330
        MARSHAL t = new MARSHAL();
331
        t.minor = Minor.Header;
332
        t.initCause(ex);
333
        throw t;
334
      }
335
  }
336
 
337
  /**
338
   * Get the short string summary of the message.
339
   *
340
   * @return a short message summary.
341
   */
342
  public String toString()
343
  {
344
    return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little")
345
      + " endian, " + getTypeString(message_type) + ", " + message_size
346
      + " bytes. ";
347
  }
348
 
349
  /**
350
   * Write the header to stream.
351
   *
352
   * @param out a stream to write into.
353
   */
354
  public void write(java.io.OutputStream out)
355
  {
356
    try
357
      {
358
        AbstractDataOutput dout;
359
 
360
        if (isBigEndian())
361
          dout = new BigEndianOutputStream(out);
362
        else
363
          dout = new LittleEndianOutputStream(out);
364
 
365
        // Write magic sequence.
366
        dout.write(MAGIC);
367
 
368
        // Write version number.
369
        version.write((OutputStream) dout);
370
        dout.write(flags);
371
        dout.write(message_type);
372
        dout.writeInt(message_size);
373
      }
374
    catch (IOException ex)
375
      {
376
        MARSHAL t = new MARSHAL(ex.getMessage());
377
        t.minor = Minor.Header;
378
        t.initCause(ex);
379
        throw t;
380
      }
381
  }
382
 
383
  /**
384
   * Read data, followed by the message header. Handle fragmented messages.
385
   *
386
   * @param source the data source to read from.
387
   * @param service the socket on that the time outs are set. Can be null (no
388
   * timeouts are set).
389
   * @param to_read the timeout while reading the message.
390
   * @param to_pause the timeout for pauses between the message parts.
391
   */
392
  public byte[] readMessage(InputStream source, Socket service, int to_read,
393
    int to_pause)
394
  {
395
    try
396
      {
397
        byte[] r = new byte[message_size];
398
 
399
        int n = 0;
400
        if (service != null)
401
          service.setSoTimeout(to_read);
402
 
403
        while (n < r.length)
404
          {
405
            n += source.read(r, n, r.length - n);
406
          }
407
        if (service != null)
408
          service.setSoTimeout(to_pause);
409
 
410
        // Read the message remainder if the message is fragmented.
411
        if (moreFragmentsFollow())
412
          {
413
            ByteArrayOutputStream buffer = new ByteArrayOutputStream(
414
              2 * r.length);
415
            buffer.write(r);
416
 
417
            if (r.length < 10)
418
              // Increase the buffer size if the default value (size of the
419
              // previous message) is really too small.
420
              r = new byte[1024];
421
 
422
            MessageHeader h2 = new MessageHeader();
423
 
424
            do
425
              {
426
                h2.read(source);
427
 
428
                int dn;
429
 
430
                n = 0;
431
                while (n < h2.message_size)
432
                  {
433
                    dn = source.read(r, 0, h2.message_size - n);
434
 
435
                    if (n == 0 && service != null)
436
                      service.setSoTimeout(to_read);
437
 
438
                    if (n == 0 && version.since_inclusive(1, 2))
439
                      {
440
                        // Skip the four byte request id.
441
                        buffer.write(r, 4, dn - 4);
442
                      }
443
                    else
444
                      buffer.write(r, 0, dn);
445
                    n = +dn;
446
                  }
447
 
448
                if (service != null)
449
                  service.setSoTimeout(to_pause);
450
              }
451
            while (h2.moreFragmentsFollow());
452
            return buffer.toByteArray();
453
          }
454
        else
455
          return r;
456
      }
457
    catch (IOException ioex)
458
      {
459
        MARSHAL m = new MARSHAL("Unable to read the message continuation.");
460
        m.minor = Minor.Header;
461
        m.initCause(ioex);
462
        throw m;
463
      }
464
  }
465
}

powered by: WebSVN 2.1.0

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