/[classpath]/classpath/gnu/CORBA/GIOP/MessageHeader.java
ViewVC logotype

Diff of /classpath/gnu/CORBA/GIOP/MessageHeader.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.3 by gnu_andrew, Tue Aug 2 20:12:08 2005 UTC revision 1.1.2.4 by gnu_andrew, Wed Nov 2 00:43:25 2005 UTC
# Line 1  Line 1 
1  /* MessageHeader.java -- GIOP 1.0 message header.  /* MessageHeader.java -- GIOP message header.
2     Copyright (C) 2005 Free Software Foundation, Inc.     Copyright (C) 2005 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
# Line 38  exception statement from your version. * Line 38  exception statement from your version. *
38    
39  package gnu.CORBA.GIOP;  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;  import gnu.CORBA.CDR.BigEndianOutputStream;
45  import gnu.CORBA.CDR.LittleEndianInputStream;  import gnu.CORBA.CDR.LittleEndianInputStream;
46  import gnu.CORBA.CDR.LittleEndianOutputStream;  import gnu.CORBA.CDR.LittleEndianOutputStream;
47  import gnu.CORBA.CDR.abstractDataOutputStream;  import gnu.CORBA.CDR.AbstractDataInput;
48  import gnu.CORBA.Version;  import gnu.CORBA.CDR.AbstractDataOutput;
49    
50  import org.omg.CORBA.MARSHAL;  import org.omg.CORBA.MARSHAL;
51  import org.omg.CORBA.portable.IDLEntity;  import org.omg.CORBA.portable.IDLEntity;
52    
53  import java.io.DataInputStream;  import java.io.ByteArrayOutputStream;
54  import java.io.IOException;  import java.io.IOException;
55    import java.io.InputStream;
56  import java.io.OutputStream;  import java.io.OutputStream;
57    import java.net.Socket;
58  import java.util.Arrays;  import java.util.Arrays;
 import gnu.CORBA.CDR.BigEndianInputStream;  
 import gnu.CORBA.CDR.abstractDataInputStream;  
 import java.io.InputStream;  
59    
60  /**  /**
61   * The GIOP message header.   * The GIOP message header.
62   *   *
63   * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)   * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
64   */   */
65  public class MessageHeader  public class MessageHeader
66    implements IDLEntity    implements IDLEntity
67  {  {
68    /**    /**
69       * Use serialVersionUID for interoperability.
70       */
71      private static final long serialVersionUID = 1;
72    
73      /**
74     * Request message.     * Request message.
75     */     */
76    public static final byte REQUEST = 0;    public static final byte REQUEST = 0;
# Line 80  public class MessageHeader Line 86  public class MessageHeader
86    public static final byte CANCEL_REQUEST = 2;    public static final byte CANCEL_REQUEST = 2;
87    
88    /**    /**
89     * Locate request message, used to check the server ability to     * Locate request message, used to check the server ability to process
90     * process requests for the object reference.     * requests for the object reference. This message is also used to get the
    * This message is also used to get the  
91     * address where the object reference should be sent.     * address where the object reference should be sent.
92     */     */
93    public static final byte LOCATE_REQUEST = 3;    public static final byte LOCATE_REQUEST = 3;
94    
95    /**    /**
96     * Locate reply message, sent in response to the     * Locate reply message, sent in response to the {@link #LocateRequest}
97     * {@link #LocateRequest} message.     * message.
98     */     */
99    public static final byte LOCATE_REPLY = 4;    public static final byte LOCATE_REPLY = 4;
100    
# Line 104  public class MessageHeader Line 109  public class MessageHeader
109    public static final byte MESSAGE_ERROR = 6;    public static final byte MESSAGE_ERROR = 6;
110    
111    /**    /**
112     * The fragment messge, following the previous message that     * The fragment messge, following the previous message that has more fragments
113     * has more fragments flag set. Added in GIOP 1.1     * flag set. Added in GIOP 1.1
114     */     */
115    public static final byte FRAGMENT = 7;    public static final byte FRAGMENT = 7;
116    
# Line 117  public class MessageHeader Line 122  public class MessageHeader
122    /**    /**
123     * The message type names.     * The message type names.
124     */     */
125    protected static String[] types =    protected static String[] types = new String[] { "Request", "Reply",
126      new String[]      "Cancel", "Locate request", "Locate reply", "Close connection", "Error",
127      {      "Fragment" };
       "Request", "Reply", "Cancel", "Locate request", "Locate reply",  
       "Close connection", "Error", "Fragment"  
     };  
128    
129    /**    /**
130     * The GIOP version. Initialised to 1.0 .     * The GIOP version. Initialised to 1.0 .
# Line 154  public class MessageHeader Line 156  public class MessageHeader
156    
157    /**    /**
158     * Create an empty message header, corresponding the given version.     * Create an empty message header, corresponding the given version.
159     *     *
160     * @param major the major message header version.     * @param major the major message header version.
161     * @param minor the minot message header version.     * @param minor the minot message header version.
162     */     */
# Line 164  public class MessageHeader Line 166  public class MessageHeader
166    }    }
167    
168    /**    /**
169     * Checks if the message is encoded in the Big Endian, most significant     * Checks if the message is encoded in the Big Endian, most significant byte
170     * byte first.     * first.
171     */     */
172    public boolean isBigEndian()    public boolean isBigEndian()
173    {    {
# Line 173  public class MessageHeader Line 175  public class MessageHeader
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.     * Set the encoding to use.
187     *     *
188     * @param use_big_endian if true (default), the Big Endian     * @param use_big_endian if true (default), the Big Endian encoding is used.
189     * encoding is used. If false, the Little Endian encoding is used.     * If false, the Little Endian encoding is used.
190     */     */
191    public void setBigEndian(boolean use_big_endian)    public void setBigEndian(boolean use_big_endian)
192    {    {
# Line 196  public class MessageHeader Line 206  public class MessageHeader
206    
207    /**    /**
208     * Get the message type as string.     * Get the message type as string.
209     *     *
210     * @param type the message type as int (the field {@link message_type}).     * @param type the message type as int (the field {@link message_type}).
211     *     *
212     * @return the message type as string.     * @return the message type as string.
213     */     */
214    public String getTypeString(int type)    public String getTypeString(int type)
215    {    {
216      try      try
217        {        {
218          return types [ type ];          return types[type];
219        }        }
220      catch (ArrayIndexOutOfBoundsException ex)      catch (ArrayIndexOutOfBoundsException ex)
221        {        {
# Line 215  public class MessageHeader Line 225  public class MessageHeader
225    
226    /**    /**
227     * Creates reply header, matching the message header version number.     * Creates reply header, matching the message header version number.
228     *     *
229     * @return one of {@link gnu.CORBA.GIOP.v1_0.ReplyHeader},     * @return one of {@link gnu.CORBA.GIOP.v1_0.ReplyHeader},
230     * {@link gnu.CORBA.GIOP.v1_2.ReplyHeader}, etc - depending on     * {@link gnu.CORBA.GIOP.v1_2.ReplyHeader}, etc - depending on the version
231     * the version number in this header.     * number in this header.
232     */     */
233    public ReplyHeader create_reply_header()    public ReplyHeader create_reply_header()
234    {    {
# Line 230  public class MessageHeader Line 240  public class MessageHeader
240    
241    /**    /**
242     * Creates request header, matching the message header version number.     * Creates request header, matching the message header version number.
243     *     *
244     * @return one of {@link gnu.CORBA.GIOP.v1_0.RequestHeader},     * @return one of {@link gnu.CORBA.GIOP.v1_0.RequestHeader},
245     * {@link gnu.CORBA.GIOP.v1_2.RequestHeader}, etc - depending on     * {@link gnu.CORBA.GIOP.v1_2.RequestHeader}, etc - depending on the version
246     * the version number in this header.     * number in this header.
247     */     */
248    public RequestHeader create_request_header()    public RequestHeader create_request_header()
249    {    {
# Line 261  public class MessageHeader Line 271  public class MessageHeader
271    
272    /**    /**
273     * Read the header from the stream.     * Read the header from the stream.
274     *     *
275     * @param istream a stream to read from.     * @param istream a stream to read from.
276     *     *
277     * @throws MARSHAL if this is not a GIOP 1.0 header.     * @throws MARSHAL if this is not a GIOP 1.0 header.
278     */     */
279    public void read(java.io.InputStream istream)    public void read(java.io.InputStream istream)
280              throws MARSHAL      throws MARSHAL
281    {    {
282      try      try
283        {        {
284          byte[] xMagic = new byte[ MAGIC.length ];          byte[] xMagic = new byte[MAGIC.length];
285          istream.read(xMagic);          istream.read(xMagic);
286          if (!Arrays.equals(xMagic, MAGIC))          if (!Arrays.equals(xMagic, MAGIC))
287            throw new MARSHAL("Not a GIOP message");            {
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);          version = Version.read_version(istream);
294    
295          abstractDataInputStream din;          AbstractDataInput din;
296    
297          flags = (byte) istream.read();          flags = (byte) istream.read();
298    
# Line 295  public class MessageHeader Line 309  public class MessageHeader
309      catch (IOException ex)      catch (IOException ex)
310        {        {
311          MARSHAL t = new MARSHAL();          MARSHAL t = new MARSHAL();
312            t.minor = Minor.Header;
313          t.initCause(ex);          t.initCause(ex);
314          throw t;          throw t;
315        }        }
# Line 302  public class MessageHeader Line 317  public class MessageHeader
317    
318    /**    /**
319     * Get the short string summary of the message.     * Get the short string summary of the message.
320     *     *
321     * @return a short message summary.     * @return a short message summary.
322     */     */
323    public String toString()    public String toString()
324    {    {
325      return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little") +      return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little")
326             " endian, " + getTypeString(message_type) + ", " + message_size +        + " endian, " + getTypeString(message_type) + ", " + message_size
327             " bytes. ";        + " bytes. ";
328    }    }
329    
330    /**    /**
331     * Write the header to stream.     * Write the header to stream.
332     *     *
333     * @param out a stream to write into.     * @param out a stream to write into.
334     */     */
335    public void write(java.io.OutputStream out)    public void write(java.io.OutputStream out)
336    {    {
337      try      try
338        {        {
339          abstractDataOutputStream dout;          AbstractDataOutput dout;
340    
341          if (isBigEndian())          if (isBigEndian())
342            dout = new BigEndianOutputStream(out);            dout = new BigEndianOutputStream(out);
# Line 333  public class MessageHeader Line 348  public class MessageHeader
348    
349          // Write version number.          // Write version number.
350          version.write((OutputStream) dout);          version.write((OutputStream) dout);
   
351          dout.write(flags);          dout.write(flags);
   
352          dout.write(message_type);          dout.write(message_type);
   
353          dout.writeInt(message_size);          dout.writeInt(message_size);
354        }        }
355      catch (IOException ex)      catch (IOException ex)
356        {        {
357          MARSHAL t = new MARSHAL();          MARSHAL t = new MARSHAL();
358            t.minor = Minor.Header;
359          t.initCause(ex);          t.initCause(ex);
360          throw t;          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  }  }

Legend:
Removed from v.1.1.2.3  
changed lines
  Added in v.1.1.2.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26