Пример #1
0
        public static IDictionary ToSerpentDict(object obj)
        {
            PyroException ex   = (PyroException)obj;
            IDictionary   dict = new Hashtable();

            // {'attributes':{},'__exception__':True,'args':('hello',),'__class__':'PyroError'}
            dict["__class__"]     = "PyroError";
            dict["__exception__"] = true;
            if (ex.Message != null)
            {
                dict["args"] = new object[1] {
                    ex.Message
                }
            }
            ;
            else
            {
                dict["args"] = new object[0];
            }
            if (!string.IsNullOrEmpty(ex._pyroTraceback))
            {
                ex.Data["_pyroTraceback"] = new string[] { ex._pyroTraceback }
            }
            ;                                                                                   // transform single string back into list
            dict["attributes"] = ex.Data;
            return(dict);
        }
Пример #2
0
        public void PyroClassesPickle()
        {
            var pickler = new PickleSerializer();
            var uri = new PyroURI("PYRO:something@localhost:4444");
            byte[] s = pickler.serializeData(uri);
            object x = pickler.deserializeData(s);
            Assert.AreEqual(uri, x);

            var proxy = new PyroProxy(uri);
            proxy.correlation_id = Guid.NewGuid();
            proxy.pyroHandshake = "apples";
            proxy.pyroHmacKey = Encoding.UTF8.GetBytes("secret");
            proxy.pyroAttrs = new HashSet<string>();
            proxy.pyroAttrs.Add("attr1");
            proxy.pyroAttrs.Add("attr2");
            s = pickler.serializeData(proxy);
            x = pickler.deserializeData(s);
            PyroProxy proxy2 = (PyroProxy) x;
            Assert.AreEqual(uri.host, proxy2.hostname);
            Assert.AreEqual(uri.objectid, proxy2.objectid);
            Assert.AreEqual(uri.port, proxy2.port);
            Assert.IsNull(proxy2.correlation_id, "correlation_id is not serialized on the proxy object");
            Assert.AreEqual(proxy.pyroHandshake, proxy2.pyroHandshake);
            Assert.AreEqual(proxy.pyroHmacKey, proxy2.pyroHmacKey);
            Assert.AreEqual(2, proxy2.pyroAttrs.Count);
            Assert.AreEqual(proxy.pyroAttrs, proxy2.pyroAttrs);

            PyroException ex = new PyroException("error");
            s = pickler.serializeData(ex);
            x = pickler.deserializeData(s);
            PyroException ex2 = (PyroException) x;
            Assert.AreEqual(ex.Message, ex2.Message);
            Assert.IsNull(ex._pyroTraceback);
        }
Пример #3
0
	public static object FromSerpentDict(IDictionary dict)
	{
		object[] args = (object[]) dict["args"];
		PyroException ex = new PyroException((string)args[0]);
		IDictionary attrs = (IDictionary)dict["attributes"];
		foreach(DictionaryEntry entry in attrs)
		{
			string key = (string)entry.Key;
			ex.Data[key] = entry.Value;
			if("_pyroTraceback"==key)
			{
				// if the traceback is a list of strings, create one string from it
				if(entry.Value is ICollection) {
					StringBuilder sb=new StringBuilder();
					ICollection tbcoll=(ICollection)entry.Value;
					foreach(object line in tbcoll) {
						sb.Append(line);
					}	
					ex._pyroTraceback=sb.ToString();
				} else {
					ex._pyroTraceback=(string)entry.Value;
				}
			}
		}
		return ex;
	}
Пример #4
0
		public void PyroClasses()
		{
			var uri = new PyroURI("PYRO:something@localhost:4444");
			byte[] s = this.ser.serializeData(uri);
			object x = this.ser.deserializeData(s);
			Assert.AreEqual(uri, x);

			var proxy = new PyroProxy(uri);
			s = this.ser.serializeData(proxy);
			x = this.ser.deserializeData(s);
			PyroProxy proxy2 = (PyroProxy) x;
			Assert.AreEqual(uri.host, proxy2.hostname);
			Assert.AreEqual(uri.objectid, proxy2.objectid);
			Assert.AreEqual(uri.port, proxy2.port);

			PyroException ex = new PyroException("error");
			s = this.ser.serializeData(ex);
			x = this.ser.deserializeData(s);
			PyroException ex2 = (PyroException) x;
			Assert.AreEqual(ex.Message, ex2.Message);
			Assert.IsNull(ex._pyroTraceback);
			
			// try another kind of pyro exception
			s = Encoding.UTF8.GetBytes("{'attributes':{'tb': 'traceback', '_pyroTraceback': ['line1', 'line2']},'__exception__':True,'args':('hello',42),'__class__':'CommunicationError'}");
			x = this.ser.deserializeData(s);
			ex2 = (PyroException) x;
			Assert.AreEqual("hello", ex2.Message);
			Assert.AreEqual("traceback", ex2.Data["tb"]);
			Assert.AreEqual("line1line2", ex2._pyroTraceback);
		}
