Inheritance: OtpErlangObject
示例#1
0
        /**
         * Read an Erlang atom from the stream.
         *
         * @return a String containing the value of the atom.
         *
         * @exception OtpErlangDecodeException
         *                if the next term in the stream is not an atom.
         */
        public String read_atom()
        {
            int tag;
            int len;

            byte[] strbuf;
            String atom;

            tag = read1skip_version();

            if (tag != OtpExternal.atomTag)
            {
                throw new OtpErlangDecodeException("wrong tag encountered, expected " + OtpExternal.atomTag + ", got " + tag);
            }

            len = read2BE();

            strbuf = new byte[len];
            this.readN(strbuf);
            atom = OtpErlangString.newString(strbuf);

            if (atom.Length > OtpExternal.maxAtomLength)
            {
                atom = atom.Substring(0, OtpExternal.maxAtomLength);
            }

            return(atom);
        }
示例#2
0
        /**
         * Read a string from the stream.
         */
        public string ReadString()
        {
            int len;
            int tag = Read1SkipVersion();

            switch (tag)
            {
            case OtpExternal.stringTag:
                return(ReadStringData());

            case OtpExternal.nilTag:
                return("");

            case OtpExternal.listTag:     // List when unicode +
                len = Read4BE();
                int[] cps = new int[len];
                for (int i = 0; i < len; i++)
                {
                    cps[i] = ReadInt();
                }
                string s = OtpErlangString.FromCodePoints(cps);
                ReadNil();
                return(s);

            default:
                throw new OtpDecodeException("Wrong tag encountered, expected " + OtpExternal.stringTag + " or " + OtpExternal.listTag + ", got " + tag);
            }
        }
示例#3
0
        private async Task Port_R4(IOtpTransport socket, OtpInputStream ibuf)
        {
            try
            {
                int    len   = (int)(ibuf.Length - 1);
                byte[] alive = ibuf.ReadN(len);

                string name = OtpErlangString.FromEncoding(alive);
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug($"<- PORT (r4) {name}");
                }

                if (!portmap.TryGetValue(name, out AbstractNode node))
                {
                    node = null;
                }

                OtpOutputStream obuf = new OtpOutputStream();
                if (node != null)
                {
                    obuf.Write1(port4resp);
                    obuf.Write1(0);
                    obuf.Write2BE(node.Port);
                    obuf.Write1(node.Type);
                    obuf.Write1(node.Proto);
                    obuf.Write2BE(node.DistHigh);
                    obuf.Write2BE(node.DistLow);
                    obuf.Write2BE(len);
                    obuf.WriteN(alive);
                    obuf.Write2BE(0);
                    if (traceLevel >= traceThreshold)
                    {
                        Logger.Debug("-> 0 (success)");
                    }
                }
                else
                {
                    obuf.Write1(port4resp);
                    obuf.Write1(1);
                    if (traceLevel >= traceThreshold)
                    {
                        Logger.Debug("-> 1 (failure)");
                    }
                }

                await obuf.WriteToAsync(socket.OutputStream);
            }
            catch (IOException e)
            {
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug("<- (no response)");
                }
                throw new IOException("Request not responding", e);
            }
        }
示例#4
0
 /**
  * Create a list of Erlang integers representing Unicode codePoints.
  * This method does not check if the string contains valid code points.
  */
 public OtpErlangList(string str)
     : base(str.Length)
 {
     if (string.IsNullOrWhiteSpace(str))
     {
         return;
     }
     AddRange(OtpErlangString.ToCodePoints(str).Select((cp) => new OtpErlangInt(cp)));
 }
