using System; using System.Runtime.Serialization; using System.Net.Sockets; using System.IO; using System.Diagnostics.CodeAnalysis; //using Util; namespace lib { public interface IFormatter { // // Summary: // Gets or sets the System.Runtime.Serialization.SerializationBinder that performs // type lookups during deserialization. // // Returns: // The System.Runtime.Serialization.SerializationBinder that performs type lookups // during deserialization. SerializationBinder? Binder { get; set; } // // Summary: // Gets or sets the System.Runtime.Serialization.StreamingContext used for serialization // and deserialization. // // Returns: // The System.Runtime.Serialization.StreamingContext used for serialization and // deserialization. StreamingContext Context { get; set; } // // Summary: // Gets or sets the System.Runtime.Serialization.SurrogateSelector used by the current // formatter. // // Returns: // The System.Runtime.Serialization.SurrogateSelector used by this formatter. ISurrogateSelector? SurrogateSelector { get; set; } // // Summary: // Deserializes the data on the provided stream and reconstitutes the graph of objects. // // // Parameters: // serializationStream: // The stream that contains the data to deserialize. // // Returns: // The top object of the deserialized graph. [RequiresDynamicCode("BinaryFormatter serialization uses dynamic code generation, the type of objects being processed cannot be statically discovered.")] [RequiresUnreferencedCode("BinaryFormatter serialization is not trim compatible because the type of objects being processed cannot be statically discovered.")] object Deserialize(Stream serializationStream); // // Summary: // Serializes an object, or graph of objects with the given root to the provided // stream. // // Parameters: // serializationStream: // The stream where the formatter puts the serialized data. This stream can reference // a variety of backing stores (such as files, network, memory, and so on). // // graph: // The object, or root of the object graph, to serialize. All child objects of this // root object are automatically serialized. [RequiresUnreferencedCode("BinaryFormatter serialization is not trim compatible because the type of objects being processed cannot be statically discovered.")] void Serialize(Stream serializationStream, object graph); } public interface IProcess { void process( object obj ); } public interface ISerDes where T : IFormatter { T getInstance(); } public class NewEveryCall: ISerDes where T : IFormatter, new() { public T getInstance() { return new T(); } } public class Conn { public static int BufferSize = 2048; } public class Conn : Conn where T : IFormatter, new() where TInst : ISerDes, new() { public Socket Sock { get { return m_socket; } } public Stream Stream { get { return m_streamNet; } } private TInst m_formatter = new TInst(); public Conn( Socket sock, IProcess proc ) { m_socket = sock; sock.NoDelay = true; m_streamNet = new NetworkStream( m_socket ); m_proc = proc; } public object recieveObject() { return recieveObject( Stream ); } public object recieveObject( Stream stream ) { object obj = null; var formatter = m_formatter.getInstance(); try { obj = formatter.Deserialize( stream ); } catch( System.Xml.XmlException ex ) { log.error( $"Outer Exception {ex.Message}" ); } return obj; } public void send( object obj ) { var formatter = m_formatter.getInstance(); try { var ms = new MemoryStream( BufferSize ); formatter.Serialize( ms, obj ); //var str = System.Text.Encoding.Default.GetString( mm_buffer, 0, (int)ms.Position ); //log.info( $"Sent data {str} of length {ms.Position}" ); //log.info( $"Sent {obj}" ); byte[] byteSize = BitConverter.GetBytes( (uint)ms.Position ); m_streamNet.Write( byteSize, 0, 4 ); m_streamNet.Write( ms.GetBuffer(), 0, (int)ms.Position ); m_streamNet.Flush(); } catch( Exception e ) { log.warn( $"Exception sending obj {obj} of {e}" ); throw; } } public virtual void recieve( object obj ) { if( m_proc != null ) m_proc.process( obj ); } Socket m_socket; NetworkStream m_streamNet; IProcess m_proc; //private BufferedStream m_streamBufIn; //private BufferedStream m_streamBufOut; } }