Пример #5
0
        public static object FromSerpentDict(IDictionary dict)
        {
            object[]      args  = (object[])dict["args"];
            PyroException ex    = new PyroException((string)args[0]);
            IDictionary   attrs = (IDictionary)dict["attributes"];

            foreach (DictionaryEntry entry in attrs)
            {
                string key = (string)entry.Key;
                ex.Data[key] = entry.Value;
                if ("_pyroTraceback" == key)
                {
                    // if the traceback is a list of strings, create one string from it
                    if (entry.Value is ICollection)
                    {
                        StringBuilder sb     = new StringBuilder();
                        ICollection   tbcoll = (ICollection)entry.Value;
                        foreach (object line in tbcoll)
                        {
                            sb.Append(line);
                        }
                        ex._pyroTraceback = sb.ToString();
                    }
                    else
                    {
                        ex._pyroTraceback = (string)entry.Value;
                    }
                }
            }
            return(ex);
        }
Пример #6
0
        public static object FromSerpentDict(IDictionary dict)
        {
            object[] args = (object[])dict["args"];

            string        pythonExceptionType = (string)dict["__class__"];
            PyroException ex;

            if (args.Length == 0)
            {
                if (string.IsNullOrEmpty(pythonExceptionType))
                {
                    ex = new PyroException();
                }
                else
                {
                    ex = new PyroException("[" + pythonExceptionType + "]");
                }
            }
            else
            {
                if (string.IsNullOrEmpty(pythonExceptionType))
                {
                    ex = new PyroException((string)args[0]);
                }
                else
                {
                    ex = new PyroException(string.Format("[{0}] {1}", pythonExceptionType, args[0]));
                }
            }

            ex.PythonExceptionType = pythonExceptionType;

            IDictionary attrs = (IDictionary)dict["attributes"];

            foreach (DictionaryEntry entry in attrs)
            {
                string key = (string)entry.Key;
                ex.Data[key] = entry.Value;
                if ("_pyroTraceback" == key)
                {
                    // if the traceback is a list of strings, create one string from it
                    if (entry.Value is ICollection)
                    {
                        StringBuilder sb     = new StringBuilder();
                        ICollection   tbcoll = (ICollection)entry.Value;
                        foreach (object line in tbcoll)
                        {
                            sb.Append(line);
                        }
                        ex._pyroTraceback = sb.ToString();
                    }
                    else
                    {
                        ex._pyroTraceback = (string)entry.Value;
                    }
                }
            }
            return(ex);
        }
