194 lines
6.6 KiB
C#
194 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using ln.types.odb.ng;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
/**
|
|
* typeCode list
|
|
*
|
|
* 0x0000 ODBNull
|
|
* 0x0001 ODBStringValue
|
|
* 0x0002 ODBList
|
|
* 0x0003 ODBGuid
|
|
* 0x0004 ODBBool
|
|
*
|
|
* 0x0010 ODBInteger
|
|
* 0x0011 ODBUInteger
|
|
* 0x0012 ODBLong
|
|
* 0x0013 ODBULong
|
|
*
|
|
* 0x0018 ODBDouble
|
|
*
|
|
* 0x0020 ODBTypedMapping
|
|
*
|
|
* 0x1000 ODBDocument
|
|
* 0x1001 Document (ln.types.odb.ng)
|
|
*
|
|
*
|
|
*
|
|
**/
|
|
|
|
|
|
|
|
namespace ln.types.odb.values
|
|
{
|
|
public delegate ODBEntity ODBValueFactory(object value);
|
|
public delegate ODBEntity ODBDeserialize(byte[] storageBytes, int offset, int length);
|
|
|
|
/// <summary>
|
|
/// ODBEntity. The base of all ODB types.
|
|
/// </summary>
|
|
/// <remarks>
|
|
///
|
|
/// </remarks>
|
|
///
|
|
public abstract class ODBEntity : IComparable<ODBEntity>
|
|
{
|
|
int storageTypeCode;
|
|
|
|
/// <summary>
|
|
/// Gets the identity of this Entity.
|
|
/// </summary>
|
|
/// <value>The identity.</value>
|
|
public virtual ODBValue Identity { get; }
|
|
|
|
/// <summary>
|
|
/// Return a .NET native value / object that semantically equals this ODBEntity instance.
|
|
/// </summary>
|
|
/// <returns>The native .NET value</returns>
|
|
/// <typeparam name="T">The type to which this ODBEntity should be casted/converted.</typeparam>
|
|
public abstract T As<T>();
|
|
|
|
/// <summary>
|
|
/// Independently clone this instance.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// For immutable values this returns the instance itself.
|
|
/// Complex ODBEntities will return a copy of themself that is completly independend of the source.
|
|
/// </remarks>
|
|
/// <returns>The clone.</returns>
|
|
public abstract ODBEntity Clone();
|
|
|
|
/// <summary>
|
|
/// Implements the internal comparison within the same subclass of ODBEntity.
|
|
/// </summary>
|
|
/// <returns>The compare.</returns>
|
|
/// <param name="other">Other.</param>
|
|
protected abstract int compare(ODBEntity other);
|
|
|
|
|
|
|
|
|
|
protected ODBEntity(int storageTypeCode)
|
|
{
|
|
this.storageTypeCode = storageTypeCode;
|
|
}
|
|
|
|
|
|
public int CompareTo(ODBEntity other)
|
|
{
|
|
if (storageTypeCode != other.storageTypeCode)
|
|
return storageTypeCode - other.storageTypeCode;
|
|
return compare(other);
|
|
}
|
|
|
|
public abstract byte[] GetStorageBytes();
|
|
public virtual void Write(BinaryWriter storage)
|
|
{
|
|
byte[] storageBytes = GetStorageBytes();
|
|
|
|
storage.Write(storageTypeCode);
|
|
storage.Write(storageBytes.Length);
|
|
storage.Write(storageBytes, 0, storageBytes.Length);
|
|
}
|
|
|
|
public override int GetHashCode() => Identity.GetHashCode();
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is ODBEntity)
|
|
return Identity.Equals((obj as ODBEntity).Identity);
|
|
return false;
|
|
}
|
|
|
|
public virtual object As(Type targetType)
|
|
{
|
|
MethodInfo methodInfo = GetType().GetMethod("As");
|
|
return methodInfo.MakeGenericMethod(targetType).Invoke(this, new object[0]);
|
|
}
|
|
|
|
public static bool operator <(ODBEntity a, ODBEntity b) => a.CompareTo(b) < 0;
|
|
public static bool operator >(ODBEntity a, ODBEntity b) => a.CompareTo(b) > 0;
|
|
public static bool operator <=(ODBEntity a, ODBEntity b) => a.CompareTo(b) <= 0;
|
|
public static bool operator >=(ODBEntity a, ODBEntity b) => a.CompareTo(b) >= 0;
|
|
public static bool operator ==(ODBEntity a, ODBEntity b) => (a is null) ? b is null : a.CompareTo(b) == 0;
|
|
public static bool operator !=(ODBEntity a, ODBEntity b) => (a is null) ? !(b is null) : a.CompareTo(b) != 0;
|
|
|
|
//public static implicit operator ODBEntity(ValueType v)
|
|
//{
|
|
// return Mapper.Default.MapValue(v);
|
|
//}
|
|
//public static implicit operator ODBEntity(String v)
|
|
//{
|
|
// return Mapper.Default.MapValue(v);
|
|
//}
|
|
|
|
public static ODBEntity FromNative(object v)
|
|
{
|
|
return Mapper.Default.MapValue(v);
|
|
}
|
|
|
|
static Dictionary<int, ODBDeserialize> valueDeserializers = new Dictionary<int, ODBDeserialize>();
|
|
public static void RegisterDeserializer(int storageTypeCode, ODBDeserialize deserialize)
|
|
{
|
|
valueDeserializers.Add(storageTypeCode, deserialize);
|
|
}
|
|
|
|
public static ODBEntity Deserialize(byte[] buffer, ref int offset)
|
|
{
|
|
int storageTypeCode = BitConverter.ToInt32(buffer, offset);
|
|
int storageLength = BitConverter.ToInt32(buffer, offset + 4);
|
|
if (!valueDeserializers.ContainsKey(storageTypeCode))
|
|
throw new KeyNotFoundException(String.Format("StorageTypeCode 0x{0:x8} at offset 0x{1:x8}",storageTypeCode,offset));
|
|
|
|
ODBEntity value = valueDeserializers[storageTypeCode](buffer, offset + 8, storageLength);
|
|
offset += 8 + storageLength;
|
|
return value;
|
|
}
|
|
|
|
public static ODBEntity Read(Stream stream)
|
|
{
|
|
int storageTypeCode = stream.ReadInteger();
|
|
int storageLength = stream.ReadInteger();
|
|
byte[] b = new byte[storageLength];
|
|
stream.Read(b, 0, storageLength);
|
|
|
|
if (valueDeserializers.ContainsKey(storageTypeCode))
|
|
return valueDeserializers[storageTypeCode](b, 0, storageLength);
|
|
else
|
|
throw new FormatException("wrong storage type code");
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return String.Format("[{0} Identity={1}]", GetType().Name, Identity);
|
|
}
|
|
|
|
static ODBEntity()
|
|
{
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBNull).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(Document).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBList).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBStringValue).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBInteger).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBUInteger).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBLong).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBULong).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBDouble).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBGuid).TypeHandle);
|
|
RuntimeHelpers.RunClassConstructor(typeof(ODBBool).TypeHandle);
|
|
}
|
|
}
|
|
}
|