diff options
author | Carlos Alberto Cortez <calberto.cortez@gmail.com> | 2006-02-28 12:11:27 +0300 |
---|---|---|
committer | Carlos Alberto Cortez <calberto.cortez@gmail.com> | 2006-02-28 12:11:27 +0300 |
commit | cd35e907282abebeab30570bf8fd797e6e74f78b (patch) | |
tree | f4bfc0b3104bad543efb76755ea7bfc505b16356 /mcs | |
parent | bf06a9b5be67891dc18d365e8576e3eb572b33f8 (diff) |
2006-02-28 Carlos Alberto Cortez <calberto.cortez@gmail.com>
* SerialPort.cs:
* SerialPortStream.cs: Cleanups and some small funcionalities
added. Also, some code was moved to SerialPortStream, to have a
better design.
svn path=/trunk/mcs/; revision=57386
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/class/System/System.IO.Ports/ChangeLog | 7 | ||||
-rw-r--r-- | mcs/class/System/System.IO.Ports/SerialPort.cs | 293 | ||||
-rw-r--r-- | mcs/class/System/System.IO.Ports/SerialPortStream.cs | 224 |
3 files changed, 357 insertions, 167 deletions
diff --git a/mcs/class/System/System.IO.Ports/ChangeLog b/mcs/class/System/System.IO.Ports/ChangeLog index f50f309a5af..1ccf92bc504 100644 --- a/mcs/class/System/System.IO.Ports/ChangeLog +++ b/mcs/class/System/System.IO.Ports/ChangeLog @@ -1,3 +1,10 @@ +2006-02-28 Carlos Alberto Cortez <calberto.cortez@gmail.com> + + * SerialPort.cs: + * SerialPortStream.cs: Cleanups and some small funcionalities + added. Also, some code was moved to SerialPortStream, to have a + better design. + 2006-02-21 Carlos Alberto Cortez <calberto.cortez@gmail.com> * SerialPort.cs: diff --git a/mcs/class/System/System.IO.Ports/SerialPort.cs b/mcs/class/System/System.IO.Ports/SerialPort.cs index ca0035abc52..1360e544133 100644 --- a/mcs/class/System/System.IO.Ports/SerialPort.cs +++ b/mcs/class/System/System.IO.Ports/SerialPort.cs @@ -10,8 +10,9 @@ namespace System.IO.Ports { public class SerialPort /* : Component */ { - public const int InfiniteTimeout = -1; + const int DefaultReadBufferSize = 4096; + const int DefaultWriteBufferSize = 2048; bool isOpen = false; int baudRate = 9600; @@ -20,13 +21,20 @@ namespace System.IO.Ports Handshake handshake = Handshake.None; int dataBits = 8; bool breakState = false; - Stream baseStream; + SerialPortStream stream; Encoding encoding = Encoding.ASCII; string newLine = Environment.NewLine; string portName; - int unixFd; int readTimeout = InfiniteTimeout; int writeTimeout = InfiniteTimeout; + int readBufferSize = DefaultReadBufferSize; + int writeBufferSize = DefaultWriteBufferSize; + int readBufferOffset; + int readBufferLength; + int writeBufferOffset; + int writeBufferLength; + byte [] readBuffer; + byte [] writeBuffer; public SerialPort () { @@ -65,7 +73,8 @@ namespace System.IO.Ports this.dataBits = dataBits; } - public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) { + public SerialPort (string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits) + { this.portName = portName; this.baudRate = baudRate; this.parity = parity; @@ -73,22 +82,15 @@ namespace System.IO.Ports this.stopBits = stopBits; } - public Stream BaseStream - { + public Stream BaseStream { get { if (!isOpen) throw new InvalidOperationException (); - if (baseStream == null) - baseStream = new SerialPortStream (this); - - return baseStream; + return stream; } } - [DllImport("MonoPosixHelper")] - private static extern bool set_attributes (int unix_fd, int baud_rate, Parity parity, int dataBits, StopBits stopBits, Handshake handshake); - public int BaudRate { get { return baudRate; @@ -98,7 +100,8 @@ namespace System.IO.Ports throw new ArgumentOutOfRangeException ("value"); baudRate = value; - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); + if (isOpen) + stream.BaudRate = value; } } @@ -107,8 +110,7 @@ namespace System.IO.Ports return breakState; } set { - if (!isOpen) - throw new InvalidOperationException (); + CheckOpen (); if (value == breakState) return; // Do nothing. @@ -117,42 +119,30 @@ namespace System.IO.Ports } } - public int BytesToRead - { + public int BytesToRead { get { - if (!isOpen) - throw new InvalidOperationException (); - - throw new NotImplementedException (); + CheckOpen (); + return readBufferLength + stream.BytesToRead; } } - public int BytesToWrite - { + public int BytesToWrite { get { - if (!isOpen) - throw new InvalidOperationException (); - - throw new NotImplementedException (); + CheckOpen (); + return writeBufferLength + stream.BytesToWrite; } } - public bool CDHolding - { + public bool CDHolding { get { - if (!isOpen) - throw new InvalidOperationException (); - + CheckOpen (); throw new NotImplementedException (); } } - public bool CtsHolding - { + public bool CtsHolding { get { - if (!isOpen) - throw new InvalidOperationException (); - + CheckOpen (); throw new NotImplementedException (); } } @@ -166,39 +156,32 @@ namespace System.IO.Ports throw new ArgumentOutOfRangeException ("value"); dataBits = value; - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); + if (isOpen) + stream.DataBits = value; } } - public bool DiscardNull - { + public bool DiscardNull { get { - if (!isOpen) - throw new InvalidOperationException (); - + CheckOpen (); throw new NotImplementedException (); } set { - if (!isOpen) - throw new InvalidOperationException (); - + CheckOpen (); throw new NotImplementedException (); } } - public bool DsrHolding - { + public bool DsrHolding { get { - if (!isOpen) - throw new InvalidOperationException (); - + CheckOpen (); throw new NotImplementedException (); } } - public bool DtrEnable - { + public bool DtrEnable { get { + CheckOpen (); throw new NotImplementedException (); } } @@ -217,25 +200,19 @@ namespace System.IO.Ports public Handshake Handshake { get { - if (!isOpen) - throw new InvalidOperationException (); - return handshake; } set { - if (!isOpen) - throw new InvalidOperationException (); if (value < Handshake.None || value > Handshake.RequestToSendXOnXOff) throw new ArgumentOutOfRangeException ("value"); handshake = value; - - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); + if (isOpen) + stream.Handshake = value; } } - public bool IsOpen - { + public bool IsOpen { get { return isOpen; } @@ -255,24 +232,19 @@ namespace System.IO.Ports public Parity Parity { get { - if (!isOpen) - throw new InvalidOperationException (); - return parity; } set { - if (!isOpen) - throw new InvalidOperationException (); if (value < Parity.None || value > Parity.Space) throw new ArgumentOutOfRangeException ("value"); parity = value; - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); + if (isOpen) + stream.Parity = value; } } - public byte ParityReplace - { + public byte ParityReplace { get { throw new NotImplementedException (); } @@ -287,31 +259,33 @@ namespace System.IO.Ports } set { if (isOpen) - throw new InvalidOperationException (); + throw new InvalidOperationException ("Port name cannot be set while port is open."); if (value == null) throw new ArgumentNullException ("value"); - if (value.Length == 0 || value.StartsWith ("\\")) + if (value.Length == 0 || value.StartsWith ("\\\\")) throw new ArgumentException ("value"); - - throw new NotImplementedException (); + + portName = value; } } - public int ReadBufferSize - { + public int ReadBufferSize { get { - throw new NotImplementedException (); + return readBufferSize; } set { + if (isOpen) + throw new InvalidOperationException (); if (value <= 0) throw new ArgumentOutOfRangeException ("value"); + if (value <= DefaultReadBufferSize) + return; - throw new NotImplementedException (); + readBufferSize = value; } } - public int ReadTimeout - { + public int ReadTimeout { get { return readTimeout; } @@ -320,6 +294,8 @@ namespace System.IO.Ports throw new ArgumentOutOfRangeException ("value"); readTimeout = value; + /*if (isOpen) + stream.ReadTimeout = value;*/ } } @@ -335,12 +311,13 @@ namespace System.IO.Ports } } - public bool RtsEnable - { + public bool RtsEnable { get { + CheckOpen (); throw new NotImplementedException (); } set { + CheckOpen (); throw new NotImplementedException (); } } @@ -353,26 +330,29 @@ namespace System.IO.Ports if (value < StopBits.One || value > StopBits.OnePointFive) throw new ArgumentOutOfRangeException ("value"); - this.stopBits = value; - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); + stopBits = value; + if (isOpen) + stream.StopBits = value; } } - public int WriteBufferSize - { + public int WriteBufferSize { get { - throw new NotImplementedException (); + return writeBufferSize; } set { + if (isOpen) + throw new InvalidOperationException (); if (value <= 0) throw new ArgumentOutOfRangeException ("value"); + if (value <= DefaultWriteBufferSize) + return; - throw new NotImplementedException (); + writeBufferSize = value; } } - public int WriteTimeout - { + public int WriteTimeout { get { return writeTimeout; } @@ -381,70 +361,56 @@ namespace System.IO.Ports throw new ArgumentOutOfRangeException ("value"); writeTimeout = value; + /*if (isOpen) + stream.WriteTimeout = value;*/ } } // methods - [DllImport("MonoPosixHelper")] - private static extern void close_serial (int unixFd); public void Close () { - if (!isOpen) - return; - isOpen = false; - close_serial (unixFd); + if (stream != null) + stream.Close (); + + stream = null; + readBuffer = null; + writeBuffer = null; } - [DllImport("MonoPosixHelper")] - private static extern void discard_buffer (int unixFd, bool input_buffer); public void DiscardInBuffer () { - if (!isOpen) - throw new InvalidOperationException (); - discard_buffer (unixFd, true); + CheckOpen (); + stream.DiscardInputBuffer (); } public void DiscardOutBuffer () { - if (!isOpen) - throw new InvalidOperationException (); - discard_buffer (unixFd, false); + CheckOpen (); + stream.DiscardOutputBuffer (); } - [DllImport("MonoPosixHelper")] - private static extern string[] list_serial_devices (); - public static string[] GetPortNames() + public static string [] GetPortNames () { - return list_serial_devices (); + return new string [0]; // Return empty by now } - [DllImport("MonoPosixHelper")] - private static extern int open_serial (string portName); - public void Open () { - if (portName == null || portName.StartsWith ("\\\\")) - throw new ArgumentException (); - - unixFd = open_serial (portName); - if (unixFd == -1) - throw new IOException(); - - set_attributes (unixFd, baudRate, parity, dataBits, stopBits, handshake); - + if (isOpen) + throw new InvalidOperationException ("Port is already open"); + isOpen = true; + stream = new SerialPortStream (this); + readBuffer = new byte [readBufferSize]; + writeBuffer = new byte [writeBufferSize]; } - [DllImport("MonoPosixHelper")] - private static extern int read_serial (int unixFd, byte[] buffer, int offset, int count, int timeout); - public int Read (byte[] buffer, int offset, int count) { - if (!isOpen) - throw new InvalidOperationException (); + CheckOpen (); if (buffer == null) throw new ArgumentNullException ("buffer"); if (offset < 0 || offset >= buffer.Length) @@ -454,13 +420,27 @@ namespace System.IO.Ports if (count > buffer.Length - offset) throw new ArgumentException ("count > buffer.Length - offset"); - return read_serial (unixFd, buffer, offset, count, readTimeout); + if (readBufferLength <= 0) { + readBufferOffset = 0; + readBufferLength = stream.Read (readBuffer, 0, readBuffer.Length); + } + + if (readBufferLength == 0) + return 0; // No bytes left + + if (count > readBufferLength) + count = readBufferLength; // Update count if needed + + Buffer.BlockCopy (readBuffer, readBufferOffset, buffer, offset, count); + readBufferOffset += count; + readBufferLength -= count; + + return count; } public int Read (char[] buffer, int offset, int count) { - if (!isOpen) - throw new InvalidOperationException (); + CheckOpen (); if (buffer == null) throw new ArgumentNullException ("buffer"); if (offset < 0 || offset >= buffer.Length) @@ -471,16 +451,15 @@ namespace System.IO.Ports throw new ArgumentException ("count > buffer.Length - offset"); byte [] bytes = encoding.GetBytes (buffer, offset, count); - return read_serial (unixFd, bytes, 0, bytes.Length, readTimeout); + return Read (bytes, 0, bytes.Length); } - byte[] read_buffer = new byte[4096]; - public int ReadByte () { - if (Read (read_buffer, 0, 1) == 1) - return read_buffer [0]; - + byte [] buff = new byte [1]; + if (Read (buff, 0, 1) > 0) + return buff [0]; + return -1; } @@ -501,56 +480,54 @@ namespace System.IO.Ports public string ReadTo (string value) { + CheckOpen (); + if (value == null) + throw new ArgumentNullException ("value"); + if (value.Length == 0) + throw new ArgumentException ("value"); + throw new NotImplementedException (); } - [DllImport("MonoPosixHelper")] - private static extern void write_serial (int unixFd, byte[] buffer, int offset, int count, int timeout); - public void Write (string str) { + CheckOpen (); if (str == null) throw new ArgumentNullException ("str"); - if (!isOpen) - throw new InvalidOperationException ("Specified port is not open"); byte [] buffer = encoding.GetBytes (str); Write (buffer, 0, buffer.Length); } - public void Write (byte[] buffer, int offset, int count) + public void Write (byte [] buffer, int offset, int count) { + CheckOpen (); if (buffer == null) throw new ArgumentNullException ("buffer"); if (offset < 0 || offset >= buffer.Length) throw new ArgumentOutOfRangeException ("offset"); if (count < 0 || count > buffer.Length) throw new ArgumentOutOfRangeException ("count"); - if (offset + count > buffer.Length) - throw new ArgumentException ("offset+count > buffer.Length"); - - if (!isOpen) - throw new InvalidOperationException ("Specified port is not open"); - - write_serial (unixFd, buffer, offset, count, writeTimeout); + if (count > buffer.Length - offset) + throw new ArgumentException ("count > buffer.Length - offset"); + + stream.Write (buffer, offset, count); } - public void Write (char[] buffer, int offset, int count) + public void Write (char [] buffer, int offset, int count) { + CheckOpen (); if (buffer == null) throw new ArgumentNullException ("buffer"); if (offset < 0 || offset >= buffer.Length) throw new ArgumentOutOfRangeException ("offset"); if (count < 0 || count > buffer.Length) throw new ArgumentOutOfRangeException ("count"); - if (offset + count > buffer.Length) - throw new ArgumentException ("offset+count > buffer.Length"); + if (count > buffer.Length - offset) + throw new ArgumentException ("count > buffer.Length - offset"); - if (!isOpen) - throw new InvalidOperationException ("Specified port is not open"); - byte [] bytes = encoding.GetBytes (buffer, offset, count); - write_serial (unixFd, bytes, offset, count, writeTimeout); + stream.Write (bytes, 0, bytes.Length); } public void WriteLine (string str) @@ -558,6 +535,12 @@ namespace System.IO.Ports Write (str + newLine); } + void CheckOpen () + { + if (!isOpen) + throw new InvalidOperationException ("Specified port is not open."); + } + // events public delegate void SerialReceivedEventHandler (object sender, SerialReceivedEventArgs e); diff --git a/mcs/class/System/System.IO.Ports/SerialPortStream.cs b/mcs/class/System/System.IO.Ports/SerialPortStream.cs index ea6170ac07f..eb8fe896391 100644 --- a/mcs/class/System/System.IO.Ports/SerialPortStream.cs +++ b/mcs/class/System/System.IO.Ports/SerialPortStream.cs @@ -1,8 +1,9 @@ // -// System.IO.Ports.Handshake.cs +// System.IO.Ports.SerialPortStream.cs // // Authors: // Chris Toshok (toshok@ximian.com) +// Carlos Alberto Cortez (calberto.cortez@gmail.com) // // (c) Copyright 2006 Novell, Inc. (http://www.novell.com) // @@ -16,13 +17,37 @@ using System.Runtime.InteropServices; namespace System.IO.Ports { - class SerialPortStream : Stream + class SerialPortStream : Stream, IDisposable { - SerialPort port; + int fd; + int baudRate; + int dataBits; + Parity parity; + StopBits stopBits; + Handshake handshake; + int readTimeout; + int writeTimeout; + bool disposed; + + [DllImport ("MonoPosixHelper")] + static extern int open_serial (string portName); public SerialPortStream (SerialPort port) { - this.port = port; + fd = open_serial (port.PortName); + if (fd == -1) + throw new IOException (); + + readTimeout = port.ReadTimeout; + writeTimeout = port.WriteTimeout; + baudRate = port.BaudRate; + parity = port.Parity; + dataBits = port.DataBits; + stopBits = port.StopBits; + handshake = port.Handshake; + + if (!set_attributes (fd, port.BaudRate, port.Parity, port.DataBits, port.StopBits, port.Handshake)) + throw new IOException (); } public override bool CanRead { @@ -43,45 +68,220 @@ namespace System.IO.Ports } } + // Remove this comments as soon as these properties + // are added to System.IO.Stream + /* + public override bool CanTimeout { + get { + return true; + } + } + + public override int ReadTimeout { + get { + return readTimeout; + } + set { + if (value < 0 && value != SerialPort.InfiniteTimeout) + throw new ArgumentOutOfRangeException ("value"); + + readTimeout = value; + } + } + + public override int WriteTimeout { + get { + return writeTimeout; + } + set { + if (value < 0 && value != SerialPort.InfiniteTimeout) + throw new ArgumentOutOfRangeException ("value"); + + writeTimeout = value; + } + }*/ + public override long Length { get { - return -1; + throw new NotSupportedException (); } } public override long Position { get { - return -1; + throw new NotSupportedException (); } set { - throw new InvalidOperationException (); + throw new NotSupportedException (); } } public override void Flush () { - throw new NotImplementedException (); + // If used, this _could_ flush the serial port + // buffer (not the SerialPort class buffer) } + [DllImport ("MonoPosixHelper")] + static extern int read_serial (int fd, byte [] buffer, int offset, int count, int timeout); + public override int Read ([In,Out] byte[] buffer, int offset, int count) { - return port.Read (buffer, offset, count); + CheckDisposed (); + if (buffer == null) + throw new ArgumentNullException ("buffer"); + if (offset < 0 || offset >= buffer.Length) + throw new ArgumentOutOfRangeException ("offset"); + if (count < 0 || count > buffer.Length) + throw new ArgumentOutOfRangeException ("count"); + if (count > buffer.Length - offset) + throw new ArgumentException ("count > buffer.Length - offset"); + + return read_serial (fd, buffer, offset, count, readTimeout); } public override long Seek (long offset, SeekOrigin origin) { - throw new InvalidOperationException (); + throw new NotSupportedException (); } public override void SetLength (long value) { - throw new InvalidOperationException (); + throw new NotSupportedException (); } + [DllImport ("MonoPosixHelper")] + static extern void write_serial (int fd, byte [] buffer, int offset, int count, int timeout); + public override void Write (byte[] buffer, int offset, int count) { - port.Write (buffer, offset, count); + CheckDisposed (); + if (buffer == null) + throw new ArgumentNullException ("buffer"); + if (offset < 0 || offset >= buffer.Length) + throw new ArgumentOutOfRangeException ("offset"); + if (count < 0 || count > buffer.Length) + throw new ArgumentOutOfRangeException ("count"); + if (count > buffer.Length - offset) + throw new ArgumentException ("offset+count > buffer.Length"); + + write_serial (fd, buffer, offset, count, writeTimeout); + } + + protected void Dispose (bool disposing) + { + if (disposed) + return; + + disposed = true; + close_serial (fd); + } + + [DllImport ("MonoPosixHelper")] + static extern void close_serial (int fd); + + public override void Close () + { + ((IDisposable) this).Dispose (); + } + + void IDisposable.Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); } + + ~SerialPortStream () + { + Dispose (false); + } + + void CheckDisposed () + { + if (disposed) + throw new ObjectDisposedException (GetType ().FullName); + } + + [DllImport ("MonoPosixHelper")] + static extern bool set_attributes (int fd, int baudRate, Parity parity, int dataBits, StopBits stopBits, Handshake handshake); + + // FIXME - Separate baud rate from the other values, + // since it can be set individually + internal int BaudRate { + get { + return baudRate; + } + set { + baudRate = value; + set_attributes (fd, baudRate, parity, dataBits, stopBits, handshake); + } + } + + internal Parity Parity { + get { + return parity; + } + set { + parity = value; + set_attributes (fd, baudRate, parity, dataBits, stopBits, handshake); + } + } + + internal int DataBits { + get { + return dataBits; + } + set { + dataBits = value; + set_attributes (fd, baudRate, parity, dataBits, stopBits, handshake); + } + } + + internal StopBits StopBits { + get { + return stopBits; + } + set { + stopBits = stopBits; + set_attributes (fd, baudRate, parity, dataBits, stopBits, handshake); + } + } + + internal Handshake Handshake { + get { + return handshake; + } + set { + handshake = value; + set_attributes (fd, baudRate, parity, dataBits, stopBits, handshake); + } + } + + internal int BytesToRead { + get { + return 0; // Not implemented yet + } + } + + internal int BytesToWrite { + get { + return 0; // Not implemented yet + } + } + + [DllImport ("MonoPosixHelper")] + static extern void discard_buffer (int fd, bool inputBuffer); + + internal void DiscardInputBuffer () + { + discard_buffer (fd, true); + } + + internal void DiscardOutputBuffer () + { + discard_buffer (fd, false); + } + } } |