Пример #7
0
        public void PyroClassesSerpent()
        {
            var ser = new SerpentSerializer();
            var uri = new PyroURI("PYRO:something@localhost:4444");
            byte[] s = ser.serializeData(uri);
            object x = ser.deserializeData(s);
            Assert.AreEqual(uri, x);

            var proxy = new PyroProxy(uri);
            proxy.correlation_id = Guid.NewGuid();
            proxy.pyroHandshake = "apples";
            proxy.pyroHmacKey = Encoding.UTF8.GetBytes("secret");
            proxy.pyroAttrs = new HashSet<string>();
            proxy.pyroAttrs.Add("attr1");
            proxy.pyroAttrs.Add("attr2");
            s = ser.serializeData(proxy);
            x = ser.deserializeData(s);
            PyroProxy proxy2 = (PyroProxy) x;
            Assert.AreEqual(uri.host, proxy2.hostname);
            Assert.AreEqual(uri.objectid, proxy2.objectid);
            Assert.AreEqual(uri.port, proxy2.port);
            Assert.IsNull(proxy2.correlation_id, "correlation_id is not serialized on the proxy object");
            Assert.AreEqual(proxy.pyroHandshake, proxy2.pyroHandshake);
            Assert.AreEqual(proxy.pyroHmacKey, proxy2.pyroHmacKey);
            Assert.AreEqual(2, proxy2.pyroAttrs.Count);
            Assert.AreEqual(proxy.pyroAttrs, proxy2.pyroAttrs);

            PyroException ex = new PyroException("error");
            s = ser.serializeData(ex);
            x = ser.deserializeData(s);
            PyroException ex2 = (PyroException) x;
            Assert.AreEqual(ex.Message, ex2.Message);
            Assert.IsNull(ex._pyroTraceback);

            // try another kind of pyro exception
            s = Encoding.UTF8.GetBytes("{'attributes':{'tb': 'traceback', '_pyroTraceback': ['line1', 'line2']},'__exception__':True,'args':('hello',42),'__class__':'CommunicationError'}");
            x = ser.deserializeData(s);
            ex2 = (PyroException) x;
            Assert.AreEqual("hello", ex2.Message);
            Assert.AreEqual("traceback", ex2.Data["tb"]);
            Assert.AreEqual("line1line2", ex2._pyroTraceback);
        }
Пример #8
0
        public void pickle(object o, Stream outs, Pickler currentPickler)
        {
            PyroException error = (PyroException)o;

            outs.WriteByte(Opcodes.GLOBAL);
            byte[] output = Encoding.Default.GetBytes("Pyro4.errors\nPyroError\n");
            outs.Write(output, 0, output.Length);
            object[] args = new object[] { error.Message };
            currentPickler.save(args);
            outs.WriteByte(Opcodes.REDUCE);

            if (!string.IsNullOrEmpty(error._pyroTraceback))
            {
                // add _pyroTraceback attribute to the output
                Hashtable tb = new Hashtable();
                tb["_pyroTraceback"] = new string[] { error._pyroTraceback };                   // transform single string back into list
                currentPickler.save(tb);
                outs.WriteByte(Opcodes.BUILD);
            }
        }
Пример #9
0
		public void PyroClasses()
		{
			var uri = new PyroURI("PYRO:object@host:4444");
			byte[] s = this.ser.serializeData(uri);
			object x = this.ser.deserializeData(s);
			Assert.AreEqual(uri, x);

			var proxy = new PyroProxy(uri);
			s = this.ser.serializeData(proxy);
			x = this.ser.deserializeData(s);
			PyroProxy proxy2 = (PyroProxy) x;
			Assert.AreEqual(uri.host, proxy2.hostname);
			Assert.AreEqual(uri.objectid, proxy2.objectid);
			Assert.AreEqual(uri.port, proxy2.port);

			var ex = new PyroException("error");
			ex._pyroTraceback = "traceback";
			s = this.ser.serializeData(ex);
			x = this.ser.deserializeData(s);
			PyroException ex2 = (PyroException) x;
			Assert.AreEqual(ex.Message, ex2.Message);
			Assert.AreEqual("traceback", ex2._pyroTraceback);
		}
Пример #10
0
        /// <summary>
        /// Internal call method to actually perform the Pyro method call and process the result.
        /// </summary>
        private object internal_call(string method, string actual_objectId, ushort flags, bool checkMethodName, params object[] parameters)
        {
            actual_objectId = actual_objectId ?? this.objectid;
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            }
            if(pyroAttrs.Contains(method)) {
            throw new PyroException("cannot call an attribute");
            }
            if(pyroOneway.Contains(method)) {
            flags |= Message.FLAGS_ONEWAY;
            }
            if(checkMethodName && Config.METADATA && !pyroMethods.Contains(method)) {
            throw new PyroException(string.Format("remote object '{0}' has no exposed attribute or method '{1}'", actual_objectId, method));
            }

            if (parameters == null)
            parameters = new object[] {};

            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);
            byte[] pickle = ser.serializeCall(actual_objectId, method, parameters, new Dictionary<string,object>(0));
            var msg = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, this.annotations(), pyroHmacKey);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, msg.to_bytes());
            if(Config.MSG_TRACE_DIR!=null) {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }
            pickle = null;

            if ((flags & Message.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = Message.recv(sock_stream, new ushort[]{Message.MSG_RESULT}, pyroHmacKey);
            }
            if (resultmsg.seq != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            responseAnnotations(resultmsg.annotations, resultmsg.type);
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) {
            _decompressMessageData(resultmsg);
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) {
            Exception rx = (Exception) ser.deserializeData(resultmsg.data);
            if (rx is PyroException) {
                throw (PyroException) rx;
            } else {
                PyroException px = new PyroException("remote exception occurred", rx);
                PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                if(remotetbProperty!=null) {
                    string remotetb=(string)remotetbProperty.GetValue(rx,null);
                    px._pyroTraceback=remotetb;
                }
                throw px;
            }
            }

            return ser.deserializeData(resultmsg.data);
        }
