Iron Python: the output stream.

I needed to embed IronPython in my Second Messenger project. So i wrote a small interactive console looking like this:

Python Console

where in the upper section i write my code and sending the output stream on the bottom section.

So i wrote the following class:

    class MyPythonStream : Stream
    {
        #region unsupported Read + Seek members
        public override bool CanRead
        {
            get { return false; }
        }
        public override bool CanSeek
        {
            get { return false; }
        }
        public override bool CanWrite
        {
            get { return true; }
        }
        public override void Flush()
        {
            // ...
        }
        public override long Length
        {
            get { throw new NotSupportedException("Seek not supported"); } // can't seek
        }
        public override long Position
        {
            get
            {
                throw new NotSupportedException("Seek not supported");  // can't seek
            }
            set
            {
                throw new NotSupportedException("Seek not supported");  // can't seek
            }
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException("Reed not supported"); // can't read
        }
        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotSupportedException("Seek not supported"); // can't seek
        }
        public override void SetLength(long value)
        {
            throw new NotSupportedException("Seek not supported"); // can't seek
        }
        #endregion
        public override void Write(byte[] buffer, int offset, int count)
        {
            // Very bad hack: Ignore single newline char. This is because we expect the newline is following
            // previous content and we already placed a newline on that.
            if (count == 1 && buffer[offset] == '\n')
                return;
            // Code update from ShawnFa to fix case for '\r'
            StringBuilder sb = new StringBuilder();
            while (count > 0)
            {
                char ch = (char)buffer[offset]; if (ch == '\n')
                {
                    OnWrite(sb.ToString());
                    sb.Length = 0; // reset.
                }
                else if (ch != '\r')
                {
                    sb.Append(ch);
                }
                offset++;
                count--;
            }
            // Dump remainder. @todo - need some sort of "Write" to avoid adding extra newline.
            if (sb.Length > 0)
                OnWrite(sb.ToString());
        }
		public delegate void OnWriteCallback(string s);
		public OnWriteCallback OnWrite;
    }

This class allows you to add your own custom OnWriteCallback according to the delegate definition: public delegate void OnWriteCallback(string s);

I finally added an instance of the class to my code:

PythonEngine engine;
MyPythonStream myOut;
// Creating the engine
engine = new PythonEngine( );
// Creating the stream
myOut = new MyPythonStream();
myOut.OnWrite = new MyPythonStream.OnWriteCallback(Python_OnWrite);
// Setting the output streams
engine.SetStandardOutput(myOut);
engine.SetStandardError(myOut);

where my callback looks like:

public void Python_OnWrite(string s) {
  this.textview2.Buffer.Text += s +"\n"; // Gtk# textview output
}

Now I can write my python code:

a = [ 'a', 123, 5.0 ]
for x in a:
    print x

and executing it:

Executing Python…

Tags: ,

Comments are closed.


 
Roberto Rocco Angeloni is proudly powered by WordPress
Entries (RSS) and Comments (RSS).