ln.types/odb/values/ODBValue.cs

248 lines
6.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
/**
* 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 ODBValue ODBValueFactory(object value);
public delegate ODBValue ODBDeserialize(byte[] storageBytes, int offset, int length);
public abstract class ODBValue
{
int storageTypeCode;
public virtual object Value { get; protected set; }
protected ODBValue(int storageTypeCode)
{
this.storageTypeCode = storageTypeCode;
}
protected ODBValue(int storageTypeCode, object value)
: this(storageTypeCode)
{
Value = value;
}
public abstract int CompareLevel { get; }
public abstract int CompareInType(ODBValue other);
public virtual int CompareValueInType(ODBValue other) => CompareInType(other);
public abstract byte[] ToStorage();
public object AsObject => Value;
public virtual string AsString
{
get
{
return Value?.ToString();
}
}
public virtual bool AsBool
{
get
{
return (bool)Value;
}
}
public virtual byte AsByte => Convert.ToByte(Value);
public virtual char AsChar => (char)Value;
public virtual short AsShort => Convert.ToInt16(Value);
public virtual int AsInt => Convert.ToInt32(Value);
public virtual long AsLong => Convert.ToInt64(Value);
public virtual ushort AsUShort => (ushort)Value;
public virtual uint AsUInt => (uint)Value;
public virtual ulong AsULong => (ulong)Value;
public virtual double AsDouble => (double)Value;
public virtual float AsFloat => (float)Value;
public virtual Guid AsGuid => (Guid)Value;
public virtual DateTime AsDateTime => (DateTime)ODBMapper.Default.UnmapValue(typeof(DateTime), this);
public virtual TimeSpan AsTimeSpan => (TimeSpan)ODBMapper.Default.UnmapValue(typeof(TimeSpan), this);
public virtual ODBTypedValue AsTypedValue => this as ODBTypedValue;
public virtual ODBDocument AsDocument => (ODBDocument)this;
public virtual ODBValue Clone()
{
return this;
}
public virtual void Store(BinaryWriter storage)
{
byte[] storageBytes = ToStorage();
storage.Write(storageTypeCode);
storage.Write(storageBytes.Length);
storage.Write(storageBytes, 0, storageBytes.Length);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is ODBValue)
{
ODBValue you = obj as ODBValue;
return Value.Equals(you.Value);
}
return Value.Equals(obj);
}
public virtual bool ValueEquals(ODBValue other)
{
return Equals(other);
}
public static bool operator <(ODBValue a, ODBValue b)
{
return a.CompareTo(b) < 0;
}
public static bool operator >(ODBValue a, ODBValue b)
{
return a.CompareTo(b) > 0;
}
public static bool operator <=(ODBValue a, ODBValue b)
{
return a.CompareTo(b) <= 0;
}
public static bool operator >=(ODBValue a, ODBValue b)
{
return a.CompareTo(b) >= 0;
}
public static bool operator ==(ODBValue a, ODBValue b)
{
if (Object.ReferenceEquals(a, null))
return object.ReferenceEquals(b, null);
return a.CompareTo(b) == 0;
}
public static bool operator !=(ODBValue a, ODBValue b)
{
return a.CompareTo(b) != 0;
}
public static implicit operator ODBValue(ValueType v)
{
return ODBMapper.Default.MapValue(v);
}
public static implicit operator ODBValue(String v)
{
return ODBMapper.Default.MapValue(v);
}
public static ODBValue FromNative(object v)
{
return ODBMapper.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 ODBValue Deserialize(byte[] buffer, ref int offset)
{
int storageTypeCode = BitConverter.ToInt32(buffer, offset);
int storageLength = BitConverter.ToInt32(buffer, offset + 4);
ODBValue value = valueDeserializers[storageTypeCode](buffer, offset + 8, storageLength);
offset += 8 + storageLength;
return value;
}
public static ODBValue 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 int CompareTo(ODBValue other)
{
if (CompareLevel != other.CompareLevel)
return CompareLevel - other.CompareLevel;
return CompareInType(other);
}
public virtual int CompareValueTo(ODBValue other)
{
if (CompareLevel != other.CompareLevel)
return CompareLevel - other.CompareLevel;
return CompareValueInType(other);
}
public override string ToString()
{
return String.Format("[ODBValue Value={0}]", Value);
}
public static int Compare(ODBValue a,ODBValue b)
{
return a.CompareTo(b);
}
public static int CompareValue(ODBValue a, ODBValue b)
{
return a.CompareValueTo(b);
}
static ODBValue()
{
new ODBDocument();
new ODBNull();
new ODBStringValue();
new ODBBool();
new ODBList();
new ODBInteger();
new ODBUInteger();
new ODBLong();
new ODBULong();
new ODBDouble();
new ODBGuid();
new ODBTypedValue();
}
}
}