Пример #11
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, ushort flags, params object[] parameters)
        {
            lock (this) {
                connect();
                unchecked {
                    sequenceNr++;                // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
                }
            }
            if (parameters == null)
            {
                parameters = new object[] {}
            }
            ;
            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);

            byte[]  pickle = ser.serializeCall(objectid, method, parameters, new Dictionary <string, object>(0));
            var     msg    = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, null);
            Message resultmsg;

            lock (this.sock) {
                IOUtil.send(sock_stream, msg.to_bytes());
                if (Config.MSG_TRACE_DIR != null)
                {
                    Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
                }
                pickle = null;

                if ((flags & Message.FLAGS_ONEWAY) != 0)
                {
                    return(null);
                }

                resultmsg = Message.recv(sock_stream, new ushort[] { Message.MSG_RESULT });
            }
            if (resultmsg.seq != sequenceNr)
            {
                throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0)
            {
                // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
                // data and the deflate data bytes that .net expects.
                // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
                using (MemoryStream compressed = new MemoryStream(resultmsg.data, 2, resultmsg.data.Length - 2, false)) {
                    using (DeflateStream decompresser = new DeflateStream(compressed, CompressionMode.Decompress)) {
                        MemoryStream bos    = new MemoryStream(resultmsg.data.Length);
                        byte[]       buffer = new byte[4096];
                        int          numRead;
                        while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            bos.Write(buffer, 0, numRead);
                        }
                        resultmsg.data = bos.ToArray();
                    }
                }
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0)
            {
                Exception rx = (Exception)ser.deserializeData(resultmsg.data);
                if (rx is PyroException)
                {
                    throw (PyroException)rx;
                }
                else
                {
                    PyroException px = new PyroException("remote exception occurred", rx);
                    PropertyInfo  remotetbProperty = rx.GetType().GetProperty("_pyroTraceback");
                    if (remotetbProperty != null)
                    {
                        string remotetb = (string)remotetbProperty.GetValue(rx, null);
                        px._pyroTraceback = remotetb;
                    }
                    throw px;
                }
            }

            return(ser.deserializeData(resultmsg.data));
        }
