read_any() public method

public read_any ( ) : Otp.Erlang.Object
return Otp.Erlang.Object
Beispiel #1
0
 /*
  * <p> Deserialize and return a new copy of the message contained in
  * this OtpMsg. </p>
  *
  * <p> The first time this method is called the actual payload is
  * deserialized and the Erlang term is created. Calling this method
  * subsequent times will not cuase the message to be deserialized
  * additional times, instead the same Erlang term object will be
  * returned. </p>
  *
  * @return an Erlang term.
  *
  * @exception DecodeException if the byte stream could not be deserialized.
  *
  **/
 public Erlang.Object getMsg()
 {
     if (payload == null)
     {
         payload = paybuf.read_any();
     }
     return(payload);
 }
Beispiel #2
0
        public virtual void Start()
        {
            if (!connected)
            {
                deliver(new System.IO.IOException("Not connected"));
                return ;
            }

            byte[] lbuf = new byte[4];
            OtpInputStream ibuf;
            Erlang.Object traceobj;
            int len;
            byte[] tock = new byte[]{0, 0, 0, 0};
            
            try
            {
                while (!done)
                {
                    // don't return until we get a real message
                    // or a failure of some kind (e.g. EXIT)
                    // read length and read buffer must be atomic!
                    do
                    {
                        // read 4 bytes - get length of incoming packet
                        // socket.getInputStream().read(lbuf);
                        int n;
                        if ((n = readSock(socket, lbuf)) < lbuf.Length)
                            throw new System.Exception("Read " + n + " out of " + lbuf.Length + " bytes!");

                        ibuf = new OtpInputStream(lbuf);
                        len = ibuf.read4BE();
                        
                        //  received tick? send tock!
                        if (len == 0)
                            lock(this)
                            {
                                System.Byte[] temp_bytearray;
                                temp_bytearray = tock;
                                if (socket != null)
                                    ((System.IO.Stream) socket.GetStream()).Write(temp_bytearray, 0, temp_bytearray.Length);
                            }
                        
                    }
                    while (len == 0); // tick_loop
                    
                    // got a real message (maybe) - read len bytes
                    byte[] tmpbuf = new byte[len];
                    // i = socket.getInputStream().read(tmpbuf);
                    int m = readSock(socket, tmpbuf);
                    if (m < len)
                        throw new System.Exception("Read " + m + " out of " + len + " bytes!");

                    ibuf = new OtpInputStream(tmpbuf);
                    
                    if (ibuf.read1() != passThrough)
                    {
                        goto receive_loop_brk;
                    }
                    
                    // got a real message (really)
                    Erlang.Atom reason = null;
                    Erlang.Atom cookie = null;
                    Erlang.Object tmp = null;
                    Erlang.Tuple head = null;
                    Erlang.Atom toName;
                    Erlang.Pid to;
                    Erlang.Pid from;
                    Erlang.Ref eref;
                    
                    // decode the header
                    tmp = ibuf.read_any();
                    if (!(tmp is Erlang.Tuple))
                    {
                        goto receive_loop_brk;
                    }
                    
                    head = (Erlang.Tuple) tmp;
                    if (!(head.elementAt(0) is Erlang.Long))
                    {
                        goto receive_loop_brk;
                    }
                    
                    // lets see what kind of message this is
                    OtpMsg.Tag tag = (OtpMsg.Tag)((Erlang.Long)(head.elementAt(0))).longValue();
                    
                    switch (tag)
                    {
                        case OtpMsg.Tag.sendTag:
                        case OtpMsg.Tag.sendTTTag: 
                            // { SEND, Cookie, ToPid, TraceToken }
                            if (!cookieOk)
                            {
                                // we only check this once, he can send us bad cookies later if he likes
                                if (!(head.elementAt(1) is Erlang.Atom))
                                {
                                    goto receive_loop_brk;
                                }
                                cookie = (Erlang.Atom) head.elementAt(1);
                                if (sendCookie)
                                {
                                    if (!cookie.atomValue().Equals(auth_cookie))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                else
                                {
                                    if (!cookie.atomValue().Equals(""))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                cookieOk = true;
                            }

                            if (traceLevel >= OtpTrace.Type.sendThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());

                                /*show received payload too */
                                long mark = ibuf.Position;
                                traceobj = ibuf.read_any();

                                if (traceobj != null)
                                    OtpTrace.TraceEvent("   " + traceobj.ToString());
                                else
                                    OtpTrace.TraceEvent("   (null)");
                                ibuf.Seek(mark, System.IO.SeekOrigin.Begin);
                            }

                            to = (Erlang.Pid) (head.elementAt(2));

                            deliver(new OtpMsg(to, ibuf));
                            break;

                        case OtpMsg.Tag.regSendTag:
                        case OtpMsg.Tag.regSendTTTag:
                            // { REG_SEND, FromPid, Cookie, ToName, TraceToken }
                            if (!cookieOk)
                            {
                                // we only check this once, he can send us bad cookies later if he likes
                                if (!(head.elementAt(2) is Erlang.Atom))
                                {
                                    goto receive_loop_brk;
                                }
                                cookie = (Erlang.Atom) head.elementAt(2);
                                if (sendCookie)
                                {
                                    if (!cookie.atomValue().Equals(auth_cookie))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                else
                                {
                                    if (!cookie.atomValue().Equals(""))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                cookieOk = true;
                            }

                            if (traceLevel >= OtpTrace.Type.sendThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                                
                                /*show received payload too */
                                long mark = ibuf.Position;
                                traceobj = ibuf.read_any();

                                if (traceobj != null)
                                    OtpTrace.TraceEvent("   " + traceobj.ToString());
                                else
                                    OtpTrace.TraceEvent("   (null)");
                                ibuf.Seek(mark, System.IO.SeekOrigin.Begin);
                            }

                            from = (Erlang.Pid) (head.elementAt(1));
                            toName = (Erlang.Atom) (head.elementAt(3));

                            deliver(new OtpMsg(from, toName.atomValue(), ibuf));
                            break;

                        case OtpMsg.Tag.exitTag:
                        case OtpMsg.Tag.exit2Tag:
                            // { EXIT2, FromPid, ToPid, Reason }
                            if (!(head.elementAt(3) is Erlang.Atom))
                            {
                                goto receive_loop_brk;
                            }
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }
                            
                            from = (Erlang.Pid) (head.elementAt(1));
                            to = (Erlang.Pid) (head.elementAt(2));
                            reason = (Erlang.Atom) head.elementAt(3);
                            
                            deliver(new OtpMsg(tag, from, to, reason));
                            break;

                        case OtpMsg.Tag.exitTTTag:
                        case OtpMsg.Tag.exit2TTTag:
                            // { EXIT2, FromPid, ToPid, TraceToken, Reason }
                            // as above, but bifferent element number
                            if (!(head.elementAt(4) is Erlang.Atom))
                            {
                                goto receive_loop_brk;
                            }
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }

                            from = (Erlang.Pid) (head.elementAt(1));
                            to = (Erlang.Pid) (head.elementAt(2));
                            reason = (Erlang.Atom) head.elementAt(4);

                            deliver(new OtpMsg(tag, from, to, reason));
                            break;

                        case OtpMsg.Tag.linkTag:
                        case OtpMsg.Tag.unlinkTag:
                            // { UNLINK, FromPid, ToPid}
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }
                            
                            from = (Erlang.Pid) (head.elementAt(1));
                            to = (Erlang.Pid) (head.elementAt(2));

                            deliver(new OtpMsg(tag, from, to));
                            break;

                        // absolutely no idea what to do with these, so we ignore them...
                        case OtpMsg.Tag.groupLeaderTag:
                        case OtpMsg.Tag.nodeLinkTag:
                            // { NODELINK }
                            // (just show trace)
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }
                            break;

                        case OtpMsg.Tag.monitorPTag:
                            // {MONITOR_P, FromPid, ToProc, Ref}
                        case OtpMsg.Tag.demonitorPTag:
                            // {DEMONITOR_P, FromPid, ToProc, Ref}
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }
                            from = (Erlang.Pid)(head.elementAt(1));
                            to = (Erlang.Pid)(head.elementAt(2));
                            eref = (Erlang.Ref)(head.elementAt(3));
                            deliver(new OtpMsg(tag, from, to, eref));
                            break;

                        case OtpMsg.Tag.monitorPexitTag:
                            // {MONITOR_P_EXIT, FromPid, ToProc, Ref, Reason}
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- " + headerType(head) + " " + head.ToString());
                            }
                            from = (Erlang.Pid)(head.elementAt(1));
                            to = (Erlang.Pid)(head.elementAt(2));
                            eref = (Erlang.Ref)(head.elementAt(3));

                            deliver(new OtpMsg(tag, from, to, eref, reason));
                            break;

                        default:
                            // garbage?
                            if (traceLevel >= OtpTrace.Type.ctrlThreshold)
                            {
                                OtpTrace.TraceEvent("<- Unknown tag " + headerType(head) + " " + head.ToString());
                            }
                            goto receive_loop_brk;
                    }
                }
receive_loop_brk: ;
                 // end receive_loop

                // this section reachable only with break
                // we have received garbage from peer
                deliver(new Erlang.Exit("Remote is sending garbage"));

            }
            catch (OtpAuthException e)
            {
                deliver(e);
            }
            catch (Erlang.Exception e)
            {
                OtpTrace.TraceEvent(e.ToString());
                deliver(new Erlang.Exit("Remote is sending garbage: " + e.ToString()));
            }
            catch (System.Exception e)
            {
                deliver(new Erlang.Exit("Remote has closed connection: " + e.ToString()));
            }
            finally
            {
                close();
                OtpTrace.TraceEvent("exit connection "+System.Threading.Thread.CurrentThread.Name);
            }
        }