2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-10-29 15:20:29 +00:00
This commit is contained in:
2025-10-15 17:34:18 +03:00
parent 9386cc7a84
commit a63a9b5511
11 changed files with 477 additions and 172 deletions

View File

@@ -189,42 +189,53 @@ public static class Codec
/// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param>
/// <param name="dataType">DataType, in case the data is not prepended with DataType</param>
/// <returns>Value</returns>
public static (uint, object) ParseAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, ParsedTDU? dataType = null)
public static (uint, object) ParseAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)
{
uint len = 0;
if (dataType == null)
var tdu = ParsedTDU.Parse(data, offset, (uint)data.Length);
if (tdu.Class == TDUClass.Invalid)
throw new NullReferenceException("DataType can't be parsed.");
if (tdu.Class == TDUClass.Fixed)
{
(var longLen, dataType) = ParsedTDU.Parse(data, offset, (uint)data.Length);
if (dataType == null)
throw new NullReferenceException("DataType can't be parsed.");
len = (uint)longLen;
offset = dataType.Value.Offset;
return ((uint)tdu.TotalLength, FixedAsyncParsers[tdu.Exponent][tdu.Index](tdu, connection, requestSequence));
}
else
len = (uint)dataType.Value.ContentLength;
var tt = dataType.Value;
//Console.WriteLine("Parsing " + tt.Class + " " + tt.Identifier);
if (tt.Class == TDUClass.Fixed)
else if (tdu.Class == TDUClass.Dynamic)
{
return (len, FixedAsyncParsers[tt.Exponent][tt.Index](tt, connection, requestSequence));
return ((uint)tdu.TotalLength, DynamicAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
else if (tt.Class == TDUClass.Dynamic)
else if (tdu.Class == TDUClass.Typed)
{
return (len, DynamicAsyncParsers[tt.Index](tt, connection, requestSequence));
return ((uint)tdu.TotalLength, TypedAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
else if (tt.Class == TDUClass.Typed)
else // if (tt.Class == TDUClass.Extension)
{
return (len, TypedAsyncParsers[tt.Index](tt, connection, requestSequence));
return ((uint)tdu.TotalLength, ExtendedAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
else if (tt.Class == TDUClass.Extension)
}
public static (uint, object) ParseAsync(ParsedTDU tdu, DistributedConnection connection, uint[] requestSequence)
{
if (tdu.Class == TDUClass.Invalid)
throw new NullReferenceException("DataType can't be parsed.");
if (tdu.Class == TDUClass.Fixed)
{
return (len, ExtendedAsyncParsers[tt.Index](tt, connection, requestSequence));
return ((uint)tdu.TotalLength, FixedAsyncParsers[tdu.Exponent][tdu.Index](tdu, connection, requestSequence));
}
else if (tdu.Class == TDUClass.Dynamic)
{
return ((uint)tdu.TotalLength, DynamicAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
else if (tdu.Class == TDUClass.Typed)
{
return ((uint)tdu.TotalLength, TypedAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
else // if (tt.Class == TDUClass.Extension)
{
return ((uint)tdu.TotalLength, ExtendedAsyncParsers[tdu.Index](tdu, connection, requestSequence));
}
}
@@ -252,34 +263,27 @@ public static class Codec
public static (uint, object) ParseSync(byte[] data, uint offset, Warehouse warehouse)
{
uint len = 0;
var tdu = ParsedTDU.Parse(data, offset, (uint)data.Length);
var (longLen, dataType) = ParsedTDU.Parse(data, offset, (uint)data.Length);
if (dataType == null)
if (tdu.Class == TDUClass.Invalid)
throw new NullReferenceException("DataType can't be parsed.");
len = (uint)longLen;
offset = dataType.Value.Offset;
var tt = dataType.Value;
if (tt.Class == TDUClass.Fixed)
if (tdu.Class == TDUClass.Fixed)
{
return (len, FixedParsers[tt.Exponent][tt.Index](tt, warehouse));
return ((uint)tdu.TotalLength, FixedParsers[tdu.Exponent][tdu.Index](tdu, warehouse));
}
else if (tt.Class == TDUClass.Dynamic)
else if (tdu.Class == TDUClass.Dynamic)
{
return (len, DynamicParsers[tt.Index](tt, warehouse));
return ((uint)tdu.TotalLength, DynamicParsers[tdu.Index](tdu, warehouse));
}
else if (tt.Class == TDUClass.Typed)
else if (tdu.Class == TDUClass.Typed)
{
return (len, TypedParsers[tt.Index](tt, warehouse));
return ((uint)tdu.TotalLength, TypedParsers[tdu.Index](tdu, warehouse));
}
else
{
return (len, ExtendedParsers[tt.Index](tt, warehouse));
return ((uint)tdu.TotalLength, ExtendedParsers[tdu.Index](tdu, warehouse));
}
}
/// <summary>
@@ -326,8 +330,8 @@ public static class Codec
[typeof(float?)] = DataSerializer.Float32Composer,
[typeof(long)] = DataSerializer.Int64Composer,
[typeof(long?)] = DataSerializer.Int64Composer,
[typeof(ulong)] = DataSerializer.UIn64Composer,
[typeof(ulong?)] = DataSerializer.UIn64Composer,
[typeof(ulong)] = DataSerializer.UInt64Composer,
[typeof(ulong?)] = DataSerializer.UInt64Composer,
[typeof(double)] = DataSerializer.Float64Composer,
[typeof(double?)] = DataSerializer.Float64Composer,
[typeof(DateTime)] = DataSerializer.DateTimeComposer,

View File

@@ -450,7 +450,7 @@ public static class DataDeserializer
{
var classId = tdu.Metadata.GetUUID(0);
var template = warehouse.GetTemplateByClassId(classId, TemplateType.Record);
@@ -535,7 +535,7 @@ public static class DataDeserializer
{
var classId = tdu.Metadata.GetUUID(0);
var index = tdu.Data[tdu.Offset];
var template = warehouse.GetTemplateByClassId(classId, TemplateType.Enum);
@@ -794,7 +794,7 @@ public static class DataDeserializer
var (keyCs, keyRepType) = RepresentationType.Parse(tdu.Metadata, 0);
var (valueCs, valueRepType) = RepresentationType.Parse(tdu.Metadata, keyCs);
var map = (IMap)Activator.CreateInstance(typeof(Map<,>).MakeGenericType(keyRepType.GetRuntimeType(warehouse), valueRepType.GetRuntimeType(warehouse)));
@@ -828,8 +828,9 @@ public static class DataDeserializer
public static AsyncReply TupleParserAsync(ParsedTDU tdu, DistributedConnection connection, uint[] requestSequence)
{
var rt = new AsyncReply();
var results = new List<object>();
var results = new AsyncBag<object>();
var tupleSize = tdu.Metadata[0];
var types = new List<Type>();
@@ -919,7 +920,7 @@ public static class DataDeserializer
var length = tdu.ContentLength;
var offset = tdu.Offset;
while (length > 0)
{
var (cs, reply) = Codec.ParseSync(tdu.Data, offset, warehouse);
@@ -977,20 +978,37 @@ public static class DataDeserializer
var rt = new AsyncBag<object>();
// get the type
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
var (hdrCs, rep) = RepresentationType.Parse(tdu.Metadata, 0);
offset += hdrCs;
length -= hdrCs;
var runtimeType = rep.GetRuntimeType(connection.Instance.Warehouse);
rt.ArrayType = runtimeType;
ParsedTDU current;
ParsedTDU? previous = null;
var offset = tdu.Offset;
var length = tdu.ContentLength;
var ends = offset + (uint)length;
while (length > 0)
{
var (cs, reply) = Codec.ParseAsync(data, offset, connection, requestSequence);
current = ParsedTDU.Parse(tdu.Data, offset, ends);
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
var (cs, reply) = Codec.ParseAsync(tdu.Data, offset, connection, requestSequence);
rt.Add(reply);
@@ -1021,7 +1039,7 @@ public static class DataDeserializer
var list = new List<object>();
ParsedTDU? current;
ParsedTDU current;
ParsedTDU? previous = null;
var offset = tdu.Offset;
@@ -1030,21 +1048,20 @@ public static class DataDeserializer
while (length > 0)
{
(var longLen, current) = ParsedTDU.Parse(tdu.Data, offset, ends);
current = ParsedTDU.Parse(tdu.Data, offset, ends);
if (current == null)
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
var cur = (ParsedTDU)current.Value;
if (cur.Identifier == TDUIdentifier.TypeContinuation)
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
cur.Class = previous.Value.Class;
cur.Identifier = previous.Value.Identifier;
cur.Metadata = previous.Value.Metadata;
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
var (cs, reply) = Codec.ParseSync(cur, warehouse);
var (cs, reply) = Codec.ParseSync(current, warehouse);
list.Add(reply);
@@ -1052,7 +1069,7 @@ public static class DataDeserializer
{
offset += (uint)cs;
length -= (uint)cs;
previous = cur;
previous = current;
}
else
throw new Exception("Error while parsing structured data");
@@ -1061,7 +1078,7 @@ public static class DataDeserializer
var rt = Array.CreateInstance(runtimeType, list.Count);
Array.Copy(list.ToArray(), rt, rt.Length);
return rt;
}
@@ -1070,7 +1087,8 @@ public static class DataDeserializer
var rt = new AsyncBag<PropertyValue>();
ListParserAsync(data, offset, length, connection, requestSequence).Then(x =>
ListParserAsync(new ParsedTDU() { Data = data, Offset = offset, ContentLength = length }
, connection, requestSequence).Then(x =>
{
var ar = (object[])x;
var pvs = new List<PropertyValue>();

View File

@@ -3,6 +3,7 @@ using Esiur.Net.IIP;
using Esiur.Resource;
using Esiur.Resource.Template;
using System;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -17,77 +18,271 @@ public static class DataSerializer
public static unsafe TDU Int32Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (int)value;
var rt = new byte[4];
fixed (byte* ptr = rt)
*((int*)ptr) = v;
return new TDU(TDUIdentifier.Int32, rt, 4);
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
{
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
}
else if (v >= short.MinValue && v <= short.MaxValue)
{
// Fits in 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = (short)v;
return new TDU(TDUIdentifier.Int16, rt, 2);
}
else
{
// Use full 4 bytes
var rt = new byte[4];
fixed (byte* ptr = rt)
*((int*)ptr) = v;
return new TDU(TDUIdentifier.Int32, rt, 4);
}
}
public static unsafe TDU UInt32Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (uint)value;
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = v;
return new TDU(TDUIdentifier.UInt32, rt, 4);
if (v <= byte.MaxValue)
{
// Fits in 1 byte
return new TDU(TDUIdentifier.UInt8, new byte[] { (byte)v }, 1);
}
else if (v <= ushort.MaxValue)
{
// Fits in 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)v;
return new TDU(TDUIdentifier.UInt16, rt, 2);
}
else
{
// Use full 4 bytes
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = v;
return new TDU(TDUIdentifier.UInt32, rt, 4);
}
}
public static unsafe TDU Int16Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (short)value;
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = v;
return new TDU(TDUIdentifier.Int16, rt, 2);
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
{
// Fits in 1 byte
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
}
else
{
// Use full 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = v;
return new TDU(TDUIdentifier.Int16, rt, 2);
}
}
public static unsafe TDU UInt16Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (ushort)value;
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = v;
return new TDU(TDUIdentifier.UInt16, rt, 2);
if (v <= byte.MaxValue)
{
// Fits in 1 byte
return new TDU(TDUIdentifier.UInt8, new byte[] { (byte)v }, 1);
}
else
{
// Use full 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = v;
return new TDU(TDUIdentifier.UInt16, rt, 2);
}
}
public static unsafe TDU Float32Composer(object value, Warehouse warehouse, DistributedConnection connection)
public static unsafe TDU Float32Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (float)value;
var rt = new byte[4];
fixed (byte* ptr = rt)
*((float*)ptr) = v;
return new TDU(TDUIdentifier.Float32, rt, 4);
float v = (float)value;
// Special IEEE-754 values
if (float.IsNaN(v) || float.IsInfinity(v))
{
return new TDU(TDUIdentifier.Infinity, new byte[0], 0);
}
// If v is an exact integer, prefer smallest signed width up to Int32
if (v == Math.Truncate(v))
{
// Note: casts are safe because we check bounds first.
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
{
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
}
if (v >= short.MinValue && v <= short.MaxValue)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = (short)v;
return new TDU(TDUIdentifier.Int16, rt, 2);
}
}
// Default: Float32
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((float*)ptr) = v;
return new TDU(TDUIdentifier.Float32, rt, 4);
}
}
public static unsafe TDU Float64Composer(object value, Warehouse warehouse, DistributedConnection connection)
public unsafe static TDU Float64Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (double)value;
var rt = new byte[8];
fixed (byte* ptr = rt)
*((double*)ptr) = v;
return new TDU(TDUIdentifier.Float64, rt, 8);
}
double v = (double)value;
// Special IEEE-754 values
if (double.IsNaN(v) || double.IsInfinity(v))
{
return new TDU(TDUIdentifier.Infinity, new byte[0], 0);
}
// If v is an exact integer, choose the smallest signed width
if (v == Math.Truncate(v))
{
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
if (v >= short.MinValue && v <= short.MaxValue)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = (short)v;
return new TDU(TDUIdentifier.Int16, rt, 2);
}
if (v >= int.MinValue && v <= int.MaxValue)
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((int*)ptr) = (int)v;
return new TDU(TDUIdentifier.Int32, rt, 4);
}
// If it's integral but outside Int64 range, fall through to Float64.
}
// Try exact Float32 (decimal subset of doubles)
var f = (float)v;
if ((double)f == v)
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((float*)ptr) = (byte)v;
return new TDU(TDUIdentifier.Float32, rt, 4);
}
// Default: Float64
{
var rt = new byte[8];
fixed (byte* ptr = rt)
*((double*)ptr) = v;
return new TDU(TDUIdentifier.Float64, rt, 8);
}
}
public static unsafe TDU Int64Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (long)value;
var rt = new byte[8];
fixed (byte* ptr = rt)
*((long*)ptr) = v;
return new TDU(TDUIdentifier.Int64, rt, 8);
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
{
// Fits in 1 byte
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
}
else if (v >= short.MinValue && v <= short.MaxValue)
{
// Fits in 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((short*)ptr) = (short)v;
return new TDU(TDUIdentifier.Int16, rt, 2);
}
else if (v >= int.MinValue && v <= int.MaxValue)
{
// Fits in 4 bytes
var rt = new byte[4];
fixed (byte* ptr = rt)
*((int*)ptr) = (int)v;
return new TDU(TDUIdentifier.Int32, rt, 4);
}
else
{
// Use full 8 bytes
var rt = new byte[8];
fixed (byte* ptr = rt)
*((long*)ptr) = v;
return new TDU(TDUIdentifier.Int64, rt, 8);
}
}
public static unsafe TDU UIn64Composer(object value, Warehouse warehouse, DistributedConnection connection)
public static unsafe TDU UInt64Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (ulong)value;
var rt = new byte[8];
fixed (byte* ptr = rt)
*((ulong*)ptr) = v;
return new TDU(TDUIdentifier.UInt64, rt, 8);
if (v <= byte.MaxValue)
{
// Fits in 1 byte
return new TDU(TDUIdentifier.UInt8, new byte[] { (byte)v }, 1);
}
else if (v <= ushort.MaxValue)
{
// Fits in 2 bytes
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)v;
return new TDU(TDUIdentifier.UInt16, rt, 2);
}
else if (v <= uint.MaxValue)
{
// Fits in 4 bytes
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = (uint)v;
return new TDU(TDUIdentifier.UInt32, rt, 4);
}
else
{
// Use full 8 bytes
var rt = new byte[8];
fixed (byte* ptr = rt)
*((ulong*)ptr) = v;
return new TDU(TDUIdentifier.UInt64, rt, 8);
}
}
@@ -101,18 +296,89 @@ public static class DataSerializer
return new TDU(TDUIdentifier.DateTime, rt, 8);
}
//public static unsafe TDU Decimal128Composer(object value, Warehouse warehouse, DistributedConnection connection)
//{
// var v = (decimal)value;
// var rt = new byte[16];
// fixed (byte* ptr = rt)
// *((decimal*)ptr) = v;
// return new TDU(TDUIdentifier.Decimal128, rt, 16);
//}
public static unsafe TDU Decimal128Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
var v = (decimal)value;
var rt = new byte[16];
fixed (byte* ptr = rt)
*((decimal*)ptr) = v;
return new TDU(TDUIdentifier.Decimal128, rt, 16);
// Prefer smallest exact signed integer if no fractional part
int[] bits = decimal.GetBits(v);
int flags = bits[3];
int scale = (flags >> 16) & 0x7F;
if (scale == 0)
{
if (v >= sbyte.MinValue && v <= sbyte.MaxValue)
return new TDU(TDUIdentifier.Int8, new byte[] { (byte)(sbyte)v }, 1);
if (v >= short.MinValue && v <= short.MaxValue)
{
var b = new byte[2];
BinaryPrimitives.WriteInt16LittleEndian(b, (short)v);
return new TDU(TDUIdentifier.Int16, b, 2);
}
if (v >= int.MinValue && v <= int.MaxValue)
{
var b = new byte[4];
BinaryPrimitives.WriteInt32LittleEndian(b, (int)v);
return new TDU(TDUIdentifier.Int32, b, 4);
}
if (v >= long.MinValue && v <= long.MaxValue)
{
var b = new byte[8];
BinaryPrimitives.WriteInt64LittleEndian(b, (long)v);
return new TDU(TDUIdentifier.Int64, b, 8);
}
// else fall through (needs 96+ bits)
}
// Try exact Float32 (4 bytes)
// Exactness test: decimal -> float -> decimal must equal original
float f = (float)v;
if ((decimal)f == v)
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((float*)ptr) = f;
return new TDU(TDUIdentifier.Float32, rt, 4);
}
// Try exact Float64 (8 bytes)
double d = (double)v;
if ((decimal)d == v)
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((double*)ptr) = d;
return new TDU(TDUIdentifier.Float64, rt, 8);
}
{
// Fallback: full .NET decimal (16 bytes): lo, mid, hi, flags (scale/sign)
var rt = new byte[16];
fixed (byte* ptr = rt)
*((decimal*)ptr) = v;
return new TDU(TDUIdentifier.Decimal128, rt, 16);
}
}
public static TDU StringComposer(object value, Warehouse warehouse, DistributedConnection connection)
{
var b = Encoding.UTF8.GetBytes((string)value);
@@ -228,8 +494,6 @@ public static class DataSerializer
{
var composed = ArrayComposer((IEnumerable)value, warehouse, connection);
Console.WriteLine(composed.ToHex());
if (composed == null)
return new TDU(TDUIdentifier.Null, new byte[0], 0);
@@ -331,12 +595,12 @@ public static class DataSerializer
foreach (var i in value)
{
var tdu = Codec.ComposeInternal(i, warehouse, connection);
if (previous != null && tdu.MatchType(previous.Value))
if (previous != null && tdu.MatchType(previous.Value))
{
var d = tdu.Composed.Clip(tdu.ContentOffset,
(uint)tdu.Composed.Length - tdu.ContentOffset);
var ntd = new TDU(TDUIdentifier.TypeContinuation, d,(ulong) d.Length);
var ntd = new TDU(TDUIdentifier.TypeContinuation, d, (ulong)d.Length);
rt.AddRange(ntd.Composed);
}
else

View File

@@ -16,7 +16,7 @@ namespace Esiur.Data
public ulong TotalLength;
public byte[] Metadata;
public static (ulong, ParsedTDU?) Parse(byte[] data, uint offset, uint ends)
public static ParsedTDU Parse(byte[] data, uint offset, uint ends)
{
var h = data[offset++];
@@ -27,7 +27,7 @@ namespace Esiur.Data
var exp = (h & 0x38) >> 3;
if (exp == 0)
return (1, new ParsedTDU()
return new ParsedTDU()
{
Identifier = (TDUIdentifier)h,
Data = data,
@@ -37,16 +37,20 @@ namespace Esiur.Data
Index = (byte)h & 0x7,
ContentLength = 0,
TotalLength = 1,
});
};
ulong cl = (ulong)(1 << (exp - 1));
if (ends - offset < cl)
return (cl - (ends - offset), null);
return new ParsedTDU()
{
Class = TDUClass.Invalid,
TotalLength = (cl - (ends - offset))
};
//offset += (uint)cl;
return (1 + cl, new ParsedTDU()
return new ParsedTDU()
{
Identifier = (TDUIdentifier)h,
Data = data,
@@ -56,14 +60,18 @@ namespace Esiur.Data
TotalLength = 1 + cl,
Exponent = (byte)exp,
Index = (byte)h & 0x7,
});
};
}
else if (cls == TDUClass.Typed)
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return (cll - (ends - offset), null);
return new ParsedTDU()
{
Class = TDUClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
@@ -71,13 +79,17 @@ namespace Esiur.Data
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return (cl - (ends - offset), null);
return new ParsedTDU()
{
TotalLength = (cl - (ends - offset)),
Class = TDUClass.Invalid,
};
var metaData = DC.Clip(data, offset + 1, data[offset]);
offset += data[offset] + (uint)1;
return (1 + cl + cll, new ParsedTDU()
return new ParsedTDU()
{
Identifier = (TDUIdentifier)(h & 0xC7),
Data = data,
@@ -87,14 +99,18 @@ namespace Esiur.Data
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7,
Metadata = metaData,
});
};
}
else
{
ulong cll = (ulong)(h >> 3) & 0x7;
if (ends - offset < cll)
return (cll - (ends - offset), null);
return new ParsedTDU()
{
Class = TDUClass.Invalid,
TotalLength = (cll - (ends - offset))
};
ulong cl = 0;
@@ -102,10 +118,14 @@ namespace Esiur.Data
cl = cl << 8 | data[offset++];
if (ends - offset < cl)
return (cl - (ends - offset), null);
return new ParsedTDU()
{
Class = TDUClass.Invalid,
TotalLength = (cl - (ends - offset))
};
return (1 + cl + cll,
return
new ParsedTDU()
{
Identifier = (TDUIdentifier)(h & 0xC7),
@@ -115,7 +135,7 @@ namespace Esiur.Data
ContentLength = cl,
TotalLength = 1 + cl + cll,
Index = (byte)h & 0x7
});
};
}
}