示例#5
0
        /**
         * Send an auth error to peer because he sent a bad cookie. The auth error
         * uses his cookie (not revealing ours). This is just like send_reg
         * otherwise
         */
        protected void CookieError(OtpLocalNode local, OtpErlangAtom cookie)
        {
            try
            {
                OtpOutputStream header = new OtpOutputStream(headerLen);

                // preamble: 4 byte length + "passthrough" tag + version
                header.Write4BE(0); // reserve space for length
                header.Write1(passThrough);
                header.Write1(version);

                header.WriteTupleHead(4);
                header.WriteLong(regSendTag);
                header.WriteAny(local.CreatePid()); // disposable pid
                header.WriteAtom(cookie.Value);     // important: his cookie,
                // not mine...
                header.WriteAtom("auth");

                // version for payload
                header.Write1(version);

                // the payload

                // the no_auth message (copied from Erlang) Don't change this
                // (Erlang will crash)
                // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
                // [foo@aule]}}
                IOtpErlangObject[] msg     = new IOtpErlangObject[2];
                IOtpErlangObject[] msgbody = new IOtpErlangObject[3];

                msgbody[0] = new OtpErlangAtom("print");
                msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n");

                // Erlang will crash and burn if there is no third argument here...
                msgbody[2] = new OtpErlangList(); // empty list

                msg[0] = new OtpErlangAtom("$gen_cast");
                msg[1] = new OtpErlangTuple(msgbody);

                OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg));

                // fix up length in preamble
                header.Poke4BE(0, header.Length + payload.Length - 4);

                try { DoSend(header, payload); }
                catch (IOException) { } // ignore
            }
            finally
            {
                Close();
            }

            throw new OtpAuthException("Remote cookie not authorized: " + cookie.Value);
        }
示例#6
0
            private void r4_port(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int    len   = (int)(ibuf.Length - 1);
                    byte[] alive = new byte[len];
                    ibuf.readN(alive);
                    String           name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = null;

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- PORT (r4) " + name);
                    }

                    lock (portmap)
                    {
                        if (portmap.ContainsKey(name))
                        {
                            node = portmap[name];
                        }
                    }

                    OtpOutputStream obuf = new OtpOutputStream();
                    if (node != null)
                    {
                        obuf.write1(port4resp);
                        obuf.write1(0);
                        obuf.write2BE(node.Port);
                        obuf.write1(node.Type);
                        obuf.write1(node.Proto);
                        obuf.write2BE(node.DistHigh);
                        obuf.write2BE(node.DistLow);
                        obuf.write2BE(len);
                        obuf.writeN(alive);
                        obuf.write2BE(0);
                    }
                    else
                    {
                        obuf.write1(port4resp);
                        obuf.write1(1);
                    }
                    obuf.WriteTo(s.GetStream());
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
示例#7
0
            private void r4_publish(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int    port     = ibuf.read2BE();
                    int    type     = ibuf.read1();
                    int    proto    = ibuf.read1();
                    int    distHigh = ibuf.read2BE();
                    int    distLow  = ibuf.read2BE();
                    int    len      = ibuf.read2BE();
                    byte[] alive    = new byte[len];
                    ibuf.readN(alive);
                    int    elen  = ibuf.read2BE();
                    byte[] extra = new byte[elen];
                    ibuf.readN(extra);
                    String           name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = new OtpPublishedNode(name);
                    node.Type     = type;
                    node.DistHigh = distHigh;
                    node.DistLow  = distLow;
                    node.Proto    = proto;
                    node.Port     = port;

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- PUBLISH (r4) " + name + " port=" + node.Port);
                    }

                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write1(publish4resp);
                    obuf.write1(0);
                    obuf.write2BE(epmd.Creation);
                    obuf.WriteTo(s.GetStream());

                    lock (portmap)
                    {
                        portmap.Add(name, node);
                    }
                    publishedPort.Add(name);
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
示例#8
0
        /**
         * Read a string from the stream.
         *
         * @return the value of the string.
         *
         * @exception OtpErlangDecodeException
         *                if the next term in the stream is not a string.
         */
        public String read_string()
        {
            int tag;
            int len;

            byte[] strbuf;
            tag = read1skip_version();
            switch (tag)
            {
            case OtpExternal.stringTag:
                len    = read2BE();
                strbuf = new byte[len];
                this.readN(strbuf);
                return(OtpErlangString.newString(strbuf));

            case OtpExternal.nilTag:
                return("");

            case OtpExternal.listTag:     // List when unicode +
                len = read4BE();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < len; i++)
                {
                    uint cp = (uint)read_int();
                    if (!OtpErlangString.isValidCodePoint((int)cp))
                    {
                        throw new OtpErlangDecodeException("Invalid CodePoint: " + cp);
                    }
                    if (1 <= (cp >> 16))
                    {
                        cp -= 0x10000;
                        char high = (char)((cp / 0x400) + 0xD800);
                        char low  = (char)((cp % 0x400) + 0xDC00);
                        sb.Append(high);
                        sb.Append(low);
                    }
                    else
                    {
                        sb.Append((char)cp);
                    }
                }
                read_nil();
                return(sb.ToString());

            default:
                throw new OtpErlangDecodeException("Wrong tag encountered, expected " + OtpExternal.stringTag
                                                   + " or " + OtpExternal.listTag + ", got " + tag);
            }
        }
