183 lines
4.8 KiB
C#
183 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using ln.types.odb.values;
|
|
using System.Linq;
|
|
namespace ln.types.odb.ng
|
|
{
|
|
public class Document : ODBValue
|
|
{
|
|
private Dictionary<ODBValue, ODBValue> properties = new Dictionary<ODBValue, ODBValue>();
|
|
|
|
public Document()
|
|
:base(0x1001)
|
|
{
|
|
ID = Guid.NewGuid();
|
|
}
|
|
|
|
public Document(Guid id)
|
|
:base(0x1001)
|
|
{
|
|
ID = id;
|
|
}
|
|
|
|
public Guid ID { get; }
|
|
public DateTime StorageTimeStamp { get; set; }
|
|
|
|
public ODBCollection Collection { get; internal set; }
|
|
|
|
public Document(Guid documentID,byte[] bytes)
|
|
: this(documentID, bytes, 0, bytes.Length)
|
|
{ }
|
|
public Document(Guid documentID,byte[] bytes,int offset,int length)
|
|
:this(documentID)
|
|
{
|
|
ID = documentID;
|
|
|
|
int endOffset = offset + length;
|
|
int nProps = BitConverter.ToInt32(bytes, offset);
|
|
offset += 4;
|
|
|
|
for (int n=0;n<nProps;n++)
|
|
{
|
|
ODBValue propName = ODBValue.Deserialize(bytes,ref offset);
|
|
ODBValue propValue = ODBValue.Deserialize(bytes, ref offset);
|
|
properties.Add(propName, propValue);
|
|
}
|
|
|
|
if (offset > endOffset)
|
|
throw new FormatException("Document 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))
|
|
{
|
|
if (properties.ContainsKey(propName))
|
|
properties.Remove(propName);
|
|
}
|
|
else
|
|
{
|
|
properties[propName] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public IEnumerable<ODBValue> Keys => properties.Keys;
|
|
|
|
public override int CompareLevel => 128;
|
|
|
|
public bool Contains(ODBValue propName)
|
|
{
|
|
return !ODBNull.Instance.Equals(this[propName]);
|
|
}
|
|
|
|
public override ODBValue Clone()
|
|
{
|
|
Document clone = new Document(ID);
|
|
foreach (ODBValue fieldName in properties.Keys)
|
|
{
|
|
clone[fieldName] = this[fieldName].Clone();
|
|
}
|
|
return clone;
|
|
}
|
|
|
|
public override byte[] ToStorage()
|
|
{
|
|
MemoryStream stream = new MemoryStream();
|
|
BinaryWriter writer = new BinaryWriter(stream);
|
|
|
|
writer.Write(ID.ToByteArray());
|
|
writer.Write(properties.Count);
|
|
|
|
foreach (ODBValue propName in properties.Keys)
|
|
{
|
|
ODBValue propValue = properties[propName];
|
|
propName.Store(writer);
|
|
propValue.Store(writer);
|
|
}
|
|
|
|
return stream.ToArray();
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return String.Format("[Document 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 Document)
|
|
{
|
|
Document you = obj as Document;
|
|
return ID.Equals(you.ID);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool ContentEquals(Document other)
|
|
{
|
|
if (object.ReferenceEquals(null, other))
|
|
return false;
|
|
|
|
ODBValue[] keys = Keys.Union(other.Keys).ToArray();
|
|
|
|
foreach (ODBValue key in keys)
|
|
{
|
|
ODBValue value = this[key];
|
|
if (!value.ValueEquals(other[key]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override bool ValueEquals(ODBValue other)
|
|
{
|
|
return ContentEquals(other as Document);
|
|
}
|
|
|
|
public int CompareContent(Document other)
|
|
{
|
|
ODBValue[] keys = Keys.Union(other.Keys).ToArray();
|
|
|
|
foreach (ODBValue key in keys)
|
|
{
|
|
ODBValue mine = this[key];
|
|
ODBValue yours = other[key];
|
|
|
|
int c = ODBValue.Compare(mine, yours);
|
|
|
|
if (c != 0)
|
|
return c;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public override int CompareInType(ODBValue other)
|
|
{
|
|
return CompareContent(other as Document);
|
|
}
|
|
public override int CompareValueInType(ODBValue other)
|
|
{
|
|
return CompareContent(other as Document);
|
|
}
|
|
|
|
static Document()
|
|
{
|
|
RegisterDeserializer(0x1001, (b,o,l) => new Document(Guid.Empty,b,o,l));
|
|
}
|
|
}
|
|
}
|