Пример #12
0
        /// <summary>
        /// Internal call method to actually perform the Pyro method call and process the result.
        /// </summary>
        private object internal_call(string method, string actual_objectId, ushort flags, bool checkMethodName, params object[] parameters)
        {
            actual_objectId = actual_objectId ?? this.objectid;
            lock (this) {
                connect();
                unchecked {
                    sequenceNr++;                // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
                }
            }
            if (pyroAttrs.Contains(method))
            {
                throw new PyroException("cannot call an attribute");
            }
            if (pyroOneway.Contains(method))
            {
                flags |= Message.FLAGS_ONEWAY;
            }
            if (checkMethodName && Config.METADATA && !pyroMethods.Contains(method))
            {
                throw new PyroException(string.Format("remote object '{0}' has no exposed attribute or method '{1}'", actual_objectId, method));
            }

            if (parameters == null)
            {
                parameters = new object[] {}
            }
            ;

            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);

            byte[]  pickle = ser.serializeCall(actual_objectId, method, parameters, new Dictionary <string, object>(0));
            var     msg    = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, this.annotations(), pyroHmacKey);
            Message resultmsg;

            lock (this.sock) {
                IOUtil.send(sock_stream, msg.to_bytes());
                if (Config.MSG_TRACE_DIR != null)
                {
                    Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
                }
                // ReSharper disable once RedundantAssignment
                pickle = null;

                if ((flags & Message.FLAGS_ONEWAY) != 0)
                {
                    return(null);
                }

                resultmsg = Message.recv(sock_stream, new [] { Message.MSG_RESULT }, pyroHmacKey);
            }
            if (resultmsg.seq != sequenceNr)
            {
                throw new PyroException("result msg out of sync");
            }
            responseAnnotations(resultmsg.annotations, resultmsg.type);
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0)
            {
                _decompressMessageData(resultmsg);
            }

            if ((resultmsg.flags & Message.FLAGS_ITEMSTREAMRESULT) != 0)
            {
                byte[] streamId;
                if (!resultmsg.annotations.TryGetValue("STRM", out streamId))
                {
                    throw new PyroException("result of call is an iterator, but the server is not configured to allow streaming");
                }
                return(new StreamResultIterator(Encoding.UTF8.GetString(streamId), this));
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0)
            {
                Exception rx = (Exception)ser.deserializeData(resultmsg.data);
                if (rx is PyroException)
                {
                    throw (PyroException)rx;
                }
                else
                {
                    PyroException px;

                    // if the source was a PythonException, copy its message and python exception type
                    PythonException pyx = rx as PythonException;
                    if (pyx == null)
                    {
                        px = new PyroException(null, rx);
                    }
                    else
                    {
                        px = new PyroException(rx.Message, rx);
                        px.PythonExceptionType = pyx.PythonExceptionType;
                    }

                    PropertyInfo remotetbProperty = rx.GetType().GetProperty("_pyroTraceback");
                    if (remotetbProperty != null)
                    {
                        string remotetb = (string)remotetbProperty.GetValue(rx, null);
                        px._pyroTraceback = remotetb;
                    }
                    throw px;
                }
            }

            return(ser.deserializeData(resultmsg.data));
        }
Пример #13
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, int flags, params object[] parameters)
        {
            lock (this) {
                connect();
                unchecked {
                    sequenceNr++;                // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
                }
                Console.WriteLine("seq=" + sequenceNr);
            }
            if (parameters == null)
            {
                parameters = new object[] {}
            }
            ;
            object[] invokeparams = new object[] {
                objectid, method, parameters,              // vargs
                new Hashtable(0)                           // no kwargs
            };
            Pickler pickler = new Pickler(false);

            byte[] pickle = pickler.dumps(invokeparams);
            pickler.close();
            byte[]  headerdata = MessageFactory.createMsgHeader(MessageFactory.MSG_INVOKE, pickle, flags, sequenceNr);
            Message resultmsg;

            lock (this.sock) {
                IOUtil.send(sock_stream, headerdata);
                IOUtil.send(sock_stream, pickle);
                if (Config.MSG_TRACE_DIR != null)
                {
                    MessageFactory.TraceMessageSend(sequenceNr, headerdata, pickle);
                }
                pickle     = null;
                headerdata = null;

                if ((flags & MessageFactory.FLAGS_ONEWAY) != 0)
                {
                    return(null);
                }

                resultmsg = MessageFactory.getMessage(sock_stream, MessageFactory.MSG_RESULT);
            }
            if (resultmsg.sequence != sequenceNr)
            {
                throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_COMPRESSED) != 0)
            {
                // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
                // data and the deflate data bytes that .net expects.
                // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
                using (MemoryStream compressed = new MemoryStream(resultmsg.data, 2, resultmsg.data.Length - 2, false)) {
                    using (DeflateStream decompresser = new DeflateStream(compressed, CompressionMode.Decompress)) {
                        MemoryStream bos    = new MemoryStream(resultmsg.data.Length);
                        byte[]       buffer = new byte[4096];
                        int          numRead;
                        while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            bos.Write(buffer, 0, numRead);
                        }
                        resultmsg.data = bos.ToArray();
                    }
                }
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_EXCEPTION) != 0)
            {
                using (Unpickler unpickler = new Unpickler()) {
                    Exception rx = (Exception)unpickler.loads(resultmsg.data);
                    if (rx is PyroException)
                    {
                        throw (PyroException)rx;
                    }
                    else
                    {
                        PyroException px = new PyroException("remote exception occurred", rx);
                        PropertyInfo  remotetbProperty = rx.GetType().GetProperty("_pyroTraceback");
                        if (remotetbProperty != null)
                        {
                            string remotetb = (string)remotetbProperty.GetValue(rx, null);
                            px._pyroTraceback = remotetb;
                        }
                        throw px;
                    }
                }
            }

            using (Unpickler unpickler = new Unpickler()) {
                return(unpickler.loads(resultmsg.data));
            }
        }
