using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; namespace Modbus.IO { internal abstract class CrossPlatformUdpClient : IDisposable { private UdpClient _udpClient; public CrossPlatformUdpClient(UdpClient udpClient) { if (udpClient == null) throw new ArgumentNullException("udpClient"); _udpClient = udpClient; } public abstract int ReadTimeout { get; set; } public abstract int WriteTimeout { get; set; } protected UdpClient UdpClient { get { return _udpClient; } } protected List Buffer { get; set; } public static CrossPlatformUdpClient Create(UdpClient udpClient) { #if WindowsCE return new CompactUdpClient(udpClient); #else return new FullUdpClient(udpClient); #endif } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } internal int Read(byte[] buffer, int offset, int count) { if (Buffer == null || Buffer.Count == 0) Buffer = Read(); if (Buffer.Count < count) throw new IOException("Not enough bytes in the datagram."); Buffer.CopyTo(0, buffer, offset, count); Buffer.RemoveRange(0, count); return count; } /// /// This method facilitates unit testing. /// internal virtual List Read() { IPEndPoint remoteIpEndPoint = null; return new List(UdpClient.Receive(ref remoteIpEndPoint)); } internal void Write(byte[] buffer, int count) { if (buffer == null) throw new ArgumentNullException("buffer"); if (count > buffer.Length) throw new ArgumentOutOfRangeException("count", "Argument count cannot be greater than the length of buffer."); UdpClient.Send(buffer, count); } /// /// Releases unmanaged and - optionally - managed resources /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (disposing) { if (_udpClient != null) { _udpClient.Close(); _udpClient = null; } } } } }