Initial commit

Initial commit til Git.
V2 er deployed
This commit is contained in:
2026-06-13 17:31:50 +02:00
parent 9fcd2b145e
commit 41e23b6184
375 changed files with 15956 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ESCPOS_NET.Utils
{
public static class Consts
{
public static readonly string LIBNAME = "ESCPOS_NET";
}
}

View File

@@ -0,0 +1,185 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Concurrent;
namespace ESCPOS_NET.Utils
{
public class EchoStream : Stream
{
public override bool CanTimeout { get; } = true;
public override int ReadTimeout { get; set; } = Timeout.Infinite;
public override int WriteTimeout { get; set; } = Timeout.Infinite;
public override bool CanRead { get; } = true;
public override bool CanSeek { get; } = false;
public override bool CanWrite { get; } = true;
public bool CopyBufferOnWrite { get; set; } = false;
private readonly object _lock = new object();
// Default underlying mechanism for BlockingCollection is ConcurrentQueue<T>, which is what we want
private readonly BlockingCollection<byte[]> _Buffers;
private int _maxQueueDepth = 10;
private byte[] m_buffer = null;
private int m_offset = 0;
private int m_count = 0;
private bool m_Closed = false;
public override void Close()
{
m_Closed = true;
// release any waiting writes
_Buffers.CompleteAdding();
}
public bool DataAvailable
{
get
{
return _Buffers.Count > 0;
}
}
private long _Length = 0L;
public override long Length
{
get
{
return _Length;
}
}
private long _Position = 0L;
public override long Position
{
get
{
return _Position;
}
set
{
throw new NotImplementedException();
}
}
public EchoStream() : this(10)
{
}
public EchoStream(int maxQueueDepth)
{
_maxQueueDepth = maxQueueDepth;
_Buffers = new BlockingCollection<byte[]>(_maxQueueDepth);
}
// we override the xxxxAsync functions because the default base class shares state between ReadAsync and WriteAsync, which causes a hang if both are called at once
public new Task WriteAsync(byte[] buffer, int offset, int count)
{
return Task.Run(() => Write(buffer, offset, count));
}
// we override the xxxxAsync functions because the default base class shares state between ReadAsync and WriteAsync, which causes a hang if both are called at once
public new Task<int> ReadAsync(byte[] buffer, int offset, int count)
{
return Task.Run(() =>
{
return Read(buffer, offset, count);
});
}
public override void Write(byte[] buffer, int offset, int count)
{
if (m_Closed || buffer.Length - offset < count || count <= 0)
return;
byte[] newBuffer;
if (!CopyBufferOnWrite && offset == 0 && count == buffer.Length)
newBuffer = buffer;
else
{
newBuffer = new byte[count];
System.Buffer.BlockCopy(buffer, offset, newBuffer, 0, count);
}
if (!_Buffers.TryAdd(newBuffer, WriteTimeout))
throw new TimeoutException("EchoStream Write() Timeout");
_Length += count;
}
public override int Read(byte[] buffer, int offset, int count)
{
if (count == 0)
return 0;
lock (_lock)
{
if (m_count == 0 && _Buffers.Count == 0)
{
if (m_Closed)
return -1;
if (_Buffers.TryTake(out m_buffer, ReadTimeout))
{
m_offset = 0;
m_count = m_buffer.Length;
}
else
return m_Closed ? -1 : 0;
}
int returnBytes = 0;
while (count > 0)
{
if (m_count == 0)
{
if (_Buffers.TryTake(out m_buffer, 0))
{
m_offset = 0;
m_count = m_buffer.Length;
}
else
break;
}
var bytesToCopy = (count < m_count) ? count : m_count;
System.Buffer.BlockCopy(m_buffer, m_offset, buffer, offset, bytesToCopy);
m_offset += bytesToCopy;
m_count -= bytesToCopy;
offset += bytesToCopy;
count -= bytesToCopy;
returnBytes += bytesToCopy;
}
_Position += returnBytes;
return returnBytes;
}
}
public override int ReadByte()
{
byte[] returnValue = new byte[1];
return (Read(returnValue, 0, 1) <= 0 ? -1 : (int)returnValue[0]);
}
public override void Flush()
{
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.IO;
namespace ESCPOS_NET
{
public class InterceptableWriteMemoryStream : Stream
{
private MemoryStream _innerStream = new MemoryStream();
public override bool CanRead => _innerStream.CanRead;
public override bool CanSeek => _innerStream.CanSeek;
public override bool CanWrite => _innerStream.CanWrite;
public override long Length => _innerStream.Length;
public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; }
private Action<byte[]> _writeAction { get; set; }
public InterceptableWriteMemoryStream(Action<byte[]> writeAction)
{
_writeAction = writeAction;
}
public override void Flush()
{
_innerStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _innerStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _innerStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
_innerStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
var writeArray = new byte[count];
Buffer.BlockCopy(buffer, offset, writeArray, 0, count);
_writeAction(writeArray);
}
}
}

View File

@@ -0,0 +1,59 @@
using ESCPOS_NET.Utils;
using SimpleTcp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ESCPOS_NET
{
public class TCPConnection
{
public Stream ReadStream { get; private set; } = new EchoStream();
public Stream WriteStream { get; private set; }
public event EventHandler<ClientConnectedEventArgs> Connected;
public event EventHandler<ClientDisconnectedEventArgs> Disconnected;
public bool IsConnected => _client?.IsConnected ?? false;
private SimpleTcpClient _client;
//public event EventHandler<DataReceivedEventArgs> DataReceived;
public TCPConnection(string destination)
{
_client = new SimpleTcpClient(destination);
_client.Events.Connected += ConnectedEventHandler;
_client.Events.Disconnected += DisconnectedEventHandler;
_client.Events.DataReceived += DataReceivedEventHandler;
_client.Keepalive = new SimpleTcpKeepaliveSettings() { EnableTcpKeepAlives = true, TcpKeepAliveInterval = 1, TcpKeepAliveTime = 1, TcpKeepAliveRetryCount = 3 };
ReadStream.ReadTimeout = 1500;
WriteStream = new InterceptableWriteMemoryStream(bytes => _client.Send(bytes));
}
private void ConnectedEventHandler(object sender, ClientConnectedEventArgs e)
{
Connected?.Invoke(sender, e);
}
private void DisconnectedEventHandler(object sender, ClientDisconnectedEventArgs e)
{
Disconnected?.Invoke(sender, e);
}
private void DataReceivedEventHandler(object sender, DataReceivedEventArgs e)
{
ReadStream.Write(e.Data, 0, e.Data.Length);
}
public void ConnectWithRetries(int timeoutMs)
{
_client.ConnectWithRetries(timeoutMs);
}
~TCPConnection()
{
try
{
_client.Events.DataReceived -= DataReceivedEventHandler;
_client.Events.Connected -= ConnectedEventHandler;
_client.Events.Disconnected -= DisconnectedEventHandler;
_client?.Dispose();
}
catch { }
}
}
}