mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-07-30 17:30:40 +00:00
TypeDef Id
This commit is contained in:
@@ -89,48 +89,20 @@ namespace Esiur.Data
|
|||||||
if (TypeDef is RemoteTypeDef remoteTypeDef)
|
if (TypeDef is RemoteTypeDef remoteTypeDef)
|
||||||
{
|
{
|
||||||
if (connection.RemoteDomain == remoteTypeDef.Domain)
|
if (connection.RemoteDomain == remoteTypeDef.Domain)
|
||||||
{
|
|
||||||
// this is local in respect to the connection, send the remote typdef id.
|
// this is local in respect to the connection, send the remote typdef id.
|
||||||
if (Nullable)
|
WriteTypeReference(rt, isLocal: true, Nullable, remoteTypeDef.Id);
|
||||||
rt.AddUInt8(0x80 | (byte)TruIdentifier.LocalType8);
|
|
||||||
else
|
|
||||||
rt.AddUInt8((byte)TruIdentifier.LocalType8);
|
|
||||||
|
|
||||||
rt.AddUInt8((byte)remoteTypeDef.Id);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// this is remote in respect to the connection and the local typedef id is used.
|
// this is remote in respect to the connection and the local typedef id is used.
|
||||||
if (Nullable)
|
WriteTypeReference(rt, isLocal: false, Nullable, remoteTypeDef.LocalTypeDefId);
|
||||||
rt.AddUInt8(0x80 | (byte)TruIdentifier.RemoteType8);
|
|
||||||
else
|
|
||||||
rt.AddUInt8((byte)TruIdentifier.RemoteType8);
|
|
||||||
|
|
||||||
rt.AddUInt8((byte)remoteTypeDef.LocalTypeDefId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (TypeDef is LocalTypeDef localTypeDef)
|
else if (TypeDef is LocalTypeDef localTypeDef)
|
||||||
{
|
{
|
||||||
if (connection == null)
|
if (connection == null)
|
||||||
{
|
|
||||||
// if there is no connection, we assume it's local.
|
// if there is no connection, we assume it's local.
|
||||||
if (Nullable)
|
WriteTypeReference(rt, isLocal: true, Nullable, localTypeDef.Id);
|
||||||
rt.AddUInt8(0x80 | (byte)TruIdentifier.LocalType8);
|
|
||||||
else
|
|
||||||
rt.AddUInt8((byte)TruIdentifier.LocalType8);
|
|
||||||
|
|
||||||
rt.AddUInt8((byte)localTypeDef.Id);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// this is remote, unless the connection is to self @TODO: solve for this state.
|
// this is remote, unless the connection is to self @TODO: solve for this state.
|
||||||
if (Nullable)
|
WriteTypeReference(rt, isLocal: false, Nullable, localTypeDef.Id);
|
||||||
rt.AddUInt8(0x80 | (byte)TruIdentifier.RemoteType8);
|
|
||||||
else
|
|
||||||
rt.AddUInt8((byte)TruIdentifier.RemoteType8);
|
|
||||||
|
|
||||||
rt.AddUInt8((byte)localTypeDef.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -138,6 +110,45 @@ namespace Esiur.Data
|
|||||||
return rt.ToArray();
|
return rt.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Picks the narrowest Local/RemoteType{8,16,32,64} identifier that fits `id`,
|
||||||
|
// matching the widths Tru.Parse already knows how to read.
|
||||||
|
// Internal (rather than private) so it can be unit-tested directly without
|
||||||
|
// needing a real LocalTypeDef/Warehouse registration for every width tier.
|
||||||
|
internal static void WriteTypeReference(BinaryList rt, bool isLocal, bool nullable, ulong id)
|
||||||
|
{
|
||||||
|
TruIdentifier identifier;
|
||||||
|
|
||||||
|
if (id <= byte.MaxValue)
|
||||||
|
identifier = isLocal ? TruIdentifier.LocalType8 : TruIdentifier.RemoteType8;
|
||||||
|
else if (id <= ushort.MaxValue)
|
||||||
|
identifier = isLocal ? TruIdentifier.LocalType16 : TruIdentifier.RemoteType16;
|
||||||
|
else if (id <= uint.MaxValue)
|
||||||
|
identifier = isLocal ? TruIdentifier.LocalType32 : TruIdentifier.RemoteType32;
|
||||||
|
else
|
||||||
|
identifier = isLocal ? TruIdentifier.LocalType64 : TruIdentifier.RemoteType64;
|
||||||
|
|
||||||
|
rt.AddUInt8((byte)((nullable ? 0x80 : 0) | (byte)identifier));
|
||||||
|
|
||||||
|
switch (identifier)
|
||||||
|
{
|
||||||
|
case TruIdentifier.LocalType8:
|
||||||
|
case TruIdentifier.RemoteType8:
|
||||||
|
rt.AddUInt8((byte)id);
|
||||||
|
break;
|
||||||
|
case TruIdentifier.LocalType16:
|
||||||
|
case TruIdentifier.RemoteType16:
|
||||||
|
rt.AddUInt16((ushort)id);
|
||||||
|
break;
|
||||||
|
case TruIdentifier.LocalType32:
|
||||||
|
case TruIdentifier.RemoteType32:
|
||||||
|
rt.AddUInt32((uint)id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rt.AddUInt64(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override Tru ToNullable()
|
public override Tru ToNullable()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class TypeDefInfo : IndexedStructure
|
|||||||
Version = definition.Version,
|
Version = definition.Version,
|
||||||
Id = definition.Id,
|
Id = definition.Id,
|
||||||
Name = definition.Name,
|
Name = definition.Name,
|
||||||
|
Namespace = (definition as LocalTypeDef)?.DefinedType?.Namespace,
|
||||||
Kind = definition.Kind,
|
Kind = definition.Kind,
|
||||||
Parent = definition.ParentTypeId,
|
Parent = definition.ParentTypeId,
|
||||||
Usage = definition.Usage,
|
Usage = definition.Usage,
|
||||||
|
|||||||
@@ -127,4 +127,70 @@ public class TypeDefInfoSerializationTests
|
|||||||
Assert.Equal(TruIdentifier.String, Assert.Single(parsed.Events!).ArgumentType.Identifier);
|
Assert.Equal(TruIdentifier.String, Assert.Single(parsed.Events!).ArgumentType.Identifier);
|
||||||
Assert.Equal(100, Convert.ToInt32(Assert.Single(parsed.Constants!).Value));
|
Assert.Equal(100, Convert.ToInt32(Assert.Single(parsed.Constants!).Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(0ul, TruIdentifier.LocalType8, 1)]
|
||||||
|
[InlineData(255ul, TruIdentifier.LocalType8, 1)]
|
||||||
|
[InlineData(256ul, TruIdentifier.LocalType16, 2)]
|
||||||
|
[InlineData(65535ul, TruIdentifier.LocalType16, 2)]
|
||||||
|
[InlineData(65536ul, TruIdentifier.LocalType32, 4)]
|
||||||
|
[InlineData(4294967295ul, TruIdentifier.LocalType32, 4)]
|
||||||
|
[InlineData(4294967296ul, TruIdentifier.LocalType64, 8)]
|
||||||
|
public void WriteTypeReference_SelectsNarrowestSufficientWidth(ulong id, TruIdentifier expectedIdentifier, int expectedIdBytes)
|
||||||
|
{
|
||||||
|
var rt = new BinaryList();
|
||||||
|
TruTypeDef.WriteTypeReference(rt, isLocal: true, nullable: false, id);
|
||||||
|
var bytes = rt.ToArray();
|
||||||
|
|
||||||
|
Assert.Equal(1 + expectedIdBytes, bytes.Length);
|
||||||
|
Assert.Equal((byte)expectedIdentifier, bytes[0]);
|
||||||
|
|
||||||
|
ulong roundTripped = expectedIdBytes switch
|
||||||
|
{
|
||||||
|
1 => bytes[1],
|
||||||
|
2 => bytes.GetUInt16(1, Endian.Little),
|
||||||
|
4 => bytes.GetUInt32(1, Endian.Little),
|
||||||
|
_ => bytes.GetUInt64(1, Endian.Little),
|
||||||
|
};
|
||||||
|
Assert.Equal(id, roundTripped);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteTypeReference_NullableAndRemote_SetHeaderBitsCorrectly()
|
||||||
|
{
|
||||||
|
var rt = new BinaryList();
|
||||||
|
TruTypeDef.WriteTypeReference(rt, isLocal: false, nullable: true, 42ul);
|
||||||
|
var bytes = rt.ToArray();
|
||||||
|
|
||||||
|
Assert.Equal((byte)(0x80 | (byte)TruIdentifier.RemoteType8), bytes[0]);
|
||||||
|
Assert.Equal(42, bytes[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TypeDefInfo_FromTypeDef_PopulatesNamespaceFromDefinedType()
|
||||||
|
{
|
||||||
|
var typeDef = new LocalTypeDef(typeof(TruTypeDefTestRecord), Warehouse.Default);
|
||||||
|
var info = TypeDefInfo.FromTypeDef(typeDef);
|
||||||
|
|
||||||
|
Assert.Equal(typeof(TruTypeDefTestRecord).Namespace, info.Namespace);
|
||||||
|
Assert.False(string.IsNullOrEmpty(info.Namespace));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TruTypeDef_Compose_LocalTypeDefWithoutConnection_RoundTrips()
|
||||||
|
{
|
||||||
|
var typeDef = new LocalTypeDef(typeof(TruTypeDefTestRecord), Warehouse.Default);
|
||||||
|
var tru = new TruTypeDef(false, typeDef);
|
||||||
|
|
||||||
|
var bytes = tru.Compose(null);
|
||||||
|
var result = Tru.Parse(bytes, 0, Warehouse.Default);
|
||||||
|
|
||||||
|
Assert.Equal((uint)bytes.Length, result.Size);
|
||||||
|
var parsed = Assert.IsType<TruTypeDef>(result.Value);
|
||||||
|
Assert.Equal(typeDef.Id, parsed.TypeDef!.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TruTypeDefTestRecord : IRecord
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user