示例#9
0
 /**
  * Create a list of Erlang integers representing Unicode codePoints.
  * This method does not check if the string contains valid code points.
  *
  * @param str
  *            the characters from which to create the list.
  */
 public OtpErlangList(String str)
 {
     if (str == null || str.Length == 0)
     {
         elems = NO_ELEMENTS;
     }
     else
     {
         int[] codePoints = OtpErlangString.stringToCodePoints(str);
         elems = new OtpErlangObject[codePoints.Length];
         for (int i = 0; i < elems.Length; i++)
         {
             elems[i] = new OtpErlangInt(codePoints[i]);
         }
     }
 }
示例#10
0
        /**
         * Write a string to the stream.
         *
         * @param s
         *            the string to write.
         */
        public void write_string(String s)
        {
            int len = s.Length;

            switch (len)
            {
            case 0:
                write_nil();
                break;

            default:
                if (len <= 65535 && is8bitString(s))     // 8-bit string
                {
                    try
                    {
                        byte[] bytebuf = Encoding.GetEncoding("iso-8859-1").GetBytes(s);
                        write1(OtpExternal.stringTag);
                        write2BE(len);
                        writeN(bytebuf);
                    }
                    catch (EncoderFallbackException)
                    {
                        write_nil();     // it should never ever get here...
                    }
                }
                else     // unicode or longer, must code as list
                {
                    int[] codePoints = OtpErlangString.stringToCodePoints(s);
                    write_list_head(codePoints.Length);
                    foreach (int codePoint in codePoints)
                    {
                        write_int(codePoint);
                    }
                    write_nil();
                }
                break;
            }
        }