View File

@@ -9,6 +9,7 @@ namespace Esiur.Data
Fixed = 0x0,
Dynamic = 0x1,
Typed = 0x2,
Extension = 0x3
Extension = 0x3,
Invalid
}
}

View File

@@ -10,6 +10,7 @@ namespace Esiur.Data
False = 0x1,
True = 0x2,
NotModified = 0x3,
Infinity = 0x4,
UInt8 = 0x8,
Int8 = 0x9,
Char8 = 0xA,

View File

@@ -438,7 +438,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
{
// Invoke
case IIPPacketNotification.PropertyModified:
IIPNotificationPropertyModified(dt, msg);
IIPNotificationPropertyModified(dt);
break;
case IIPPacketNotification.EventOccurred:
IIPNotificationEventOccurred(dt, msg);
@@ -448,7 +448,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
IIPNotificationResourceDestroyed(dt, msg);
break;
case IIPPacketNotification.ResourceReassigned:
IIPNotificationResourceReassigned(dt, msg);
IIPNotificationResourceReassigned(dt);
break;
case IIPPacketNotification.ResourceMoved:
IIPNotificationResourceMoved(dt, msg);
@@ -537,7 +537,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
switch (packet.Reply)
{
case IIPPacketReply.Completed:
IIPReplyCompleted(packet.CallbackId, dt, msg);
IIPReplyCompleted(packet.CallbackId, dt);
break;
case IIPPacketReply.Propagated:
IIPReplyPropagated(packet.CallbackId, dt, msg);
@@ -554,7 +554,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
break;
case IIPPacketReply.Chunk:
IIPReplyChunk(packet.CallbackId, dt, msg);
IIPReplyChunk(packet.CallbackId, dt);
break;
case IIPPacketReply.Warning:
@@ -1344,7 +1344,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
protected override void DataReceived(NetworkBuffer data)
{
//Console.WriteLine("DR " + data.Available + " " + RemoteEndPoint.ToString());
var msg = data.Read();
uint offset = 0;
uint ends = (uint)msg.Length;
@@ -1353,8 +1352,6 @@ public partial class DistributedConnection : NetworkConnection, IStore
var chunkId = (new Random()).Next(1000, 1000000);
//var list = new List<Map<string, object>>();// double, IIPPacketCommand>();
this.Socket.Hold();

View File

@@ -262,7 +262,7 @@ partial class DistributedConnection
SendReply(IIPPacketReply.Chunk, callbackId, chunk);
}
void IIPReplyCompleted(uint callbackId, ParsedTDU dataType, byte[] data)
void IIPReplyCompleted(uint callbackId, ParsedTDU dataType)
{
var req = requests.Take(callbackId);
@@ -272,7 +272,7 @@ partial class DistributedConnection
return;
}
var (_, parsed) = Codec.ParseAsync(data, 0, this, null, dataType);
var (_, parsed) = Codec.ParseAsync(dataType, this, null);
if (parsed is AsyncReply reply)
{
reply.Then(result =>
@@ -374,14 +374,14 @@ partial class DistributedConnection
void IIPReplyChunk(uint callbackId, ParsedTDU dataType, byte[] data)
void IIPReplyChunk(uint callbackId, ParsedTDU dataType)
{
var req = requests[callbackId];
if (req == null)
return;
var (_, parsed) = Codec.ParseAsync(data, dataType.Offset, this, null, dataType);
var (_, parsed) = Codec.ParseAsync(dataType, this, null);
if (parsed is AsyncReply reply)
reply.Then(result => req.TriggerChunk(result));
@@ -389,7 +389,7 @@ partial class DistributedConnection
req.TriggerChunk(parsed);
}
void IIPNotificationResourceReassigned(ParsedTDU dataType, byte[] data)
void IIPNotificationResourceReassigned(ParsedTDU dataType)
{
// uint resourceId, uint newResourceId
}
@@ -429,11 +429,11 @@ partial class DistributedConnection
}
void IIPNotificationPropertyModified(ParsedTDU dataType, byte[] data)
void IIPNotificationPropertyModified(ParsedTDU dataType)
{
// resourceId, index, value
var (valueOffset, valueSize, args) =
DataDeserializer.LimitedCountListParser(data, dataType.Offset, dataType.ContentLength, Instance.Warehouse, 2);
DataDeserializer.LimitedCountListParser(dataType.Data, dataType.Offset, dataType.ContentLength, Instance.Warehouse, 2);
var rid = (uint)args[0];
var index = (byte)args[1];
@@ -447,7 +447,7 @@ partial class DistributedConnection
var item = new AsyncReply<DistributedResourceQueueItem>();
queue.Add(item);
var (_, parsed) = Codec.ParseAsync(data, valueOffset, this, null);
var (_, parsed) = Codec.ParseAsync(dataType.Data, valueOffset, this, null);
if (parsed is AsyncReply)
{
@@ -663,7 +663,7 @@ partial class DistributedConnection
void IIPRequestCreateResource(uint callback, ParsedTDU dataType, byte[] data)
{
var (_, parsed) = Codec.ParseAsync(data, 0, this, null, dataType);
var (_, parsed) = Codec.ParseAsync(dataType, this, null);
var args = (object[])parsed;

View File

@@ -117,7 +117,7 @@ public abstract class NetworkServer<TConnection> : IDestructible where TConnecti
if (s == null)
{
Console.Write("sock == null");
Global.Log("NetworkServer", LogType.Error, "sock == null");
return;
}

View File

@@ -188,13 +188,13 @@ public class IIPAuthPacket : Packet
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = ParsedTDU.Parse(data, offset, ends);
DataType = ParsedTDU.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
if (DataType.Value.Class == TDUClass.Invalid)
return -(int)DataType.Value.TotalLength;
offset += (uint)size;
offset += (uint)DataType.Value.TotalLength;
}
else if (Command == IIPAuthPacketCommand.Acknowledge)
@@ -208,13 +208,13 @@ public class IIPAuthPacket : Packet
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = ParsedTDU.Parse(data, offset, ends);
DataType = ParsedTDU.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
if (DataType.Value.Class == TDUClass.Invalid)
return -(int)DataType.Value.TotalLength;
offset += (uint)size;
offset += (uint)DataType.Value.TotalLength;
}
else if (Command == IIPAuthPacketCommand.Action)
{
@@ -280,12 +280,12 @@ public class IIPAuthPacket : Packet
Reference = data.GetUInt32(offset, Endian.Little);
offset += 4;
(var size, DataType) = ParsedTDU.Parse(data, offset, ends);
DataType = ParsedTDU.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
if (DataType.Value.Class == TDUClass.Invalid)
return -(int)DataType.Value.TotalLength;
offset += (uint)size;
offset += (uint)DataType.Value.TotalLength;
}
else if (Action == IIPAuthPacketAction.IAuthHashed)
@@ -445,12 +445,12 @@ public class IIPAuthPacket : Packet
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = ParsedTDU.Parse(data, offset, ends);
DataType = ParsedTDU.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
if (DataType.Value.Class == TDUClass.Invalid)
return -(int)DataType.Value.TotalLength;
offset += (uint)size;
offset += (uint)DataType.Value.TotalLength;
}
}

View File

@@ -37,10 +37,10 @@ class IIPPacket : Packet
public uint CallbackId { get; set; }
public IIPPacketMethod Method { get; set; }
public IIPPacketRequest Request { get; set; }
public IIPPacketReply Reply { get; set; }
public IIPPacketRequest Request { get; set; }
public IIPPacketReply Reply { get; set; }
public IIPPacketNotification Notification { get; set; }
public IIPPacketNotification Notification { get; set; }
public byte Extension { get; set; }
@@ -57,12 +57,12 @@ class IIPPacket : Packet
public override string ToString()
{
return Method switch
return Method switch
{
IIPPacketMethod.Notification => $"{Method} {Notification}",
IIPPacketMethod.Request => $"{Method} {Request}",
IIPPacketMethod.Reply => $"{Method} {Reply}",
IIPPacketMethod.Extension => $"{Method} {Extension}",
IIPPacketMethod.Request => $"{Method} {Request}",
IIPPacketMethod.Reply => $"{Method} {Reply}",
IIPPacketMethod.Extension => $"{Method} {Extension}",
_ => $"{Method}"
};
}
@@ -124,12 +124,12 @@ class IIPPacket : Packet
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = ParsedTDU.Parse(data, offset, ends);
DataType = ParsedTDU.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
if (DataType.Value.Class == TDUClass.Invalid)
return -(int)DataType.Value.TotalLength;
offset += (uint)size;
offset += (uint)DataType.Value.TotalLength;
}
else
{