protected override void ReadDataFromStream(CdrInputStream inputStream) { // internet-iiop profile is encapsulated CdrEncapsulationInputStream encapsulation = inputStream.ReadEncapsulation(); Debug.WriteLine("parse Internet IIOP Profile"); byte giopMajor = encapsulation.ReadOctet(); byte giopMinor = encapsulation.ReadOctet(); m_giopVersion = new GiopVersion(giopMajor, giopMinor); Debug.WriteLine("giop-verion: " + m_giopVersion); m_hostName = encapsulation.ReadString(); Debug.WriteLine("hostname: " + m_hostName); m_port = encapsulation.ReadUShort(); Debug.WriteLine("port: " + m_port); uint objectKeyLength = encapsulation.ReadULong(); m_objectKey = new byte[objectKeyLength]; Debug.WriteLine("object key follows"); for (uint i = 0; i < objectKeyLength; i++) { m_objectKey[i] = encapsulation.ReadOctet(); Debug.Write(m_objectKey[i] + " "); } Debug.WriteLine(""); // GIOP 1.1, 1.2: if (!(m_giopVersion.Major == 1 && m_giopVersion.Minor == 0)) { m_taggedComponents = new TaggedComponentList(encapsulation); } Debug.WriteLine("parsing Internet-IIOP-profile completed"); }
private uint AddFinishFragment(CdrOutputStreamImpl targetStream, GiopVersion version, byte endianFlags, uint reqId, uint reqContentLength, uint offsetInMsg) { byte giopFlags = endianFlags; // no more fragments GiopHeader fragmentHeader = new GiopHeader(version.Major, version.Minor, endianFlags, GiopMsgTypes.Request); uint contentLength = 0; if (!((version.Major == 1) && (version.Minor <= 1))) { // GIOP 1.2 contentLength = 4 + reqContentLength; } else { contentLength = reqContentLength; } fragmentHeader.WriteToStream(targetStream, contentLength); if (!((version.Major == 1) && (version.Minor <= 1))) { // GIOP 1.2 targetStream.WriteULong(reqId); } // more is not needed to write a correct GIOP-message for this test from here for (uint i = offsetInMsg; i < (offsetInMsg + reqContentLength); i++) { targetStream.WriteOctet((byte)(i % 255)); } return(offsetInMsg + reqContentLength); }
private void InternalTestTwoFramgents(GiopVersion version) { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 11; uint startMsgContentBlocks = 2; // make sure, that start fragment length is a multiple of 8; giop 1.2 uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message CdrOutputStreamImpl cdrOut = AddStartMsg(msgStream, version, endianFlags, reqId, startMsgContentBlocks, out currentOffsetInMsg); uint endOffset = AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); // start fragment FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); assembler.StartFragment(msgStream); // finish fragment GiopHeader combinedHeader; Stream resultStream = assembler.FinishFragmentedMsg(msgStream, out combinedHeader); CheckAssembledMessage(resultStream, version, endianFlags, reqId, endOffset); }
public NamingContext GetNameService(string host, int port, GiopVersion version) { string nsKey = String.Format("NameService:{0}:{1}:{2}.{3}", host, port, version.Major, version.Minor); lock (m_initalServices.SyncRoot) { NamingContext result = null; if (!m_initalServices.ContainsKey(nsKey)) { string corbaLoc = String.Format("corbaloc:iiop:{0}.{1}@{2}:{3}/{4}", version.Major, version.Minor, host, port, InitialCOSNamingContextImpl.INITIAL_NAMING_OBJ_NAME); result = (NamingContext)RemotingServices.Connect(typeof(NamingContext), corbaLoc); m_initalServices.Add(nsKey, result); } else { result = (NamingContext)m_initalServices[nsKey]; } return(result); } }
public override Uri ParseUrl(string objectUri, out GiopVersion version) { version = Version; return(new Uri(iiopsslPrefix + version.Major + "." + version.Minor + Uri.SchemeDelimiter + Host + ":" + Port)); }
internal CodecImplEncap(GiopVersion version, SerializerFactory serFactory) { m_version = version; m_serFactory = serFactory; m_serializerForAnyType = m_serFactory.Create(ReflectionHelper.ObjectType, AttributeExtCollection.EmptyCollection); }
public Uri ParseUrl(out string objectUri, out GiopVersion version) { if (m_objAddrs.Length == 0) { throw new INTERNAL(8540, CompletionStatus.Completed_MayBe); } objectUri = ObjectUri; return(m_objAddrs[0].ParseUrl(objectUri, out version)); }
/// <summary> /// reads a locate-request message from the message input stream msgInput /// and formulates an answer. /// </summary> /// <returns></returns> internal Stream SerialiseOutgoingLocateReplyMessage(LocateReplyMessage replyMsg, LocateRequestMessage requestMsg, GiopVersion version, Stream targetStream, GiopConnectionDesc conDesc) { GiopHeader header = new GiopHeader(version.Major, version.Minor, m_headerFlags, GiopMsgTypes.LocateReply); CdrMessageOutputStream msgOutput = new CdrMessageOutputStream(targetStream, header); // serialize the message m_ser.SerialiseLocateReply(msgOutput.GetMessageContentWritingStream(), version, requestMsg.RequestId, replyMsg); msgOutput.CloseStream(); // write to the stream return(targetStream); }
/// <summary>parses an iiop-addr string</summary> private void ParseIiopAddr(string iiopAddr, int protocolPrefixLength) { // version part int hostIndex; int atIndex = iiopAddr.IndexOf('@', protocolPrefixLength); if (atIndex >= 0) { // version spec string versionPart = iiopAddr.Substring(protocolPrefixLength, atIndex - protocolPrefixLength); string[] versionParts = versionPart.Split(new char[] { '.' }, 2); try { byte major = System.Byte.Parse(versionParts[0]); if (versionParts.Length != 2) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } byte minor = System.Byte.Parse(versionParts[1]); m_version = new GiopVersion(major, minor); } catch (Exception) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } hostIndex = atIndex + 1; } else { m_version = new GiopVersion(1, 0); // default hostIndex = protocolPrefixLength; } // host, port part int commaIndex = iiopAddr.IndexOf(':', hostIndex); if (commaIndex >= 0) { m_host = iiopAddr.Substring(hostIndex, commaIndex - hostIndex); try { m_port = System.Int32.Parse(iiopAddr.Substring(commaIndex + 1)); } catch (Exception) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } } else { m_host = iiopAddr.Substring(hostIndex); } if (StringConversions.IsBlank(m_host)) { m_host = "localhost"; } }
public void TestLocateReplySerialisation() { uint requestId = 5; byte[] objectKey = new byte[] { 116, 101, 115, 116, 111, 98, 106, 101, 99, 116 }; // testobject string targetUri = "testobject"; GiopVersion version = new GiopVersion(1, 2); LocateRequestMessage locReq = new LocateRequestMessage(requestId, objectKey, targetUri); // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply LocateStatus replyStatus = LocateStatus.OBJECT_HERE; LocateReplyMessage locReply = new LocateReplyMessage(replyStatus); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingLocateReplyMessage(locReply, locReq, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, version); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: locate reply data = (byte)cdrIn.ReadOctet(); Assert.AreEqual((byte)GiopMsgTypes.LocateReply, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(requestId, cdrIn.ReadULong()); // the location status Assert.AreEqual((uint)replyStatus, cdrIn.ReadULong()); }
public Codec create_codec(Encoding enc) { GiopVersion version = new GiopVersion(enc.major_version, enc.minor_version); if (enc.format == omg.org.IOP.ENCODING_CDR_ENCAPS.ConstVal) { Codec impl = new CodecImplEncap(version, m_serFactory); return(impl); } else { throw new omg.org.IOP.CodecFactory_package.UnknownEncoding(); } }
/// <summary> /// This method parses an url for the IIOP channel. /// It extracts the channel URI and the objectURI /// </summary> /// <param name="url">the url to parse</param> /// <param name="objectURI">the objectURI</param> /// <returns>the channel-Uri</returns> internal Uri ParseUrl(string url, out string objectUri, out GiopVersion version) { Uri uri = null; if (url.StartsWith("iiop")) { IiopLoc iiopLoc = new IiopLoc(url, m_codec, m_defaultAdditionalTaggedComponents); uri = iiopLoc.ParseUrl(out objectUri, out version); } else if (url.StartsWith("IOR")) { Ior ior = new Ior(url); IInternetIiopProfile profile = ior.FindInternetIiopProfile(); if (profile != null) { uri = new Uri("iiop" + profile.Version.Major + "." + profile.Version.Minor + Uri.SchemeDelimiter + profile.HostName + ":" + profile.Port); objectUri = IorUtil.GetObjectUriForObjectKey(profile.ObjectKey); version = profile.Version; } else { uri = null; objectUri = null; version = new GiopVersion(1, 0); } } else if (url.StartsWith("corbaloc")) { Corbaloc loc = new Corbaloc(url, m_codec, m_defaultAdditionalTaggedComponents); uri = loc.ParseUrl(out objectUri, out version); } else { // not possible uri = null; objectUri = null; version = new GiopVersion(1, 0); } return(uri); }
public void TestLocateRequestDeserialisation() { MemoryStream sourceStream = new MemoryStream(); // prepare msg uint requestId = 5; GiopVersion version = new GiopVersion(1, 2); CdrOutputStreamImpl cdrOut = new CdrOutputStreamImpl(sourceStream, 0, version); cdrOut.WriteOpaque(m_giopMagic); // version cdrOut.WriteOctet(version.Major); cdrOut.WriteOctet(version.Minor); // flags cdrOut.WriteOctet(0); // msg-type: request cdrOut.WriteOctet((byte)GiopMsgTypes.LocateRequest); // msg-length cdrOut.WriteULong(22); // request-id cdrOut.WriteULong(requestId); // target: key type cdrOut.WriteULong(0); cdrOut.WriteULong(10); // key length byte[] objectKey = new byte[] { 116, 101, 115, 116, 111, 98, 106, 101, 99, 116 }; // testobject cdrOut.WriteOpaque(objectKey); // create a connection context: this is needed for request deserialisation GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // go to stream begin sourceStream.Seek(0, SeekOrigin.Begin); // deserialise request message LocateRequestMessage result = m_handler.ParseIncomingLocateRequestMessage(sourceStream); // now check if values are correct Assert.IsTrue(result != null, "deserialised message is null"); Assert.AreEqual(requestId, result.RequestId); Assert.NotNull(result.ObjectKey); Assert.NotNull(result.TargetUri); Assert.AreEqual("testobject", result.TargetUri); }
public void TestCantAddFragmentAfterMessageFinished() { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 16; uint startMsgContentBlocks = 2; // make sure, that start fragment length is a multiple of 8; giop 1.2 uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message GiopVersion version = new GiopVersion(1, 2); CdrOutputStreamImpl cdrOut = AddStartMsg(msgStream, version, endianFlags, reqId, startMsgContentBlocks, out currentOffsetInMsg); uint endOffset = AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); // start fragment FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); assembler.StartFragment(msgStream); // finish fragment GiopHeader combinedHeader; assembler.FinishFragmentedMsg(msgStream, out combinedHeader); // now check, that no additional finish fragment is supported msgStream = new MemoryStream(); currentOffsetInMsg = 0; // the content offset for the next message cdrOut = new CdrOutputStreamImpl(msgStream, endianFlags, version); AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); try { // finish fragment assembler.FinishFragmentedMsg(msgStream, out combinedHeader); Assert.Fail("accepted finish fragment, although no start fragment seen"); } catch (IOException) { // ok, no start fragment found } }
private object[] MarshalAndUnmarshalRequestArgsOnce(MethodInfo testMethod, object[] actual) { ArgumentsSerializerFactory serFactory = m_argSerFactory; ArgumentsSerializer ser = serFactory.Create(testMethod.DeclaringType); MemoryStream data = new MemoryStream(); GiopVersion version = new GiopVersion(1, 2); byte endian = 0; CdrOutputStream targetStream = new CdrOutputStreamImpl(data, endian, version); ser.SerializeRequestArgs(testMethod.Name, actual, targetStream, null); data.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl sourceStream = new CdrInputStreamImpl(data); sourceStream.ConfigStream(endian, version); IDictionary contextElements; object[] deser = ser.DeserializeRequestArgs(testMethod.Name, sourceStream, out contextElements); return(deser); }
/// <param name="fragmentContentBlocks">the nr of 4 byte blocks in the content; /// must be even for GIOP 1.2</param> private CdrOutputStreamImpl AddStartMsg(Stream targetStream, GiopVersion version, byte endianFlags, uint reqId, uint fragmentContentBlocks, out uint offsetInMsg) { byte giopFlags = (byte)(endianFlags | ((byte)2)); // more fragments CdrOutputStreamImpl cdrOut = new CdrOutputStreamImpl(targetStream, endianFlags, version); GiopHeader startHeader = new GiopHeader(version.Major, version.Minor, giopFlags, GiopMsgTypes.Request); uint contentLength = 0; if (!((version.Major == 1) && (version.Minor <= 1))) { // GIOP 1.2 contentLength = (uint)(4 + (fragmentContentBlocks * 4)); } else { contentLength = (uint)(8 + (fragmentContentBlocks * 4)); } startHeader.WriteToStream(cdrOut, contentLength); if ((version.Major == 1) && (version.Minor == 1)) { // GIOP 1.1: add service context list here cdrOut.WriteULong(0); // no contexts } cdrOut.WriteULong(reqId); // request id // more is not needed to write a correct GIOP-message for this test from here for (uint i = 0; i < fragmentContentBlocks * 4; i++) { cdrOut.WriteOctet((byte)(i % 255)); } offsetInMsg = fragmentContentBlocks * 4; return(cdrOut); }
public void Setup() { m_version = new GiopVersion(1, 2); m_hostName = "localhost"; m_port = 8089; m_objectKey = new byte[] { 65 }; m_profile = new InternetIiopProfile(m_version, m_hostName, m_port, m_objectKey); m_serFactory = new SerializerFactory(); CodecFactory codecFactory = new Ch.Elca.Iiop.Interception.CodecFactoryImpl(m_serFactory); m_codec = codecFactory.create_codec( new omg.org.IOP.Encoding(ENCODING_CDR_ENCAPS.ConstVal, 1, 2)); IiopUrlUtil iiopUrlUtil = IiopUrlUtil.Create(m_codec, new object[] { Services.CodeSetService.CreateDefaultCodesetComponent(m_codec) }); m_serFactory.Initalize(new SerializerFactoryConfig(), iiopUrlUtil); }
private object MarshalAndUnmarshalResponeArgsOnce(MethodInfo testMethod, object returnValue, object[] outArgs, out object[] deserOutArgs) { ArgumentsSerializerFactory serFactory = m_argSerFactory; ArgumentsSerializer ser = serFactory.Create(testMethod.DeclaringType); MemoryStream data = new MemoryStream(); GiopVersion version = new GiopVersion(1, 2); byte endian = 0; CdrOutputStream targetStream = new CdrOutputStreamImpl(data, endian, version); ser.SerializeResponseArgs(testMethod.Name, returnValue, outArgs, targetStream); data.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl sourceStream = new CdrInputStreamImpl(data); sourceStream.ConfigStream(endian, version); object returnValueDeser = ser.DeserializeResponseArgs(testMethod.Name, out deserOutArgs, sourceStream); return(returnValueDeser); }
/// <summary>serialises an outgoing .NET request Message on client side</summary> internal void SerialiseOutgoingRequestMessage(IMessage msg, IIorProfile target, GiopClientConnectionDesc conDesc, Stream targetStream, uint requestId) { if (msg is IConstructionCallMessage) { // not supported in CORBA, TBD: replace through do nothing instead of exception throw new NotSupportedException("client activated objects are not supported with this channel"); } else if (msg is IMethodCallMessage) { GiopVersion version = target.Version; // write a CORBA request message into the stream targetStream GiopHeader header = new GiopHeader(version.Major, version.Minor, m_headerFlags, GiopMsgTypes.Request); CdrMessageOutputStream msgOutput = new CdrMessageOutputStream(targetStream, header); // serialize the message, this insert some data into msg, e.g. request-id msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = requestId; // set request-id msg.Properties[SimpleGiopMsg.TARGET_PROFILE_KEY] = target; GiopClientRequest request = new GiopClientRequest((IMethodCallMessage)msg, conDesc, m_interceptionOptions); m_ser.SerialiseRequest(request, msgOutput.GetMessageContentWritingStream(), target, conDesc); msgOutput.CloseStream(); if ((request.IsAsyncRequest) || (request.IsOneWayCall)) { // after successful serialisation, call for oneway and async requests receive other, // see corba 2.6, page 21-12. request.InterceptReceiveOther(); } } else { throw new NotImplementedException("handling for this type of .NET message is not implemented at the moment, type: " + msg.GetType()); } }
public void TestCantAddFragmentIfNotStarted() { Stream msgStream = new MemoryStream(); byte endianFlags = 0; uint reqId = 15; uint lastFragmentContentLength = 13; uint currentOffsetInMsg = 0; // the content offset for the next message GiopVersion version = new GiopVersion(1, 2); CdrOutputStreamImpl cdrOut = new CdrOutputStreamImpl(msgStream, endianFlags, version); AddFinishFragment(cdrOut, version, endianFlags, reqId, lastFragmentContentLength, currentOffsetInMsg); msgStream.Seek(0, SeekOrigin.Begin); try { FragmentedMessageAssembler assembler = new FragmentedMessageAssembler(); // finish fragment GiopHeader combinedHeader; assembler.FinishFragmentedMsg(msgStream, out combinedHeader); Assert.Fail("accepted finish fragment, although no start fragment seen"); } catch (IOException) { // ok, no start fragment found } }
/// <param name="expectedContentLength">length in bytes after the request-id</param> private void CheckAssembledMessage(Stream msgStream, GiopVersion version, byte endianFlags, uint reqId, uint expectedContentLength) { CdrInputStreamImpl inStream = new CdrInputStreamImpl(msgStream); GiopHeader header = new GiopHeader(inStream); Assert.AreEqual(GiopMsgTypes.Request, header.GiopType); Assert.AreEqual(version, header.Version); uint contentLength = 0; uint msgReqId = 0; if (!((version.Major == 1) && (version.Minor <= 1))) { // GIOP 1.2 // req-id contentLength = (uint)(4 + expectedContentLength); msgReqId = inStream.ReadULong(); } else { // svc-cntx + req-id contentLength = (uint)(8 + expectedContentLength); inStream.ReadULong(); // svc-cnxt msgReqId = inStream.ReadULong(); } Assert.AreEqual(contentLength, header.ContentMsgLength); Assert.AreEqual(endianFlags, header.GiopFlags); for (int i = 0; i < expectedContentLength; i++) { Assert.AreEqual(i % 255, inStream.ReadOctet()); } }
/// <summary> /// Deserialises the Giop Message body for a request /// </summary> /// <param name="cdrStream"></param> /// <param name="version"></param> /// <returns></returns> internal IMessage DeserialiseRequest(CdrInputStream cdrStream, GiopVersion version, GiopConnectionDesc conDesc, IInterceptionOption[] interceptionOptions) { MethodCall methodCallInfo = null; GiopServerRequest serverRequest = new GiopServerRequest(conDesc, interceptionOptions); serverRequest.Version = version; try { ServiceContextList cntxColl = null; if (version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1 cntxColl = DeserialiseContext(cdrStream); // Service context deser } // read the request-ID and set it as a message property uint requestId = cdrStream.ReadULong(); serverRequest.RequestId = requestId; Trace.WriteLine("received a message with reqId: " + requestId); // read response-flags: byte respFlags = cdrStream.ReadOctet(); Debug.WriteLine("response-flags: " + respFlags); cdrStream.ReadPadding(3); // read reserved bytes serverRequest.ResponseFlags = respFlags; // decode the target of this request byte[] objectKey; serverRequest.RequestUri = ReadTarget(cdrStream, version, out objectKey); serverRequest.ObjectKey = objectKey; serverRequest.RequestMethodName = cdrStream.ReadString(); Trace.WriteLine("call for .NET object: " + serverRequest.RequestUri + ", methodName: " + serverRequest.RequestMethodName); if (version.IsBeforeGiop1_2()) { // GIOP 1.0 / 1.1 uint principalLength = cdrStream.ReadULong(); cdrStream.ReadOpaque((int)principalLength); } else { cntxColl = DeserialiseContext(cdrStream); // Service context deser } PerformCodeSetEstablishmentServer(version, conDesc, cntxColl); // set codeset for stream SetCodeSet(cdrStream, conDesc); // request header deserialised serverRequest.RequestServiceContext = cntxColl; serverRequest.InterceptReceiveRequestServiceContexts(); serverRequest.SetThreadScopeCurrentFromPICurrent(); // copy request scope picurrent to thread scope pi-current serverRequest.ResolveTargetType(); // determine the .net target object type and check if target object is available ArgumentsSerializer argSer = m_argSerFactory.Create(serverRequest.ServerTypeType); MethodInfo called = argSer.GetMethodInfoFor(serverRequest.RequestMethodName); serverRequest.ResolveCalledMethod(called); // set target method and handle special cases IDictionary contextElements; DeserialiseRequestBody(cdrStream, version, serverRequest, argSer, out contextElements); methodCallInfo = new MethodCall(serverRequest.Request); if (contextElements != null) { AddContextElementsToCallContext(methodCallInfo.LogicalCallContext, contextElements); } serverRequest.UpdateWithFinalRequest(methodCallInfo); serverRequest.InterceptReceiveRequest(); // all information now available return methodCallInfo; } catch (Exception e) { // an Exception encountered during deserialisation try { cdrStream.SkipRest(); // skip rest of the message, to not corrupt the stream } catch (Exception) { // ignore exception here, already an other exception leading to problems } ReturnMessage exceptionResponse; exceptionResponse = new ReturnMessage(e, methodCallInfo); throw new RequestDeserializationException(e, serverRequest.Request, exceptionResponse); // send exception interception point will be called when serialising exception response } }
/// <summary> /// reads a locate-request message from the message input stream msgInput /// and formulates an answer. /// </summary> /// <returns></returns> internal Stream SerialiseOutgoingLocateReplyMessage(LocateReplyMessage replyMsg, LocateRequestMessage requestMsg, GiopVersion version, Stream targetStream, GiopConnectionDesc conDesc) { GiopHeader header = new GiopHeader(version.Major, version.Minor, m_headerFlags, GiopMsgTypes.LocateReply); CdrMessageOutputStream msgOutput = new CdrMessageOutputStream(targetStream, header); // serialize the message m_ser.SerialiseLocateReply(msgOutput.GetMessageContentWritingStream(), version, requestMsg.RequestId, replyMsg); msgOutput.CloseStream(); // write to the stream return targetStream; }
private Exception DeserialiseUserException(CdrInputStream cdrStream, GiopVersion version) { // exception body AlignBodyIfNeeded(cdrStream, version); Serializer ser = m_serFactory.Create(typeof(AbstractUserException), Util.AttributeExtCollection.EmptyCollection); Exception result = (Exception) ser.Deserialize(cdrStream); if (result == null) { return new Exception("user exception received from peer orb, but was not deserializable"); } else { return result; } }
private void SerialiseResponseOk(CdrOutputStream targetStream, GiopServerRequest request, GiopVersion version) { // reply body // clarification form CORBA 2.6, chapter 15.4.2: no padding, when no arguments are serialised --> // for backward compatibility, do it nevertheless AlignBodyIfNeeded(targetStream, version); // marshal the parameters ArgumentsSerializer ser = m_argSerFactory.Create(request.CalledMethod.DeclaringType); ser.SerializeResponseArgs(request.RequestMethodName, request.ReturnValue, request.OutArgs, targetStream); }
/// <summary>deserialize response with ok-status.</summary> private IMessage DeserialiseNormalReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request) { // body // clarification from CORBA 2.6, chapter 15.4.2: no padding, when no arguments are serialised TryAlignBodyIfNeeded(cdrStream, version); // read alignement, if present // read the parameters object[] outArgs; object retVal = null; ArgumentsSerializer ser = m_argSerFactory.Create(request.MethodToCall.DeclaringType); retVal = ser.DeserializeResponseArgs(request.RequestMethodName, out outArgs, cdrStream); ReturnMessage response = new ReturnMessage(retVal, outArgs, outArgs.Length, null, request.Request); return response; }
public Uri ParseUrl(out string objectUri, out GiopVersion version) { if (m_objAddrs.Length == 0) { throw new INTERNAL(8540, CompletionStatus.Completed_MayBe); } objectUri = ObjectUri; return m_objAddrs[0].ParseUrl(objectUri, out version); }
/// <summary> /// creates a profile from the standard data needed /// </summary> public IorProfile(GiopVersion version, byte[] objectKey) { m_giopVersion = version; m_objectKey = objectKey; }
public InternetIiopProfile(GiopVersion version, string hostName, ushort port, byte[] objectKey) : base(version, objectKey) { m_hostName = hostName; m_port = port; }
/// <summary>parses an iiop-addr string</summary> private void ParseIiopAddr(string iiopAddr, int protocolPrefixLength) { // version part int hostIndex; int atIndex = iiopAddr.IndexOf('@', protocolPrefixLength); if (atIndex >= 0) { // version spec string versionPart = iiopAddr.Substring(protocolPrefixLength, atIndex - protocolPrefixLength); string[] versionParts = versionPart.Split(new char[] { '.' }, 2); try { byte major = System.Byte.Parse(versionParts[0]); if (versionParts.Length != 2) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } byte minor = System.Byte.Parse(versionParts[1]); m_version = new GiopVersion(major, minor); } catch (Exception) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } hostIndex = atIndex + 1; } else { m_version = new GiopVersion(1,0); // default hostIndex = protocolPrefixLength; } // host, port part int commaIndex = iiopAddr.IndexOf(':', hostIndex); if (commaIndex >= 0) { m_host = iiopAddr.Substring(hostIndex, commaIndex - hostIndex); try { m_port = System.Int32.Parse(iiopAddr.Substring(commaIndex + 1)); } catch (Exception) { throw new BAD_PARAM(9, CompletionStatus.Completed_No); } } else { m_host = iiopAddr.Substring(hostIndex); } if (StringConversions.IsBlank(m_host)) { m_host = "localhost"; } }
public abstract Uri ParseUrl(string objectUri, out GiopVersion version);
public void TestRequestDeserialisation() { MemoryStream sourceStream = new MemoryStream(); // prepare msg uint requestId = 5; byte responseFlags = 3; string methodName = "Add"; int nrOfArgs = 2; int arg1 = 1; int arg2 = 2; GiopVersion version = new GiopVersion(1, 2); CdrOutputStreamImpl cdrOut = new CdrOutputStreamImpl(sourceStream, 0, version); cdrOut.WriteOpaque(m_giopMagic); // version cdrOut.WriteOctet(version.Major); cdrOut.WriteOctet(version.Minor); // flags cdrOut.WriteOctet(0); // msg-type: request cdrOut.WriteOctet(0); // msg-length cdrOut.WriteULong(68); // request-id cdrOut.WriteULong(requestId); // response-flags cdrOut.WriteOctet(responseFlags); cdrOut.WritePadding(3); // target: key type cdrOut.WriteULong(0); cdrOut.WriteULong(10); // key length cdrOut.WriteOpaque(new byte[] { 116, 101, 115, 116, 111, 98, 106, 101, 99, 116 }); // testobject // method name cdrOut.WriteString(methodName); // no service contexts cdrOut.WriteULong(0); cdrOut.ForceWriteAlign(Aligns.Align8); // parameters cdrOut.WriteLong(arg1); cdrOut.WriteLong(arg2); // create a connection context: this is needed for request deserialisation GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // go to stream begin sourceStream.Seek(0, SeekOrigin.Begin); IMessage result = null; TestService service = new TestService(); try { // object which should be called string uri = "testobject"; RemotingServices.Marshal(service, uri); // deserialise request message result = m_handler.ParseIncomingRequestMessage(sourceStream, conDesc); } catch (RequestDeserializationException e) { throw e; } finally { RemotingServices.Disconnect(service); } // now check if values are correct Assert.IsTrue(result != null, "deserialised message is null"); Assert.AreEqual(requestId, result.Properties[SimpleGiopMsg.REQUEST_ID_KEY]); Assert.AreEqual(version, result.Properties[SimpleGiopMsg.GIOP_VERSION_KEY]); Assert.AreEqual(responseFlags, result.Properties[SimpleGiopMsg.RESPONSE_FLAGS_KEY]); Assert.AreEqual("testobject", result.Properties[SimpleGiopMsg.URI_KEY]); Assert.AreEqual("Ch.Elca.Iiop.Tests.TestService", result.Properties[SimpleGiopMsg.TYPENAME_KEY]); Assert.AreEqual(methodName, result.Properties[SimpleGiopMsg.METHODNAME_KEY]); object[] args = (object[])result.Properties[SimpleGiopMsg.ARGS_KEY]; Assert.IsTrue(args != null, "args is null"); Assert.AreEqual(nrOfArgs, args.Length); Assert.AreEqual(arg1, args[0]); Assert.AreEqual(arg2, args[1]); }
/// <summary>deserialise the request body</summary> /// <param name="contextElements">the deserialised context elements, if any or null</param> private void DeserialiseRequestBody(CdrInputStream cdrStream, GiopVersion version, GiopServerRequest request, ArgumentsSerializer ser, out IDictionary contextElements) { // clarification from CORBA 2.6, chapter 15.4.1: no padding, when no arguments/no context elements // are serialised, i.e. body empty // ignores, if not enough bytes because no args/context; because in this case, no more bytes follow TryAlignBodyIfNeeded(cdrStream, version); // unmarshall parameters object[] args = ser.DeserializeRequestArgs(request.RequestMethodName, cdrStream, out contextElements); // for standard corba ops, adapt args: if (request.IsStandardCorbaOperation) { args = AdaptArgsForStandardOp(args, request.RequestUri); } request.RequestArgs = args; }
/// <summary>serialize the GIOP message body of a repsonse message</summary> /// <param name="requestId">the requestId of the request, this response belongs to</param> internal void SerialiseReply(GiopServerRequest request, CdrOutputStream targetStream, GiopVersion version, GiopConnectionDesc conDesc) { Trace.WriteLine("serializing response for method: " + request.GetRequestedMethodNameInternal()); try { bool isExceptionReply = request.IsExceptionReply; Exception exceptionToSend = null; try { request.SetRequestPICurrentFromThreadScopeCurrent(); // copy from thread scope picurrent after processing request by servant // reply interception point if (!request.IsExceptionReply) { request.InterceptSendReply(); } else { exceptionToSend = request.InterceptSendException(request.IdlException); } } catch (Exception ex) { // update the reply with the exception from interception layer isExceptionReply = true; if (SerialiseAsSystemException(ex)) { exceptionToSend = ex; } else { exceptionToSend = new UNKNOWN(300, CompletionStatus.Completed_MayBe); } } ServiceContextList cntxColl = request.ResponseServiceContext; SetCodeSet(targetStream, conDesc); if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1 SerialiseContext(targetStream, cntxColl); // serialize the context } targetStream.WriteULong(request.RequestId); if (!isExceptionReply) { Trace.WriteLine("sending normal response to client"); targetStream.WriteULong(0); // reply status ok if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here SerialiseContext(targetStream, cntxColl); // serialize the context } // serialize a response to a successful request SerialiseResponseOk(targetStream, request, version); Trace.WriteLine("reply body serialised"); } else { Trace.WriteLine("excpetion to send to client: " + exceptionToSend.GetType()); if (SerialiseAsSystemException(exceptionToSend)) { targetStream.WriteULong(2); // system exception } else if (SerialiseAsUserException(exceptionToSend)) { targetStream.WriteULong(1); // user exception } else { // should not occur targetStream.WriteULong(2); exceptionToSend = new INTERNAL(204, CompletionStatus.Completed_Yes); } if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here SerialiseContext(targetStream, cntxColl); // serialize the context } AlignBodyIfNeeded(targetStream, version); if (SerialiseAsSystemException(exceptionToSend)) { SerialiseSystemException(targetStream, exceptionToSend); } else { SerialiseUserException(targetStream, (AbstractUserException)exceptionToSend); } Trace.WriteLine("exception reply serialised"); } } finally { request.ClearThreadScopePICurrent(); // no longer needed, clear afterwards to prevent access to stale data during next requests } }
protected IiopLocIiopAddrBase(string scheme, string host, int port, int protocolPrefixLength) { m_host = host; m_port = port; m_version = ParseIiopScheme(scheme, protocolPrefixLength); }
internal IMessage DeserialiseReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request, GiopConnectionDesc conDesc) { ServiceContextList cntxColl = null; IMessage response = null; try { if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1, the service context is placed here cntxColl = DeserialiseContext(cdrStream); // deserialize the service contexts } cdrStream.ReadULong(); // skip request id, already handled by transport uint responseStatus = cdrStream.ReadULong(); if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here cntxColl = DeserialiseContext(cdrStream); // deserialize the service contexts } // set codeset for stream SetCodeSet(cdrStream, conDesc); switch (responseStatus) { case 0 : Trace.WriteLine("deserializing normal reply for methodCall: " + request.MethodToCall); response = DeserialiseNormalReply(cdrStream, version, request); UpdateClientRequestWithReplyData(request, response, cntxColl); request.InterceptReceiveReply(); break; case 1 : Exception userEx = DeserialiseUserException(cdrStream, version); // the error .NET message for this exception is created in the formatter UpdateClientRequestWithReplyData(request, new ReturnMessage(userEx, request.Request), cntxColl); userEx = request.InterceptReceiveException(userEx); response = new ReturnMessage(userEx, request.Request); // definitive exception only available here, because interception chain may change exception break; case 2 : Exception systemEx = DeserialiseSystemError(cdrStream, version); // the error .NET message for this exception is created in the formatter UpdateClientRequestWithReplyData(request, new ReturnMessage(systemEx, request.Request), cntxColl); systemEx = request.InterceptReceiveException(systemEx); response = new ReturnMessage(systemEx, request.Request); // definitive exception only available here, because interception chain may change exception break; case 3 : case 4 : // LOCATION_FORWARD / LOCATION_FORWARD_PERM: // --> deserialise it and return location fwd message response = DeserialiseLocationFwdReply(cdrStream, version, request); UpdateClientRequestWithReplyData(request, response, cntxColl); request.InterceptReceiveOther(); break; default : // deseralization of reply error, unknown reply status: responseStatus // the error .NET message for this exception is created in the formatter throw new MARSHAL(2401, CompletionStatus.Completed_MayBe); } } catch (Exception ex) { Trace.WriteLine("exception while deserialising reply: " + ex); try { cdrStream.SkipRest(); } catch (Exception) { // ignore this one, already problems. } if (!request.IsReplyInterceptionChainCompleted()) { // reply interception chain not yet called for this reply // deserialisation not ok: interception not called; // call interceptors with this exception. request.Reply = new ReturnMessage(ex, request.Request as IMethodCallMessage); Exception newException = request.InterceptReceiveException(ex); // exception may be changed by interception point if (ex != newException) { throw newException; // exception have been changed by interception point } } throw; } return response; }
/// <summary> /// deserialise a locate request msg. /// </summary> /// <param name="cdrStream"></param> /// <param name="version"></param> /// <param name="forRequestId">returns the request id as out param</param> /// <returns>the uri of the object requested to find</returns> public LocateRequestMessage DeserialiseLocateRequest(CdrInputStream cdrStream, GiopVersion version) { uint forRequestId = cdrStream.ReadULong(); byte[] objectKey; string uri = ReadTarget(cdrStream, version, out objectKey); return new LocateRequestMessage(forRequestId, objectKey, uri); }
/// <summary>deserialises a CORBA system exception </summary> private Exception DeserialiseSystemError(CdrInputStream cdrStream, GiopVersion version) { // exception body AlignBodyIfNeeded(cdrStream, version); Serializer ser = m_serFactory.Create(typeof(omg.org.CORBA.AbstractCORBASystemException), Util.AttributeExtCollection.EmptyCollection); Exception result = (Exception) ser.Deserialize(cdrStream); if (result == null) { return new Exception("received system error from peer orb, but error was not deserializable"); } else { return result; } }
public Uri ParseUrl(out string objectUri, out GiopVersion version) { objectUri = ObjectUri; return m_objAddr.ParseUrl(objectUri, out version); }
/// <summary> /// deserialise the location fwd /// </summary> private LocationForwardMessage DeserialiseLocationFwdReply(CdrInputStream cdrStream, GiopVersion version, GiopClientRequest request) { AlignBodyIfNeeded(cdrStream, version); // read the Location fwd IOR Serializer ser = m_serFactory.Create(request.MethodToCall.DeclaringType, Util.AttributeExtCollection.EmptyCollection); MarshalByRefObject newProxy = ser.Deserialize(cdrStream) as MarshalByRefObject; if (newProxy == null) { throw new OBJECT_NOT_EXIST(2402, CompletionStatus.Completed_No); } return new LocationForwardMessage(newProxy); }
public override Uri ParseUrl(string objectUri, out GiopVersion version) { version = Version; return new Uri("iiop-ssl" + version.Major + "." + version.Minor + Uri.SchemeDelimiter + Host + ":" + Port); }
/// <summary> /// serialises a locate reply message. /// </summary> /// <param name="forwardAddr"> /// specifies the IOR of the object to forward the call to. This parameter must be != null, /// if LocateStatus is OBJECT_FORWARD. /// </param> public void SerialiseLocateReply(CdrOutputStream targetStream, GiopVersion version, uint forRequestId, LocateReplyMessage msg) { targetStream.WriteULong(forRequestId); switch (msg.Status) { case LocateStatus.OBJECT_HERE: targetStream.WriteULong((uint)msg.Status); break; default: Debug.WriteLine("Locate reply status not supported"); throw new NotSupportedException("not supported"); } }
/// <summary>serialises an outgoing .NET reply Message on server side</summary> internal void SerialiseOutgoingReplyMessage(IMessage replyMsg, IMessage requestMsg, GiopVersion version, Stream targetStream, GiopConnectionDesc conDesc) { if (replyMsg is ReturnMessage) { // write a CORBA response message into the stream targetStream GiopHeader header = new GiopHeader(version.Major, version.Minor, m_headerFlags, GiopMsgTypes.Reply); CdrMessageOutputStream msgOutput = new CdrMessageOutputStream(targetStream, header); GiopServerRequest request = new GiopServerRequest(requestMsg, (ReturnMessage)replyMsg, conDesc, m_interceptionOptions); // serialize the message m_ser.SerialiseReply(request, msgOutput.GetMessageContentWritingStream(), version, conDesc); msgOutput.CloseStream(); // write to the stream } else { throw new NotImplementedException("handling for this type of .NET message is not implemented at the moment, type: " + replyMsg.GetType()); } }
/// <summary> /// This method parses an url for the IIOP channel. /// It extracts the channel URI and the objectURI /// </summary> /// <param name="url">the url to parse</param> /// <param name="objectURI">the objectURI</param> /// <returns>the channel-Uri</returns> internal Uri ParseUrl(string url, out string objectUri, out GiopVersion version) { Uri uri = null; if (url.StartsWith("iiop")) { IiopLoc iiopLoc = new IiopLoc(url, m_codec, m_defaultAdditionalTaggedComponents); uri = iiopLoc.ParseUrl(out objectUri, out version); } else if (url.StartsWith("IOR")) { Ior ior = new Ior(url); IInternetIiopProfile profile = ior.FindInternetIiopProfile(); if (profile != null) { uri = new Uri("iiop" + profile.Version.Major + "." + profile.Version.Minor + Uri.SchemeDelimiter + profile.HostName + ":" + profile.Port); objectUri = IorUtil.GetObjectUriForObjectKey(profile.ObjectKey); version = profile.Version; } else { uri = null; objectUri = null; version = new GiopVersion(1, 0); } } else if (url.StartsWith("corbaloc")) { Corbaloc loc = new Corbaloc(url, m_codec, m_defaultAdditionalTaggedComponents); uri = loc.ParseUrl(out objectUri, out version); } else { // not possible uri = null; objectUri = null; version = new GiopVersion(1, 0); } return uri; }
/// <summary> /// the same as AlignBodyIfNeeded, but without throwing exception, when not enough bytes. /// </summary> protected void TryAlignBodyIfNeeded(CdrInputStream cdrStream, GiopVersion version) { if (!version.IsBeforeGiop1_2()) { cdrStream.TryForceReadAlign(Aligns.Align8); } // force an align on 8 for GIOP-version >= 1.2 }
public void TestReplySerialisation() { // request msg the reply is for MethodInfo methodToCall = typeof(TestService).GetMethod("Add"); object[] args = new object[] { ((Int32)1), ((Int32)2) }; string uri = "iiop://localhost:8087/testuri"; // Giop 1.2 will be used because no version spec in uri GiopVersion version = new GiopVersion(1, 2); TestMessage msg = new TestMessage(methodToCall, args, uri); msg.Properties[SimpleGiopMsg.REQUEST_ID_KEY] = (uint)5; msg.Properties[SimpleGiopMsg.GIOP_VERSION_KEY] = version; msg.Properties[SimpleGiopMsg.CALLED_METHOD_KEY] = methodToCall; msg.Properties[SimpleGiopMsg.IDL_METHOD_NAME_KEY] = methodToCall.Name; // done by serialization normally // create a connection context GiopConnectionDesc conDesc = new GiopConnectionDesc(null, null); // create the reply ReturnMessage retMsg = new ReturnMessage((Int32)3, new object[0], 0, null, msg); MemoryStream targetStream = new MemoryStream(); m_handler.SerialiseOutgoingReplyMessage(retMsg, msg, version, targetStream, conDesc); // check to serialised stream targetStream.Seek(0, SeekOrigin.Begin); CdrInputStreamImpl cdrIn = new CdrInputStreamImpl(targetStream); cdrIn.ConfigStream(0, new GiopVersion(1, 2)); // first is Giop-magic byte data; AssertBytesFollowing(m_giopMagic, cdrIn); // Giop version data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(2, data); // flags: big-endian, no fragements data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(0, data); // Giop Msg type: reply data = (byte)cdrIn.ReadOctet(); Assert.AreEqual(1, data); // Giop Msg length uint msgLength = cdrIn.ReadULong(); cdrIn.SetMaxLength(msgLength); // req-id Assert.AreEqual(5, cdrIn.ReadULong()); // response status: NO_EXCEPTION Assert.AreEqual(0, cdrIn.ReadULong()); // ignore service contexts SkipServiceContexts(cdrIn); // Giop 1.2, must be aligned on 8 cdrIn.ForceReadAlign(Aligns.Align8); // now return value is following Assert.AreEqual(3, cdrIn.ReadLong()); }
public Uri ParseUrl(out string objectUri, out GiopVersion version) { objectUri = ObjectUri; return(m_objAddr.ParseUrl(objectUri, out version)); }
/// <summary>read the target for the request</summary> /// <returns>the objectURI extracted from this msg</returns> private string ReadTarget(CdrInputStream cdrStream, GiopVersion version, out byte[] objectKey) { if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1 only object key is possible objectKey = ReadTargetKey(cdrStream); } else { // for GIOP >= 1.2, a union is used for target information ushort targetAdrType = cdrStream.ReadUShort(); switch (targetAdrType) { case 0: objectKey = ReadTargetKey(cdrStream); break; default: Trace.WriteLine("received not yet supported target address type: " + targetAdrType); throw new BAD_PARAM(650, CompletionStatus.Completed_No); } } // get the object-URI of the responsible object return IorUtil.GetObjectUriForObjectKey(objectKey); }
private void WriteTarget(CdrOutputStream cdrStream, byte[] objectKey, GiopVersion version) { if (!version.IsBeforeGiop1_2()) { // for GIOP >= 1.2 ushort targetAdrType = 0; cdrStream.WriteUShort(targetAdrType); // object key adressing } WriteTargetKey(cdrStream, objectKey); }
/// <summary>serializes the request body</summary> /// <param name="targetStream"></param> /// <param name="clientRequest">the request to serialise</param> /// <param name="version">the GIOP-version</param> private void SerialiseRequestBody(CdrOutputStream targetStream, GiopClientRequest clientRequest, GiopVersion version, ArgumentsSerializer ser) { // body of request msg: serialize arguments // clarification from CORBA 2.6, chapter 15.4.1: no padding, when no arguments are serialised --> // for backward compatibility, do it nevertheless AlignBodyIfNeeded(targetStream, version); ser.SerializeRequestArgs(clientRequest.RequestMethodName, clientRequest.RequestArguments, targetStream, clientRequest.RequestCallContext); }
/// <summary> /// perform code set establishment on the server side /// </summary> protected void PerformCodeSetEstablishmentServer(GiopVersion version, GiopConnectionDesc conDesc, ServiceContextList cntxColl) { if (version.IsAfterGiop1_0()) { if (!conDesc.IsCodeSetNegotiated()) { // check for code set establishment CodeSetServiceContext context = CodeSetService.FindCodeSetServiceContext(cntxColl); if (context != null) { CodeSetService.CheckCodeSetCompatible(context.CharSet, context.WCharSet); conDesc.SetNegotiatedCodeSets(context.CharSet, context.WCharSet); } } } else { conDesc.SetCodeSetNegotiated(); } }
public void Setup() { m_version = new GiopVersion(1, 2); m_hostName = "localhost"; m_port = 8089; m_objectKey = new byte[] { 65 }; m_profile = new InternetIiopProfile(m_version, m_hostName, m_port, m_objectKey); m_serFactory = new SerializerFactory(); CodecFactory codecFactory = new Ch.Elca.Iiop.Interception.CodecFactoryImpl(m_serFactory); m_codec = codecFactory.create_codec( new omg.org.IOP.Encoding(ENCODING_CDR_ENCAPS.ConstVal, 1, 2)); IiopUrlUtil iiopUrlUtil = IiopUrlUtil.Create(m_codec, new object[] { Services.CodeSetService.CreateDefaultCodesetComponent(m_codec)}); m_serFactory.Initalize(new SerializerFactoryConfig(), iiopUrlUtil); }
protected void AlignBodyIfNeeded(CdrOutputStream cdrStream, GiopVersion version) { if (!version.IsBeforeGiop1_2()) { cdrStream.ForceWriteAlign(Aligns.Align8); } // force an align on 8 for GIOP-version >= 1.2 }