示例#11
0
        /**
         * Read an Erlang float from the stream.
         *
         * @return the float value, as a double.
         *
         * @exception OtpErlangDecodeException
         *                if the next term in the stream is not a float.
         */
        public double read_double()
        {
            int tag;

            // parse the stream
            tag = read1skip_version();

            switch (tag)
            {
            case OtpExternal.newFloatTag:
            {
                return(BitConverter.ToDouble(BitConverter.GetBytes(readBE(8)), 0));
            }

            case OtpExternal.floatTag:
            {
                byte[] strbuf = new byte[31];
                String str;
                double val;

                // get the string
                this.readN(strbuf);
                str = OtpErlangString.newString(strbuf);

                if (!Double.TryParse(str, out val))
                {
                    throw new OtpErlangDecodeException("Invalid float format: '" + str + "'");
                }

                return(val);
            }

            default:
                throw new OtpErlangDecodeException("Wrong tag encountered, expected "
                                                   + OtpExternal.newFloatTag + ", got " + tag);
            }
        }
        public override IEnumerator<OtpActor.Continuation> GetEnumerator()
        {
            m_log.Info("[Distributed PC] New PCVM is ready: " + m_mbox.Self);

            while (true)
            {
                OtpMsg msg = null;

                yield return (delegate(OtpMsg received) { msg = received; });

                OtpErlangObject obj = msg.getMsg();

                if (obj is OtpErlangAtom)
                {
                    string atom = ((OtpErlangAtom)obj).atomValue();
                    if (!String.IsNullOrEmpty(atom) && atom == "noconnection")
                    {
                        break;
                    }
                }

                OtpErlangPid sender = null;
                OtpErlangObject[] reply = new OtpErlangObject[3];

                try
                {
                    OtpErlangTuple t = (OtpErlangTuple)obj;
                    sender = (OtpErlangPid)t.elementAt(0);

                    reply[0] = sender;
                    reply[1] = new OtpErlangAtom("ok");

                    string instr = ((OtpErlangAtom)t.elementAt(1)).ToString();

                    if (instr == "load")
                    {
                        Parser parser = PCVM.MakeParser();
                        string script = String.Empty;
                        if (t.elementAt(2) is OtpErlangString)
                        {
                            script = ((OtpErlangString)t.elementAt(2)).stringValue();
                        }
                        else
                        {
                            script = OtpErlangString.newString(((OtpErlangBinary)t.elementAt(2)).binaryValue());
                        }
                        bool debug = ((OtpErlangAtom)t.elementAt(3)).boolValue();

                        SYMBOL ast = parser.Parse(script);

                        m_vm.Call((Compiler.ExpPair)ast);

                        if (debug)
                        {
                            reply[2] = new OtpErlangAtom("continue");
                        }
                        else
                        {
                            Queue<PCObj> popped = new Queue<PCObj>();
                            try
                            {
                                m_vm.Finish(popped);
                            }
                            finally
                            {
                                reply = new OtpErlangObject[] {
                                    reply[0],
                                    reply[1],
                                    new OtpErlangAtom("finished"),
                                    ErlangObjectFromPCVMObject(popped.ToArray())
                                };
                            }
                        }
                    }
                    else if (instr == "step")
                    {
                        bool cont = true;
                        Queue<PCObj> popped = new Queue<PCObj>();
                        try
                        {
                            cont = m_vm.Step(popped);
                        }
                        finally
                        {
                            reply = new OtpErlangObject[] {
                                reply[0],
                                reply[1],
                                new OtpErlangAtom(cont ? "continue" : "finished"),
                                ErlangObjectFromPCVMObject(popped.ToArray())
                            };
                        }
                    }
                    else if (instr == "finish")
                    {
                        Queue<PCObj> popped = new Queue<PCObj>();
                        try
                        {
                            m_vm.Finish(popped);
                        }
                        finally
                        {
                            reply = new OtpErlangObject[] {
                                reply[0],
                                reply[1],
                                new OtpErlangAtom("finished"),
                                ErlangObjectFromPCVMObject(popped.ToArray())
                            };
                        }
                    }
                    else if (instr == "echo")
                    {
                        reply[2] = t.elementAt(2);
                    }
                    else if (instr == "exit")
                    {
                        reply[2] = new OtpErlangAtom("bye");
                        break;
                    }
                }
                catch (Exception e)
                {
                    m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg());

                    reply[1] = new OtpErlangAtom("error");
                    reply[2] = new OtpErlangString(e.Message);
                }
                finally
                {
                    if (sender != null)
                    {
                        m_mbox.send(sender, new OtpErlangTuple(reply));
                    }
                }
            }

            m_log.Info("[Distributed PC] Delete PCVM instance: " + m_mbox.Self);
            m_vm.Dispose();
        }
        public override IEnumerator<OtpActor.Continuation> GetEnumerator()
        {
            while (true)
            {
                OtpMsg msg = null;
                OtpErlangPid sender = null;
                OtpErlangTuple reply = null;

                yield return (delegate(OtpMsg received) { msg = received; });

                try
                {
                    OtpErlangTuple t = (OtpErlangTuple)msg.getMsg();
                    sender = (OtpErlangPid)t.elementAt(0);
                    string instr = ((OtpErlangAtom)t.elementAt(1)).ToString();
                    if (instr == "echo")
                    {
                        OtpErlangObject[] v = new OtpErlangObject[3];
                        v[0] = sender;
                        v[1] = new OtpErlangAtom("ok");
                        v[2] = t.elementAt(2);
                        reply = new OtpErlangTuple(v);
                    }
                    else if (instr == "new")
                    {
                        OtpActorMbox newmbox = (OtpActorMbox)m_node.createMbox(false);
                        PCVMActor newactor = new PCVMActor(m_scene, m_source, m_node, newmbox);

                        m_node.react(newactor);

                        OtpErlangObject[] v = new OtpErlangObject[3];
                        v[0] = sender;
                        v[1] = new OtpErlangAtom("ok");
                        v[2] = newmbox.Self;
                        reply = new OtpErlangTuple(v);
                    }
                }
                catch (Exception e)
                {
                    m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg());

                    OtpErlangObject[] v = new OtpErlangObject[3];
                    v[0] = sender;
                    v[1] = new OtpErlangAtom("error");
                    v[2] = new OtpErlangString(e.Message);
                    reply = new OtpErlangTuple(v);
                }
                finally
                {
                    if (sender != null)
                    {
                        m_mbox.send(sender, reply);
                    }
                }
            }
        }