Пример #14
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, ushort flags, params object[] parameters)
        {
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            }
            if (parameters == null)
            parameters = new object[] {};
            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);
            byte[] pickle = ser.serializeCall(objectid, method, parameters, new Dictionary<string,object>(0));
            var msg = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, null);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, msg.to_bytes());
            if(Config.MSG_TRACE_DIR!=null) {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }
            pickle = null;

            if ((flags & Message.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = Message.recv(sock_stream, new ushort[]{Message.MSG_RESULT});
            }
            if (resultmsg.seq != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) {
            // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
            // data and the deflate data bytes that .net expects.
            // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
            using(MemoryStream compressed=new MemoryStream(resultmsg.data, 2, resultmsg.data.Length-2, false)) {
                using(DeflateStream decompresser=new DeflateStream(compressed, CompressionMode.Decompress)) {
                    MemoryStream bos = new MemoryStream(resultmsg.data.Length);
                    byte[] buffer = new byte[4096];
                    int numRead;
                    while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0) {
                        bos.Write(buffer, 0, numRead);
                    }
                    resultmsg.data=bos.ToArray();
                }
            }
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) {
            Exception rx = (Exception) ser.deserializeData(resultmsg.data);
            if (rx is PyroException) {
                throw (PyroException) rx;
            } else {
                PyroException px = new PyroException("remote exception occurred", rx);
                PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                if(remotetbProperty!=null) {
                    string remotetb=(string)remotetbProperty.GetValue(rx,null);
                    px._pyroTraceback=remotetb;
                }
                throw px;
            }
            }

            return ser.deserializeData(resultmsg.data);
        }
Пример #15
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, int flags, params object[] parameters)
        {
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            Console.WriteLine("seq="+sequenceNr);
            }
            if (parameters == null)
            parameters = new object[] {};
            object[] invokeparams = new object[] {
                    objectid, method, parameters, // vargs
                    new Hashtable(0)   // no kwargs
                };
            Pickler pickler=new Pickler(false);
            byte[] pickle = pickler.dumps(invokeparams);
            pickler.close();
            byte[] headerdata = MessageFactory.createMsgHeader(MessageFactory.MSG_INVOKE, pickle, flags, sequenceNr);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, headerdata);
            IOUtil.send(sock_stream, pickle);
            if(Config.MSG_TRACE_DIR!=null) {
                MessageFactory.TraceMessageSend(sequenceNr, headerdata, pickle);
            }
            pickle = null;
            headerdata = null;

            if ((flags & MessageFactory.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = MessageFactory.getMessage(sock_stream, MessageFactory.MSG_RESULT);
            }
            if (resultmsg.sequence != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_COMPRESSED) != 0) {
            // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
            // data and the deflate data bytes that .net expects.
            // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
            using(MemoryStream compressed=new MemoryStream(resultmsg.data, 2, resultmsg.data.Length-2, false)) {
                using(DeflateStream decompresser=new DeflateStream(compressed, CompressionMode.Decompress)) {
                    MemoryStream bos = new MemoryStream(resultmsg.data.Length);
                    byte[] buffer = new byte[4096];
                    int numRead;
                    while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0) {
                        bos.Write(buffer, 0, numRead);
                    }
                    resultmsg.data=bos.ToArray();
                }
            }
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_EXCEPTION) != 0) {
            using(Unpickler unpickler=new Unpickler()) {
                Exception rx = (Exception) unpickler.loads(resultmsg.data);
                if (rx is PyroException) {
                    throw (PyroException) rx;
                } else {
                    PyroException px = new PyroException("remote exception occurred", rx);
                    PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                    if(remotetbProperty!=null) {
                        string remotetb=(string)remotetbProperty.GetValue(rx,null);
                        px._pyroTraceback=remotetb;
                    }
                    throw px;
                }
            }
            }

            using(Unpickler unpickler=new Unpickler()) {
            return unpickler.loads(resultmsg.data);
            }
        }