2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2026-06-13 22:48:42 +00:00
This commit is contained in:
2026-05-24 18:27:22 +03:00
parent a6e8bed31d
commit eb323e8bf8
69 changed files with 6532 additions and 3371 deletions
+346 -16
View File
@@ -1,4 +1,7 @@
using System;
using Esiur.Core;
using Esiur.Protocol;
using Esiur.Resource;
using System;
using System.Collections.Generic;
using System.Text;
@@ -9,16 +12,22 @@ namespace Esiur.Data
public TduIdentifier Identifier;
public int Index;
public TduClass Class;
public uint Offset;
public ulong ContentLength;
public uint PayloadOffset;
public ulong PayloadLength;
public byte[] Data;
public byte Exponent;
public ulong TotalLength;
public byte[] Metadata;
public Tru Metadata;
public uint Ends;
public static ParsedTdu Parse(byte[] data, uint offset, uint ends)
public static AsyncReply<ParsedTdu> ParseAsync(byte[] data, EpConnection connection)
{
return ParseAsync(data, (uint)0, (uint)data.Length, connection);
}
public static async AsyncReply<ParsedTdu> ParseAsync(byte[] data, uint offset, uint ends, EpConnection connection)
{
// @TODO: add protection against memory allocation attacks by checking the length of the data before parsing it.
var h = data[offset++];
@@ -33,11 +42,11 @@ namespace Esiur.Data
{
Identifier = (TduIdentifier)h,
Data = data,
Offset = offset,
PayloadOffset = offset,
Class = cls,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
ContentLength = 0,
PayloadLength = 0,
TotalLength = 1,
Ends = ends
};
@@ -57,9 +66,9 @@ namespace Esiur.Data
{
Identifier = (TduIdentifier)h,
Data = data,
Offset = offset,
PayloadOffset = offset,
Class = cls,
ContentLength = cl,
PayloadLength = cl,
TotalLength = 1 + cl,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
@@ -89,20 +98,22 @@ namespace Esiur.Data
Class = TduClass.Invalid,
};
var metaData = DC.Clip(data, offset + 1, data[offset]);
offset += data[offset] + (uint)1;
//var metaData = DC.Clip(data, offset + 1, data[offset]);
//offset += data[offset] + (uint)1;
var metaDataTru = await Tru.ParseAsync(data, offset, connection, null);
offset += metaDataTru.Size;
return new ParsedTdu()
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
Offset = offset,
PayloadOffset = offset,
Class = cls,
ContentLength = cl - 1 - (uint)metaData.Length,
PayloadLength = cl - metaDataTru.Size,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Metadata = metaData,
Metadata = metaDataTru.Value,
Ends = ends
};
}
@@ -135,9 +146,9 @@ namespace Esiur.Data
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
Offset = offset,
PayloadOffset = offset,
Class = cls,
ContentLength = cl,
PayloadLength = cl,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Ends = ends
@@ -145,5 +156,324 @@ namespace Esiur.Data
}
}
public static object Parse(byte[] data, uint offset, uint ends, EpConnection connection)
{
// @TODO: add protection against memory allocation attacks by checking the length of the data before parsing it.
var h = data[offset++];
var cls = (TduClass)(h >> 6);
if (cls == TduClass.Fixed)
{
var exp = (h & 0x38) >> 3;
if (exp == 0)
return new ParsedTdu()
{
Identifier = (TduIdentifier)h,
Data = data,
PayloadOffset = offset,
Class = cls,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
PayloadLength = 0,
TotalLength = 1,
Ends = ends
};
ulong cl = (ulong)(1 << (exp - 1));
if (ends - offset < cl)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cl - (ends - offset))
};
//offset += (uint)cl;
return new ParsedTdu()
{
Identifier = (TduIdentifier)h,
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl,
TotalLength = 1 + cl,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
Ends = ends
};
}
else if (cls == TduClass.Typed)
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
for (uint i = 0; i < cll; i++)
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return new ParsedTdu()
{
TotalLength = (cl - (ends - offset)),
Class = TduClass.Invalid,
};
//var metaData = DC.Clip(data, offset + 1, data[offset]);
//offset += data[offset] + (uint)1;
var rt = new AsyncReply<ParsedTdu>();
Tru.ParseAsync(data, offset, connection, null).Then(metaDataTru =>
{
offset += metaDataTru.Size;
rt.Trigger(new ParsedTdu()
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl - metaDataTru.Size,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Metadata = metaDataTru.Value,
Ends = ends
});
});
return rt;
}
else
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
for (uint i = 0; i < cll; i++)
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cl - (ends - offset))
};
return
new ParsedTdu()
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Ends = ends
};
}
}
public static byte[] ClipTduData(byte[] data, uint offset, uint ends)
{
var oOffset = (int)offset;
var h = data[offset++];
var cls = (TduClass)(h >> 6);
if (cls == TduClass.Fixed)
{
var exp = (h & 0x38) >> 3;
if (exp == 0)
{
return new byte[] { h };
}
ulong cl = (ulong)(1 << (exp - 1));
if (ends - offset < cl)
{
return null; // failded
}
var rt = new byte[1 + cl];
Buffer.BlockCopy(data, oOffset, rt, 0, (int)cl);
return rt;
}
else
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return null;
ulong cl = 0;
for (uint i = 0; i < cll; i++)
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return null;
var rt = new byte[1 + cll + cl];
Buffer.BlockCopy(data, oOffset, rt, 0, rt.Length);
return rt;
}
}
public static ParsedTdu ParseSync(byte[] data, uint offset, uint ends, Warehouse warehouse)
{
// @TODO: add protection against memory allocation attacks by checking the length of the data before parsing it.
var h = data[offset++];
var cls = (TduClass)(h >> 6);
if (cls == TduClass.Fixed)
{
var exp = (h & 0x38) >> 3;
if (exp == 0)
return new ParsedTdu()
{
Identifier = (TduIdentifier)h,
Data = data,
PayloadOffset = offset,
Class = cls,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
PayloadLength = 0,
TotalLength = 1,
Ends = ends
};
ulong cl = (ulong)(1 << (exp - 1));
if (ends - offset < cl)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cl - (ends - offset))
};
//offset += (uint)cl;
return new ParsedTdu()
{
Identifier = (TduIdentifier)h,
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl,
TotalLength = 1 + cl,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
Ends = ends
};
}
else if (cls == TduClass.Typed)
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
for (uint i = 0; i < cll; i++)
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return new ParsedTdu()
{
TotalLength = (cl - (ends - offset)),
Class = TduClass.Invalid,
};
//var metaData = DC.Clip(data, offset + 1, data[offset]);
//offset += data[offset] + (uint)1;
var metaDataTru = Tru.Parse(data, offset, warehouse);
offset += metaDataTru.Size;
return new ParsedTdu()
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl - metaDataTru.Size,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Metadata = metaDataTru.Value,
Ends = ends
};
}
else
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
for (uint i = 0; i < cll; i++)
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return new ParsedTdu()
{
Class = TduClass.Invalid,
TotalLength = (cl - (ends - offset))
};
return
new ParsedTdu()
{
Identifier = (TduIdentifier)(h & 0xC7),
Data = data,
PayloadOffset = offset,
Class = cls,
PayloadLength = cl,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Ends = ends
};
}
}
}
}