mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-09-13 12:43:17 +00:00
288 lines
11 KiB
C#
288 lines
11 KiB
C#
using Esiur.Net.IIP;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
using System.Xml.Schema;
|
|
using static Esiur.Data.Codec;
|
|
|
|
namespace Esiur.Data;
|
|
|
|
// Transmission Data Unit
|
|
public struct TDU
|
|
{
|
|
public TDUIdentifier Identifier;
|
|
//public int Index;
|
|
public TDUClass Class;
|
|
//public ulong ContentLength;
|
|
|
|
public byte[] Composed;
|
|
//public uint Offset;
|
|
|
|
public byte[] Metadata;
|
|
|
|
//public ulong Size
|
|
//{
|
|
// get
|
|
// {
|
|
// if (TotalSize != ulong.MaxValue)
|
|
// return TotalSize;
|
|
// else
|
|
// {
|
|
// if (ContentLength <= 0xFF)
|
|
// return 2 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF)
|
|
// return 3 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF_FF)
|
|
// return 4 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF_FF_FF)
|
|
// return 5 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF_FF_FF_FF)
|
|
// return 6 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF_FF_FF_FF_FF)
|
|
// return 7 + ContentLength;
|
|
// else if (ContentLength <= 0xFF_FF_FF_FF_FF_FF_FF)
|
|
// return 8 + ContentLength;
|
|
// else //if (ContentLength <= 0xFF_FF_FF_FF_FF_FF_FF_FF)
|
|
// return 9 + ContentLength;
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
//private ulong TotalSize;
|
|
|
|
public TDU()
|
|
{
|
|
|
|
}
|
|
|
|
public TDU(TDUIdentifier identifier)
|
|
{
|
|
Identifier = identifier;
|
|
}
|
|
|
|
public TDU(TDUIdentifier identifier,
|
|
byte[] data, ulong length, byte[] metadata = null)
|
|
{
|
|
Identifier = identifier;
|
|
//Index = (byte)identifier & 0x7;
|
|
Class = (TDUClass)((byte)identifier >> 6);
|
|
Metadata = metadata;
|
|
|
|
|
|
if (Class == TDUClass.Fixed)
|
|
{
|
|
Composed = DC.Combine(new byte[] { (byte)Identifier }, 0, 1, data, 0, (uint)length);
|
|
}
|
|
else if (Class == TDUClass.Dynamic
|
|
|| Class == TDUClass.Extension)
|
|
{
|
|
|
|
if (length == 0)
|
|
{
|
|
Composed = new byte[1] { (byte)Identifier };
|
|
}
|
|
else if (length <= 0xFF)
|
|
{
|
|
Composed = new byte[2 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x8);
|
|
Composed[1] = (byte)length;
|
|
Buffer.BlockCopy(data, 0, Composed, 2, (int)length);
|
|
}
|
|
else if (length <= 0xFF_FF)
|
|
{
|
|
var Composed = new byte[3 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x10);
|
|
Composed[1] = (byte)((length >> 8) & 0xFF);
|
|
Composed[2] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 3, (int)length);
|
|
}
|
|
else if (length <= 0xFF_FF_FF)
|
|
{
|
|
Composed = new byte[4 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x18);
|
|
Composed[1] = (byte)((length >> 16) & 0xFF);
|
|
Composed[2] = (byte)((length >> 8) & 0xFF);
|
|
Composed[3] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 4, (int)length);
|
|
}
|
|
else if (length <= 0xFF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[5 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x20);
|
|
Composed[1] = (byte)((length >> 24) & 0xFF);
|
|
Composed[2] = (byte)((length >> 16) & 0xFF);
|
|
Composed[3] = (byte)((length >> 8) & 0xFF);
|
|
Composed[4] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 5, (int)length);
|
|
}
|
|
else if (length <= 0xFF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[6 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x28);
|
|
Composed[1] = (byte)((length >> 32) & 0xFF);
|
|
Composed[2] = (byte)((length >> 24) & 0xFF);
|
|
Composed[3] = (byte)((length >> 16) & 0xFF);
|
|
Composed[4] = (byte)((length >> 8) & 0xFF);
|
|
Composed[5] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 6, (int)length);
|
|
}
|
|
else if (length <= 0xFF_FF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[7 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x30);
|
|
Composed[1] = (byte)((length >> 40) & 0xFF);
|
|
Composed[2] = (byte)((length >> 32) & 0xFF);
|
|
Composed[3] = (byte)((length >> 24) & 0xFF);
|
|
Composed[4] = (byte)((length >> 16) & 0xFF);
|
|
Composed[5] = (byte)((length >> 8) & 0xFF);
|
|
Composed[6] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 7, (int)length);
|
|
}
|
|
else //if (len <= 0xFF_FF_FF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[8 + length];
|
|
Composed[0] = (byte)((byte)Identifier | 0x38);
|
|
Composed[1] = (byte)((length >> 48) & 0xFF);
|
|
Composed[2] = (byte)((length >> 40) & 0xFF);
|
|
Composed[3] = (byte)((length >> 32) & 0xFF);
|
|
Composed[4] = (byte)((length >> 24) & 0xFF);
|
|
Composed[5] = (byte)((length >> 16) & 0xFF);
|
|
Composed[6] = (byte)((length >> 8) & 0xFF);
|
|
Composed[7] = (byte)(length & 0xFF);
|
|
Buffer.BlockCopy(data, 0, Composed, 8, (int)length);
|
|
}
|
|
}
|
|
else if (Class == TDUClass.Typed)
|
|
{
|
|
if (metadata == null)
|
|
throw new Exception("Metadata must be provided for types.");
|
|
|
|
|
|
if (metadata.Length > 0xFF)
|
|
throw new Exception("Metadata can't exceed 255 bytes in length.");
|
|
|
|
var metaLen = (byte)metadata.Length;
|
|
|
|
var len = 1 + (ulong)metaLen + length;
|
|
|
|
|
|
if (length == 0)
|
|
{
|
|
Composed = new byte[1] { (byte)Identifier };
|
|
}
|
|
else if (metadata.Length > 0xFF)
|
|
{
|
|
throw new Exception("Metadata can't exceed 255 bytes in length.");
|
|
}
|
|
else if (length <= 0xFF)
|
|
{
|
|
Composed = new byte[2 + len];
|
|
Composed[0] = (byte)((byte)Identifier | 0x8);
|
|
Composed[1] = (byte)len;
|
|
Composed[2] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 3, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 3 + metaLen, (int)length);
|
|
}
|
|
else if (len <= 0xFF_FF)
|
|
{
|
|
Composed = new byte[3 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x10);
|
|
Composed[1] = (byte)((len >> 8) & 0xFF);
|
|
Composed[2] = (byte)(len & 0xFF);
|
|
Composed[3] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 4, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 4 + metaLen, (int)length);
|
|
}
|
|
else if (len <= 0xFF_FF_FF)
|
|
{
|
|
Composed = new byte[4 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x18);
|
|
Composed[1] = (byte)((len >> 16) & 0xFF);
|
|
Composed[2] = (byte)((len >> 8) & 0xFF);
|
|
Composed[3] = (byte)(len & 0xFF);
|
|
Composed[4] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 5, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 5 + metaLen, (int)length);
|
|
|
|
}
|
|
else if (len <= 0xFF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[5 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x20);
|
|
Composed[1] = (byte)((len >> 24) & 0xFF);
|
|
Composed[2] = (byte)((len >> 16) & 0xFF);
|
|
Composed[3] = (byte)((len >> 8) & 0xFF);
|
|
Composed[4] = (byte)(len & 0xFF);
|
|
Composed[5] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 6, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 6 + metaLen, (int)length);
|
|
}
|
|
else if (len <= 0xFF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[6 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x28);
|
|
Composed[1] = (byte)((len >> 32) & 0xFF);
|
|
Composed[2] = (byte)((len >> 24) & 0xFF);
|
|
Composed[3] = (byte)((len >> 16) & 0xFF);
|
|
Composed[4] = (byte)((len >> 8) & 0xFF);
|
|
Composed[5] = (byte)(len & 0xFF);
|
|
Composed[6] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 7, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 7 + metaLen, (int)length);
|
|
}
|
|
else if (len <= 0xFF_FF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[7 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x30);
|
|
Composed[1] = (byte)((len >> 40) & 0xFF);
|
|
Composed[2] = (byte)((len >> 32) & 0xFF);
|
|
Composed[3] = (byte)((len >> 24) & 0xFF);
|
|
Composed[4] = (byte)((len >> 16) & 0xFF);
|
|
Composed[5] = (byte)((len >> 8) & 0xFF);
|
|
Composed[6] = (byte)(len & 0xFF);
|
|
Composed[7] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 8, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 8 + metaLen, (int)length);
|
|
}
|
|
else //if (len <= 0xFF_FF_FF_FF_FF_FF_FF)
|
|
{
|
|
Composed = new byte[8 + len];
|
|
Composed[0] = (byte)((byte)identifier | 0x38);
|
|
Composed[1] = (byte)((len >> 48) & 0xFF);
|
|
Composed[2] = (byte)((len >> 40) & 0xFF);
|
|
Composed[3] = (byte)((len >> 32) & 0xFF);
|
|
Composed[4] = (byte)((len >> 24) & 0xFF);
|
|
Composed[5] = (byte)((len >> 16) & 0xFF);
|
|
Composed[6] = (byte)((len >> 8) & 0xFF);
|
|
Composed[7] = (byte)(len & 0xFF);
|
|
Composed[8] = metaLen;
|
|
|
|
Buffer.BlockCopy(metadata, 0, Composed, 9, metaLen);
|
|
Buffer.BlockCopy(data, 0, Composed, 9 + metaLen, (int)length);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public bool MatchType(TDU with)
|
|
{
|
|
if (Identifier != with.Identifier)
|
|
return false;
|
|
|
|
if (Class == TDUClass.Typed)
|
|
if (!Metadata.SequenceEqual(with.Metadata))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
}
|