public int SerializeBody(ref byte[] bytes, int offset, T instance, IFormatterResolver formatterResolver, bool fullSerialization, out bool dataWritten) { var startOffset = offset; var meta = DarkMeta.Get(instance.GetType()); var count = 2; if (fullSerialization) { count += meta.DeepLevel; if (!meta.Flags.IsSerializable()) { count--; } } offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, count); offset += MessagePackBinary.WriteInt32(ref bytes, offset, (int)meta.TypeIndex); offset += formatterResolver.GetFormatter <Guid>().Serialize(ref bytes, offset, instance.Guid, formatterResolver); dataWritten = false; if (fullSerialization) { var state = Serializer.Instance.State; state.StartLocalGroup(out int previousOffset); var writtenSize = meta.WriteMembers(state.Settings.Flags, instance, ref bytes, offset, formatterResolver); bool skipData = false; if (state.WriteOnlyChanged) { if (meta.Type == typeof(Entity) && FieldListFormatter.LastFieldWritten == 0) { var isArray16 = bytes[offset + writtenSize - 2] == MessagePackCode.Array16; var length = isArray16 ? writtenSize - 3 : writtenSize - 1; skipData = instance.OriginalBytes.BeginingEquals(bytes, offset, length); } else { skipData = instance.OriginalBytes.Equals(bytes, offset, writtenSize); } } if (skipData) { state.UnrollLocalGroup(); MessagePackBinary.ReWriteArrayHeaderDownwards(ref bytes, startOffset, count - 1); } else { offset += writtenSize; dataWritten = writtenSize > 1; } state.RestoreLocalGroup(previousOffset); } return(offset - startOffset); }
public int Serialize(ref byte[] bytes, int offset, ForwardDefinitionList definitionList, IFormatterResolver formatterResolver) { if (definitionList == null) { MessagePackBinary.WriteNil(ref bytes, offset); return(1); } var startOffset = offset; var itemsCount = definitionList.Count * 2; offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, itemsCount); var state = Serializer.Instance.State; // declarations foreach (var instance in definitionList) { state.RegNewObjectReference(instance); offset += GuidObjectFormatter.SerializeBody(ref bytes, offset, instance, formatterResolver, false, out bool dataWritten); } // definitions foreach (var instance in definitionList) { state.ObjectInstances.Add(null); var writtenCount = GuidObjectFormatter.SerializeBody(ref bytes, offset, instance, formatterResolver, true, out bool dataWritten); if (dataWritten) { offset += writtenCount; } else { state.ObjectInstances.RemoveAt(state.ObjectInstances.Count - 1); itemsCount--; } } MessagePackBinary.ReWriteArrayHeaderDownwards(ref bytes, startOffset, itemsCount); return(offset - startOffset); }
public int Serialize(ref byte[] bytes, int offset, FieldList list, IFormatterResolver formatterResolver) { if (list == null) { return(MessagePackBinary.WriteNil(ref bytes, offset)); } var startOffset = offset; offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, (list.Count + 1) * 3); // plus one in case of DeletedKeys var state = Serializer.Instance.State; var previousOffset = state.LocalOffset; var comparer = new FieldComparer(list.OriginalBytes); var itemCount = 0; foreach (var pair in list) { bool isValueProducer = pair.Value != null && pair.Value is ValueProducer; state.StartLocalGroup(); var groupStartOffset = offset; var typeId = (int)pair.Key.TypeId; offset += MessagePackBinary.WriteInt32(ref bytes, offset, isValueProducer ? -typeId : typeId); offset += MessagePackBinary.WriteInt32(ref bytes, offset, pair.Key.MemberId); var bodyLength = 0; if (isValueProducer) { bodyLength = formatterResolver.GetFormatter <ValueProducer>().Serialize(ref bytes, offset, (ValueProducer)pair.Value, formatterResolver); } else { bodyLength = FieldMeta.Get(pair.Key).Serialize(pair.Value, ref bytes, offset, formatterResolver); } if (state.WriteOnlyChanged && !comparer.IsChanged(pair.Key, bytes, offset, bodyLength)) { state.UnrollLocalGroup(); offset = groupStartOffset; } else { offset += bodyLength; itemCount++; } } if (state.WriteOnlyChanged) { comparer.RollToTheEnd(); if (comparer.DeletedKeys != null) { offset += MessagePackBinary.WriteInt32(ref bytes, offset, (int)TypeIndex.SystemField); offset += MessagePackBinary.WriteInt32(ref bytes, offset, (int)SystemField.DeletedKeys); offset += formatterResolver.GetFormatter <List <FieldKey> >().Serialize(ref bytes, offset, comparer.DeletedKeys, formatterResolver); itemCount++; } } LastFieldWritten = itemCount; MessagePackBinary.ReWriteArrayHeaderDownwards(ref bytes, startOffset, itemCount * 3); // write real count state.RestoreLocalGroup(previousOffset); return(offset - startOffset); }