public override void Serialize(Stream stream, NomadObject data) { Context.Begin(); // make sure the cache is ready NomadCache.Clear(); var bs = (stream as BinaryStream) ?? new BinaryStream(stream); Context.Log("Serializing data..."); WriteHeader(bs, data); switch (Format) { case FormatType.Resource: case FormatType.Objects: WriteObject_FmtA(bs, data); break; case FormatType.Entities: DescriptorTag.GlobalFlags |= DescriptorFlags.Use24Bit; WriteObject_FmtB(bs, data); DescriptorTag.GlobalFlags &= ~DescriptorFlags.Use24Bit; break; } Context.End(); }
protected void WriteObject_FmtA(BinaryStream stream, NomadObject obj) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var ptr = (int)stream.Position; var idx = NomadCache.Find(obj); if (idx != -1) { var cached = NomadCache.Refs[idx]; var tag = DescriptorTag.CreateReference(Context.GetIdx(cached), ReferenceType.Index); tag.WriteTo(stream); } else { var nChildren = DescriptorTag.Create(obj.Children.Count); var nAttributes = DescriptorTag.Create(obj.Attributes.Count); Context.AddRef(obj, ptr); nChildren.WriteTo(stream); stream.Write(obj.Id.Hash); if (obj.IsRml) { WriteRmlData(stream, obj); } else { nAttributes.WriteTo(stream); Context.State = ContextStateType.Member; foreach (var attr in obj.Attributes) { WriteAttribute_FmtA(stream, attr); } foreach (var child in obj.Children) { WriteObject_FmtA(stream, child); } } } }
protected void WriteObject_FmtB(BinaryStream stream, NomadObject obj) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var ptr = (int)stream.Position; var idx = NomadCache.Find(obj); if (idx != -1) { var cached = NomadCache.Refs[idx]; var offset = (int)Context.GetPtr(cached); var tag = DescriptorTag.CreateReference(offset, ReferenceType.Offset); tag.WriteTo(stream); } else { var reference = new NomadReference(obj); var cached = reference.Get(); Context.AddRef(cached, ptr); var count = DescriptorTag.Create(obj.Children.Count); count.WriteTo(stream); stream.Write(obj.Id.Hash); WriteAttributesList_FmtB(stream, obj); foreach (var child in obj.Children) { WriteObject_FmtB(stream, child); } } }
public NomadReference(NomadData data) { Index = NomadCache.Register(data, out long hash); Hash = hash; }