예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }