ln.types/odb/ODBDocument.cs

110 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using ln.types.odb.values;
using System.Linq;
namespace ln.types.odb
{
public class ODBDocument : ODBValue
{
private Dictionary<ODBValue, ODBValue> properties = new Dictionary<ODBValue, ODBValue>();
public ODBDocument()
:base(0x1000)
{
}
public ODBValue ID { get; set; } = new ODBGuid();
public ODBDocument(byte[] bytes,int offset,int length)
:this()
{
int endOffset = offset + length;
ID = ODBValue.Deserialize(bytes, ref offset);
int nProps = BitConverter.ToInt32(bytes, offset);
offset += 4;
for (int n=0;n<nProps;n++)
{
ODBStringValue propName = ODBValue.Deserialize(bytes,ref offset) as ODBStringValue;
ODBValue propValue = ODBValue.Deserialize(bytes, ref offset);
properties.Add(propName, propValue);
}
if (offset > endOffset)
throw new FormatException("ODBDocument deserialization read behind end of buffer");
}
public ODBValue this[ODBValue propName]
{
get
{
if (properties.ContainsKey(propName))
return properties[propName];
return ODBNull.Instance;
}
set
{
if (ODBNull.Instance.Equals(value) && properties.ContainsKey(propName))
{
properties.Remove(propName);
}
else
{
properties[propName] = value;
}
}
}
public IEnumerable<ODBValue> Keys => properties.Keys;
public bool Contains(ODBStringValue propName)
{
return !ODBNull.Instance.Equals(this[propName]);
}
public override byte[] ToStorage()
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
ID.Store(writer);
writer.Write(properties.Count);
foreach (ODBStringValue propName in properties.Keys)
{
ODBValue propValue = properties[propName];
propName.Store(writer);
propValue.Store(writer);
}
return stream.ToArray();
}
public override string ToString()
{
return String.Format("[ODBDocument ID={0} {1}]", ID.ToString(),String.Join(" ",properties.Select(kv=> String.Format("{0}={1}",kv.Key,kv.Value))));
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is ODBDocument)
{
ODBDocument you = obj as ODBDocument;
return ID.Equals(you.ID);
}
return false;
}
static ODBDocument()
{
RegisterDeserializer(0x1000, (b,o,l) => new ODBDocument(b,o,l));
}
}
}