153 lines
4.3 KiB
C#
153 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace ln.objects.catalog
|
|
{
|
|
public class ODBObject : ODBEntity
|
|
{
|
|
private Dictionary<ODBEntity, ODBEntity> properties = new Dictionary<ODBEntity, ODBEntity>();
|
|
|
|
public ODBObject()
|
|
:base(0x0005)
|
|
{ }
|
|
|
|
public ODBObject(byte[] bytes)
|
|
: this(bytes, 0, bytes.Length)
|
|
{}
|
|
public ODBObject(byte[] bytes,int offset,int length)
|
|
:this()
|
|
{
|
|
int endOffset = offset + length;
|
|
|
|
int nProps = BitConverter.ToInt32(bytes, offset);
|
|
offset += 4;
|
|
|
|
for (int n=0;n<nProps;n++)
|
|
{
|
|
ODBEntity propName = ODBEntity.Deserialize(bytes,ref offset);
|
|
ODBEntity propValue = ODBEntity.Deserialize(bytes, ref offset);
|
|
properties.Add(propName, propValue);
|
|
}
|
|
|
|
if (offset > endOffset)
|
|
throw new FormatException("object deserialization read behind end of buffer");
|
|
}
|
|
|
|
public ODBEntity this[ODBEntity propName]
|
|
{
|
|
get
|
|
{
|
|
if (properties.ContainsKey(propName))
|
|
return properties[propName];
|
|
return ODBNull.Instance;
|
|
}
|
|
set
|
|
{
|
|
if (ODBNull.Instance.Equals(value))
|
|
{
|
|
if (properties.ContainsKey(propName))
|
|
properties.Remove(propName);
|
|
}
|
|
else
|
|
{
|
|
properties[propName] = value;
|
|
}
|
|
}
|
|
}
|
|
public ODBEntity this[string propName]
|
|
{
|
|
get => this[new ODBStringValue(propName)];
|
|
set => this[new ODBStringValue(propName)] = value;
|
|
}
|
|
|
|
public IEnumerable<ODBEntity> Keys => properties.Keys;
|
|
|
|
public bool Contains(string propName) => Contains(new ODBStringValue(propName));
|
|
public bool Contains(ODBEntity propName)
|
|
{
|
|
return !ODBNull.Instance.Equals(this[propName]);
|
|
}
|
|
|
|
public override ODBEntity Clone()
|
|
{
|
|
ODBObject clone = new ODBObject();
|
|
foreach (ODBEntity fieldName in properties.Keys)
|
|
{
|
|
clone[fieldName] = this[fieldName].Clone();
|
|
}
|
|
return clone;
|
|
}
|
|
|
|
public void CloneTo(ODBObject target)
|
|
{
|
|
target.properties.Clear();
|
|
foreach (ODBEntity fieldName in properties.Keys)
|
|
{
|
|
target[fieldName] = this[fieldName].Clone();
|
|
}
|
|
}
|
|
|
|
public override byte[] Serialize()
|
|
{
|
|
MemoryStream stream = new MemoryStream();
|
|
BinaryWriter writer = new BinaryWriter(stream);
|
|
|
|
writer.Write(properties.Count);
|
|
|
|
foreach (ODBEntity propName in properties.Keys)
|
|
{
|
|
ODBEntity propValue = properties[propName];
|
|
propName.Serialize(writer);
|
|
propValue.Serialize(writer);
|
|
}
|
|
|
|
return stream.ToArray();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return String.Format("[Object {0}]", String.Join(" ",properties.Select(kv=> String.Format("{0}={1}",kv.Key,kv.Value))));
|
|
}
|
|
public override string ToTreeString(int indent)
|
|
{
|
|
indent += 2;
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
stringBuilder.AppendFormat("{0} Identity={1} Count={2}", GetType().Name, Identity, properties.Count);
|
|
foreach (ODBValue key in properties.Keys)
|
|
{
|
|
stringBuilder.AppendLine();
|
|
stringBuilder.AppendFormat("{0}{1,-32}: {2}", new String(' ', indent), key, properties[key].ToTreeString(indent));
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
protected override int compare(ODBEntity e)
|
|
{
|
|
ODBObject other = e as ODBObject;
|
|
ODBEntity[] keys = Keys.Union(other.Keys).ToArray();
|
|
|
|
foreach (ODBEntity key in keys)
|
|
{
|
|
ODBEntity mine = this[key];
|
|
ODBEntity yours = other[key];
|
|
|
|
int c = mine.CompareTo(yours);
|
|
|
|
if (c != 0)
|
|
return c;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static ODBObject()
|
|
{
|
|
RegisterDeserializer(0x0005, (b,o,l) => new ODBObject(b,o,l));
|
|
}
|
|
}
|
|
}
|