1 /*
   2  * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.corba.se.impl.protocol.giopmsgheaders;
  27 
  28 import java.nio.ByteBuffer;
  29 import org.omg.CORBA.INTERNAL;
  30 import org.omg.CORBA.CompletionStatus;
  31 
  32 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  33 
  34 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  35 import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  36 
  37 /*
  38  * This implements the GIOP 1.1 & 1.2 Message header.
  39  *
  40  * @author Ram Jeyaraman 05/14/2000
  41  */
  42 
  43 public class Message_1_1
  44         extends com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase {
  45 
  46     // Constants
  47     final static int UPPER_THREE_BYTES_OF_INT_MASK = 0xFF;
  48 
  49     private static ORBUtilSystemException wrapper =
  50         ORBUtilSystemException.get( CORBALogDomains.RPC_PROTOCOL ) ;
  51 
  52     // Instance variables
  53     int magic = (int) 0;
  54     GIOPVersion GIOP_version = null;
  55     byte flags = (byte) 0;
  56     byte message_type = (byte) 0;
  57     int message_size = (int) 0;
  58 
  59     // Constructor
  60 
  61     Message_1_1() {
  62     }
  63 
  64     Message_1_1(int _magic, GIOPVersion _GIOP_version, byte _flags,
  65             byte _message_type, int _message_size) {
  66         magic = _magic;
  67         GIOP_version = _GIOP_version;
  68         flags = _flags;
  69         message_type = _message_type;
  70         message_size = _message_size;
  71     }
  72 
  73     // Accessor methods
  74 
  75     public GIOPVersion getGIOPVersion() {
  76         return this.GIOP_version;
  77     }
  78 
  79     public int getType() {
  80         return this.message_type;
  81     }
  82 
  83     public int getSize() {
  84             return this.message_size;
  85     }
  86 
  87     public boolean isLittleEndian() {
  88         return ((this.flags & LITTLE_ENDIAN_BIT) == LITTLE_ENDIAN_BIT);
  89     }
  90 
  91     public boolean moreFragmentsToFollow() {
  92         return ( (this.flags & MORE_FRAGMENTS_BIT) == MORE_FRAGMENTS_BIT );
  93     }
  94 
  95     // Mutator methods
  96 
  97     // NOTE: This is a SUN PROPRIETARY EXTENSION
  98     // Add the poolToUse to the upper 6 bits of byte 6 of the GIOP header.
  99     // this.flags represents byte 6 here.
 100     public void setThreadPoolToUse(int poolToUse) {
 101         // IMPORTANT: Bitwise operations will promote
 102         //            byte types to int before performing
 103         //            bitwise operations. And, Java
 104         //            types are signed.
 105         int tmpFlags = poolToUse << 2;
 106         tmpFlags &= UPPER_THREE_BYTES_OF_INT_MASK;
 107         tmpFlags |= flags;
 108         flags = (byte)tmpFlags;
 109     }
 110 
 111     public void setSize(ByteBuffer byteBuffer, int size) {
 112 
 113         this.message_size = size;
 114 
 115         //
 116         // Patch the size field in the header.
 117         //
 118 
 119         int patch = size - GIOPMessageHeaderLength;
 120         if (!isLittleEndian()) {
 121             byteBuffer.put(8,  (byte)((patch >>> 24) & 0xFF));
 122             byteBuffer.put(9,  (byte)((patch >>> 16) & 0xFF));
 123             byteBuffer.put(10, (byte)((patch >>> 8)  & 0xFF));
 124             byteBuffer.put(11, (byte)((patch >>> 0)  & 0xFF));
 125         } else {
 126             byteBuffer.put(8,  (byte)((patch >>> 0)  & 0xFF));
 127             byteBuffer.put(9,  (byte)((patch >>> 8)  & 0xFF));
 128             byteBuffer.put(10, (byte)((patch >>> 16) & 0xFF));
 129             byteBuffer.put(11, (byte)((patch >>> 24) & 0xFF));
 130         }
 131     }
 132 
 133     /**
 134      * Allows us to create a fragment message from any message type.
 135      */
 136     public FragmentMessage createFragmentMessage() {
 137 
 138         // check for message type validity
 139 
 140         switch (this.message_type) {
 141         case GIOPCancelRequest :
 142         case GIOPCloseConnection :
 143         case GIOPMessageError :
 144             throw wrapper.fragmentationDisallowed(
 145                 CompletionStatus.COMPLETED_MAYBE);
 146         case GIOPLocateRequest :
 147         case GIOPLocateReply :
 148             if (this.GIOP_version.equals(GIOPVersion.V1_1)) {
 149                 throw wrapper.fragmentationDisallowed(
 150                     CompletionStatus.COMPLETED_MAYBE);
 151             }
 152             break;
 153         }
 154 
 155         /*
 156         // A fragmented mesg can be created only if the current mesg' fragment
 157         // bit is set. Otherwise, raise error
 158         // too stringent check
 159         if ( (this.flags & MORE_FRAGMENTS_BIT) != MORE_FRAGMENTS_BIT ) {
 160                 throw wrapper.fragmentationDisallowed( CompletionStatus.COMPLETED_MAYBE);
 161         }
 162         */
 163         if (this.GIOP_version.equals(GIOPVersion.V1_1)) {
 164             return new FragmentMessage_1_1(this);
 165         } else if (this.GIOP_version.equals(GIOPVersion.V1_2)) {
 166             return new FragmentMessage_1_2(this);
 167         }
 168 
 169         throw wrapper.giopVersionError( CompletionStatus.COMPLETED_MAYBE);
 170     }
 171 
 172     // IO methods
 173 
 174     // This should do nothing even if it is called. The Message Header is read
 175     // off a java.io.InputStream (not a CDRInputStream) by IIOPConnection
 176     // in order to choose the correct CDR Version , msg_type, and msg_size.
 177     // So, we would never need to read the Message Header off a CDRInputStream.
 178     public void read(org.omg.CORBA.portable.InputStream istream) {
 179         /*
 180         this.magic = istream.read_long();
 181         this.GIOP_version = (new GIOPVersion()).read(istream);
 182         this.flags = istream.read_octet();
 183         this.message_type = istream.read_octet();
 184         this.message_size = istream.read_ulong();
 185         */
 186     }
 187 
 188     public void write(org.omg.CORBA.portable.OutputStream ostream) {
 189         ostream.write_long(this.magic);
 190         nullCheck(this.GIOP_version);
 191         this.GIOP_version.write(ostream);
 192         ostream.write_octet(this.flags);
 193         ostream.write_octet(this.message_type);
 194         ostream.write_ulong(this.message_size);
 195     }
 196 } // class Message_1_1