示例#14
0
        public static String[] lookupNames(IPAddress address)
        {
            try
            {
                OtpOutputStream obuf = new OtpOutputStream();

                using (TcpClient s = new TcpClient(address.ToString(), EpmdPort.get()))
                {
                    obuf.write2BE(1);
                    obuf.write1(names4req);
                    // send request
                    obuf.WriteTo(s.GetStream());

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("-> NAMES (r4) ");
                    }

                    // get reply
                    byte[]       buffer = new byte[256];
                    MemoryStream ms     = new MemoryStream(256);
                    while (true)
                    {
                        int bytesRead = s.GetStream().Read(buffer, 0, buffer.Length);
                        if (bytesRead == -1)
                        {
                            break;
                        }
                        ms.Write(buffer, 0, bytesRead);
                    }
                    byte[]         tmpbuf = ms.GetBuffer();
                    OtpInputStream ibuf   = new OtpInputStream(tmpbuf, 0);
                    ibuf.read4BE(); // read port int
                    // int port = ibuf.read4BE();
                    // check if port = epmdPort

                    int    n   = tmpbuf.Length;
                    byte[] buf = new byte[n - 4];
                    Array.Copy(tmpbuf, 4, buf, 0, n - 4);
                    String all = OtpErlangString.newString(buf);
                    return(all.Split(new char[] { '\n' }));
                }
            }
            catch (SocketException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + address);
            }
            catch (IOException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding when requesting names");
            }
            catch (OtpErlangDecodeException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (invalid response)");
                }
                throw new IOException("Nameserver not responding when requesting names");
            }
        }
示例#15
0
        public static OtpErlangTuple Load(OtpMbox mbox, OtpErlangPid pid, string script)
        {
            OtpErlangObject body;
            OtpErlangBoolean debug = new OtpErlangBoolean(false);
            OtpErlangObject message;

            if (script.Length <= 65535)
            {
                body = new OtpErlangString(script);
            }
            else
            {
                body = new OtpErlangBinary(System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(script));
            }
            message = new OtpErlangTuple(new OtpErlangObject[] { mbox.Self, new OtpErlangAtom("load"), body, debug });

            mbox.send(pid, message);
            OtpErlangTuple reply = (OtpErlangTuple)mbox.receive();
            Console.WriteLine("Load: {0}", reply);

            return reply;
        }
示例#16
0
 /**
  * Read string data of len from stream
  */
 public string ReadStringData(int len, string encoding = "ISO-8859-1")
 {
     byte[] strbuf = ReadN(len);
     return(OtpErlangString.FromEncoding(strbuf, encoding));
 }
        /*
         * Send an auth error to peer because he sent a bad cookie. The auth error
         * uses his cookie (not revealing ours). This is just like send_reg
         * otherwise
         */
        private void cookieError(OtpLocalNode local, OtpErlangAtom cookie)
        {
            try
            {
                OtpOutputStream header = new OtpOutputStream(headerLen);

                // preamble: 4 byte length + "passthrough" tag + version
                header.write4BE(0); // reserve space for length
                header.write1(passThrough);
                header.write1(version);

                header.write_tuple_head(4);
                header.write_long(regSendTag);
                header.write_any(local.createPid()); // disposable pid
                header.write_atom(cookie.atomValue()); // important: his cookie,
                // not mine...
                header.write_atom("auth");

                // version for payload
                header.write1(version);

                // the payload

                // the no_auth message (copied from Erlang) Don't change this
                // (Erlang will crash)
                // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
                // [foo@aule]}}
                OtpErlangObject[] msg = new OtpErlangObject[2];
                OtpErlangObject[] msgbody = new OtpErlangObject[3];

                msgbody[0] = new OtpErlangAtom("print");
                msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n");

                // Erlang will crash and burn if there is no third argument here...
                msgbody[2] = new OtpErlangList(); // empty list

                msg[0] = new OtpErlangAtom("$gen_cast");
                msg[1] = new OtpErlangTuple(msgbody);

                OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg));

                // fix up length in preamble
                header.poke4BE(0, header.size() + payload.size() - 4);

                try
                {
                    do_send(header, payload);
                }
                catch (IOException)
                {
                } // ignore
            }
            finally
            {
                close();
            }
            throw new OtpAuthException("Remote cookie not authorized: " + cookie.atomValue());
        }