예제 #1
0
        private void SkipPadding(BoundedStream stream)
        {
            var length = GetFieldLength();

            if (length != null)
            {
                if (length > stream.RelativePosition)
                {
                    var padLength = length - stream.RelativePosition;
                    var pad       = new byte[(int)padLength.TotalByteCount];
                    stream.Read(pad, padLength);
                }
            }
        }
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            if (EndOfStream(stream))
            {
                if (TypeNode.IsNullable)
                {
                    return;
                }

                throw new EndOfStreamException();
            }

            Deserialize(stream, TypeNode.GetSerializedType());
        }
예제 #3
0
    internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
    {
        var terminationValue     = GetTerminationValue();
        var terminationChild     = GetTerminationChild();
        var itemTerminationValue = GetItemTerminationValue();
        var itemLengths          = GetItemLengths();

        using var itemLengthEnumerator = itemLengths?.GetEnumerator();
        var count = GetFieldCount() ?? long.MaxValue;

        for (long i = 0; i < count && !EndOfStream(stream); i++)
        {
            if (IsTerminated(stream, terminationChild, terminationValue, eventShuttle))
            {
                break;
            }

            itemLengthEnumerator?.MoveNext();

            // TODO this doesn't allow for deferred eval of endianness in the case of jagged arrays
            // probably extremely rare but still...
            var itemLength  = itemLengthEnumerator?.Current;
            var childStream = itemLength == null
                ? new BoundedStream(stream, Name)
                : new BoundedStream(stream, Name, () => itemLength);

            var child = CreateChildSerializer();

            using (var streamResetter = new StreamResetter(childStream))
            {
                child.Deserialize(childStream, eventShuttle);

                if (child.Value == null)
                {
                    break;
                }

                if (IsTerminated(child, itemTerminationValue))
                {
                    ProcessLastItem(streamResetter, child);
                    break;
                }

                streamResetter.CancelReset();
            }

            Children.Add(child);
        }
    }
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var items = DeserializeCollection(stream, eventShuttle).ToList();

            var itemCount = items.Count;

            /* Create final collection */
            Value = CreateCollection(itemCount);

            /* Copy temp list into final collection */
            for (var i = 0; i < itemCount; i++)
            {
                SetCollectionValue(items[i], i);
            }
        }
        protected static bool IsTerminated(BoundedStream stream, ValueNode terminationChild, object terminationValue,
                                           EventShuttle eventShuttle)
        {
            if (terminationChild != null)
            {
                using var streamResetter = new StreamResetter(stream);
                terminationChild.Deserialize(stream, eventShuttle);

                if (terminationChild.Value.Equals(terminationValue))
                {
                    streamResetter.CancelReset();
                    return(true);
                }
            }
            return(false);
        }
예제 #6
0
        private Task SkipPaddingAsync(BoundedStream stream, CancellationToken cancellationToken)
        {
            var length = GetFieldLength();

            if (length != null)
            {
                if (length > stream.RelativePosition)
                {
                    var padLength = length - stream.RelativePosition;
                    var pad       = new byte[(int)padLength.TotalByteCount];
                    return(stream.ReadAsync(pad, padLength, cancellationToken));
                }
            }

            return(Task.CompletedTask);
        }
예제 #7
0
    internal override void SerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
    {
        var valueStream = (Stream)Value;

        var length = GetConstFieldLength();

        if (length != null)
        {
            var valueStreamlet = new Streamlet(valueStream, valueStream.Position, length.ByteCount);
            valueStreamlet.CopyTo(stream);
        }
        else
        {
            valueStream.CopyTo(stream);
        }
    }
예제 #8
0
    internal override async Task SerializeOverrideAsync(BoundedStream stream, EventShuttle eventShuttle, CancellationToken cancellationToken)
    {
        var valueStream = (Stream)Value;

        var length = GetConstFieldLength();

        if (length != null)
        {
            var valueStreamlet = new Streamlet(valueStream, valueStream.Position, length.ByteCount);
            await valueStreamlet.CopyToAsync(stream, CopyToBufferSize, cancellationToken).ConfigureAwait(false);
        }
        else
        {
            await valueStream.CopyToAsync(stream, CopyToBufferSize, cancellationToken).ConfigureAwait(false);
        }
    }
        protected virtual void ObjectSerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            // check to see if we are actually supposed to be a custom serialization.  This is a side-effect of
            // treating all object members as object nodes.  In the case of sub-types we could later discover we
            // are actually a custom node because the specified subtype implements IBinarySerializable.
            var parent = (TypeNode)TypeNode.Parent;

            if (_valueType != null && (TypeNode.SubtypeBinding != null || parent.ItemSubtypeBinding != null))
            {
                var typeNode = (ObjectTypeNode)TypeNode;
                var subType  = typeNode.GetSubTypeNode(_valueType);

                if (subType is CustomTypeNode)
                {
                    var customValueNode = subType.CreateSerializer((ValueNode)Parent);

                    // this is a little bit of a cheat, but another side-effect of this weird corner case
                    customValueNode.Value = _cachedValue;
                    customValueNode.SerializeOverride(stream, eventShuttle);
                    return;
                }
            }

            var serializableChildren = GetSerializableChildren();

            var lazyContext = CreateLazySerializationContext();

            foreach (var child in serializableChildren)
            {
                // report on serialization start if subscribed
                if (eventShuttle != null && eventShuttle.HasSerializationSubscribers)
                {
                    eventShuttle.OnMemberSerializing(this, child.Name, lazyContext,
                                                     stream.GlobalPosition);
                }

                // serialize child
                child.Serialize(stream, eventShuttle);

                // report on serialization complete if subscribed
                if (eventShuttle != null && eventShuttle.HasSerializationSubscribers)
                {
                    eventShuttle.OnMemberSerialized(this, child.Name, child.BoundValue, lazyContext,
                                                    stream.GlobalPosition);
                }
            }
        }
예제 #10
0
        private static void Seek(BoundedStream BoundedStream)
        {
            while (true)
            {
                var Byte = BoundedStream.ReadByte();

                switch (Byte)
                {
                case 0b00000000:
                    return;

                case 0b11000000:
                    BoundedStream.ReadByte();
                    return;
                }
            }
        }
예제 #11
0
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var typeNode = (EnumTypeNode)TypeNode;
            var enumInfo = typeNode.EnumInfo;

            Deserialize(stream, enumInfo.SerializedType, enumInfo.EnumValueLength);
            var value = GetValue(enumInfo.SerializedType);

            if (enumInfo.ValueEnums != null)
            {
                value = enumInfo.ValueEnums[(string)value];
            }

            var underlyingValue = value.ConvertTo(enumInfo.UnderlyingType);

            Value = Enum.ToObject(TypeNode.BaseSerializedType, underlyingValue);
        }
        internal override void SerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            ObjectSerializeOverride(stream, eventShuttle);

            var length = GetConstFieldLength();

            /* Check if we need to pad out object */
            if (length != null)
            {
                if (length > stream.RelativePosition)
                {
                    var padLength = length - stream.RelativePosition;
                    var pad       = new byte[(int)padLength];
                    stream.Write(pad, 0, pad.Length);
                }
            }
        }
예제 #13
0
        protected override void ObjectSerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var serializationContext = CreateLazySerializationContext();

            var value = BoundValue;

            if (value == null)
            {
                return;
            }

            if (!(value is IBinarySerializable binarySerializable))
            {
                throw new InvalidOperationException("Must implement IBinarySerializable");
            }

            binarySerializable.Serialize(stream, GetFieldEndianness(), serializationContext);
        }
        internal override void SerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            long?itemLength = GetConstFieldItemLength();

            var count = GetConstFieldCount();

            PrimitiveCollectionSerializeOverride(stream, itemLength, count);

            var typeNode = (CollectionTypeNode)TypeNode;

            /* Add termination */
            if (typeNode.TerminationChild != null)
            {
                var terminationChild = typeNode.TerminationChild.CreateSerializer(this);
                terminationChild.Value = typeNode.TerminationValue;
                terminationChild.Serialize(stream, eventShuttle);
            }
        }
예제 #15
0
        protected override void PrimitiveCollectionSerializeOverride(BoundedStream stream, object boundValue,
                                                                     ValueValueNode childSerializer, SerializedType childSerializedType, FieldLength itemLength, long?itemCount)
        {
            var list = (IList)boundValue;

            // Handle const-sized mismatched collections
            PadList(ref list, itemCount);

            foreach (var value in list)
            {
                if (stream.IsAtLimit)
                {
                    break;
                }

                childSerializer.Serialize(stream, value, childSerializedType, itemLength);
            }
        }
예제 #16
0
        internal override void SerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var serializableChildren = GetSerializableChildren().ToList();

            var typeNode = (CollectionTypeNode)TypeNode;

            if (typeNode.ItemSerializeUntilAttribute != null &&
                typeNode.ItemSerializeUntilAttribute.LastItemMode == LastItemMode.Include)
            {
                var lastChild = serializableChildren.LastOrDefault();

                if (lastChild != null)
                {
                    var itemTerminationValue = TypeNode.ItemSerializeUntilBinding.GetBoundValue(this);
                    var itemTerminationChild = lastChild.GetChild(typeNode.ItemSerializeUntilAttribute.ItemValuePath);

                    var convertedItemTerminationValue =
                        itemTerminationValue.ConvertTo(itemTerminationChild.TypeNode.Type);

                    itemTerminationChild.Value = convertedItemTerminationValue;
                }
            }

            foreach (var child in serializableChildren)
            {
                if (stream.IsAtLimit)
                {
                    break;
                }

                var childStream = GetConstFieldItemLength() == null
                    ? stream
                    : new BoundedStream(stream, GetConstFieldItemLength);

                child.Serialize(childStream, eventShuttle);
            }

            if (typeNode.TerminationChild != null)
            {
                var terminationChild = typeNode.TerminationChild.CreateSerializer(this);
                terminationChild.Value = typeNode.TerminationValue;
                terminationChild.Serialize(stream, eventShuttle);
            }
        }
예제 #17
0
    protected override void PrimitiveCollectionSerializeOverride(BoundedStream stream, object boundValue,
                                                                 ValueValueNode childSerializer, SerializedType childSerializedType, FieldLength itemLength, long?itemCount)
    {
        var array = (Array)BoundValue;

        // Handle const-sized mismatched collections
        PadArray(ref array, itemCount);

        for (var i = 0; i < array.Length; i++)
        {
            if (stream.IsAtLimit)
            {
                break;
            }

            var value = array.GetValue(i);
            childSerializer.Serialize(stream, value, childSerializedType, itemLength);
        }
    }
예제 #18
0
        protected override async Task PrimitiveCollectionSerializeOverrideAsync(BoundedStream stream, object boundValue, ValueValueNode childSerializer,
                                                                                SerializedType childSerializedType, FieldLength itemLength, long?itemCount, CancellationToken cancellationToken)
        {
            var list = (IList)boundValue;

            // Handle const-sized mismatched collections
            PadList(ref list, itemCount);

            foreach (var value in list)
            {
                if (stream.IsAtLimit)
                {
                    break;
                }

                await childSerializer.SerializeAsync(stream, value, childSerializedType, itemLength, cancellationToken)
                .ConfigureAwait(false);
            }
        }
예제 #19
0
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var rootStream = GetRootStream(stream);

            var length = GetFieldLength();

            Value = length != null
                ? new Streamlet(rootStream, rootStream.Position, length.Value)
                : new Streamlet(rootStream, rootStream.Position);

            if (length != null)
            {
                stream.Seek(length.Value, SeekOrigin.Current);
            }
            else
            {
                stream.Seek(0, SeekOrigin.End);
            }
        }
        private IEnumerable <object> DeserializeCollection(BoundedStream stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            /* Create single serializer to do all the work */
            var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this);

            var reader = new BinaryReader(stream);
            var childSerializedType = childSerializer.TypeNode.GetSerializedType();

            var count = GetFieldCount() ?? long.MaxValue;

            long?itemLength = GetFieldItemLength();

            var terminationValue = typeNode.TerminationValue;
            var terminationChild = typeNode.TerminationChild?.CreateSerializer(this);

            for (long i = 0; i < count; i++)
            {
                if (EndOfStream(stream))
                {
                    break;
                }

                /* Check termination case */
                if (terminationChild != null)
                {
                    using (var streamResetter = new StreamResetter(stream))
                    {
                        terminationChild.Deserialize(stream, eventShuttle);

                        if (terminationChild.Value.Equals(terminationValue))
                        {
                            streamResetter.CancelReset();
                            break;
                        }
                    }
                }

                childSerializer.Deserialize(reader, childSerializedType, itemLength);
                yield return(childSerializer.GetValue(childSerializedType));
            }
        }
        internal override async Task SerializeOverrideAsync(BoundedStream stream, EventShuttle eventShuttle, CancellationToken cancellationToken)
        {
            var serializableChildren = GetSerializableChildren().ToList();

            SetTerminationValue(serializableChildren);

            foreach (var child in serializableChildren)
            {
                if (stream.IsAtLimit)
                {
                    break;
                }

                var childStream = new BoundedStream(stream, GetConstFieldItemLength);

                await child.SerializeAsync(childStream, eventShuttle, true, cancellationToken).ConfigureAwait(false);
            }

            await SerializeTerminationAsync(stream, eventShuttle, cancellationToken);
        }
        internal override void SerializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var serializableChildren = GetSerializableChildren().ToList();

            SetTerminationValue(serializableChildren);

            foreach (var child in serializableChildren)
            {
                if (stream.IsAtLimit)
                {
                    break;
                }

                var childStream = new BoundedStream(stream, GetConstFieldItemLength);

                child.Serialize(childStream, eventShuttle);
            }

            SerializeTermination(stream, eventShuttle);
        }
예제 #23
0
    protected override async Task PrimitiveCollectionSerializeOverrideAsync(BoundedStream stream, object boundValue, ValueValueNode childSerializer,
                                                                            SerializedType childSerializedType, FieldLength itemLength, long?itemCount, CancellationToken cancellationToken)
    {
        var array = (Array)BoundValue;

        // Handle const-sized mismatched collections
        PadArray(ref array, itemCount);

        for (var i = 0; i < array.Length; i++)
        {
            if (stream.IsAtLimit)
            {
                break;
            }

            var value = array.GetValue(i);
            await childSerializer.SerializeAsync(stream, value, childSerializedType, itemLength, cancellationToken)
            .ConfigureAwait(false);
        }
    }
예제 #24
0
    internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
    {
        var rootStream = GetRootStream(stream);

        var length = GetFieldLength();

        Value = length != null
            ? new Streamlet(rootStream, rootStream.Position, length.ByteCount)
            : new Streamlet(rootStream, rootStream.Position);

        if (length != null)
        {
            var nullStream = new NullStream();
            stream.CopyTo(nullStream, (int)length.ByteCount, CopyToBufferSize);
        }
        else
        {
            stream.Seek(0, SeekOrigin.End);
        }
    }
예제 #25
0
        public void TestRead()
        {
            using (MemoryStream baseStream = new MemoryStream(_buff)) {
                using (BoundedStream boundedStream = new BoundedStream(baseStream, 10, 100)) {
                    Assert.AreEqual((boundedStream.Position + boundedStream.LowerBound) % 256, boundedStream.ReadByte() % 256);
                    Assert.AreEqual((boundedStream.Position + boundedStream.LowerBound) % 256, boundedStream.ReadByte() % 256);

                    // Partial reads to upper bound
                    boundedStream.Seek(1, SeekOrigin.End);
                    byte[] buff = new byte[2] {
                        0, 200
                    };
                    byte[] expectedBuff = new byte[2] {
                        99, 200
                    };

                    boundedStream.Read(buff, 0, buff.Length);
                    CollectionAssert.AreEqual(expectedBuff, buff);
                }
            }
        }
예제 #26
0
    internal BoundedStream(Stream source, string name, Func <FieldLength> maxLengthDelegate = null)
    {
        Source             = source ?? throw new ArgumentNullException(nameof(source));
        _name              = name;
        _maxLengthDelegate = maxLengthDelegate;

        /* Store for performance */
        _canSeek = source.CanSeek;

        if (_canSeek)
        {
            _length = source.Length;
        }

        _root = this;

        while (_root.Source is BoundedStream root)
        {
            _root = root;
        }
    }
예제 #27
0
        private void SaveToStream(SaveMode saveMode, Stream destination, Stream serverCopy)
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();

            xmlWriterSettings.CloseOutput = false;
            if (saveMode != SaveMode.NoConflictResolution && serverCopy.Length != 0L)
            {
                try
                {
                    using (Stream stream = new BoundedStream(serverCopy, false, 0L, 524288L))
                    {
                        using (StreamReader streamReader = new StreamReader(stream, true))
                        {
                            using (XmlReader xmlReader = XmlReader.Create(streamReader))
                            {
                                xmlWriterSettings.Encoding = (streamReader.CurrentEncoding ?? Encoding.UTF8);
                                using (XmlWriter xmlTextWriter = Util.GetXmlTextWriter(destination, xmlWriterSettings))
                                {
                                    new MasterCategoryListSerializer(xmlReader).SerializeUsingSource(this, xmlTextWriter);
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (CorruptDataException inner)
                {
                    if (saveMode == SaveMode.FailOnAnyConflict)
                    {
                        throw new SaveConflictException(ServerStrings.ExMclCannotBeResolved, inner);
                    }
                }
            }
            destination.Position = 0L;
            destination.SetLength(0L);
            using (XmlWriter xmlWriter = XmlWriter.Create(destination, xmlWriterSettings))
            {
                MasterCategoryListSerializer.Serialize(this, xmlWriter);
            }
        }
예제 #28
0
        private static MemoryStream GetRootStream(BoundedStream BoundedStream)
        {
            var Root = BoundedStream.Source;

            while (true)
            {
                switch (Root)
                {
                case BoundedStream Bounded:
                {
                    Root = Bounded.Source;

                    continue;
                }

                case MemoryStream Memory:
                {
                    return(Memory);
                }
                }
            }
        }
예제 #29
0
    internal override async Task DeserializeOverrideAsync(BoundedStream stream, EventShuttle eventShuttle,
                                                          CancellationToken cancellationToken)
    {
        var rootStream = GetRootStream(stream);

        var length = GetFieldLength();

        Value = length != null
            ? new Streamlet(rootStream, rootStream.Position, length.ByteCount)
            : new Streamlet(rootStream, rootStream.Position);

        if (length != null)
        {
            var nullStream = new NullStream();
            await stream.CopyToAsync(nullStream, (int)length.ByteCount, CopyToBufferSize, cancellationToken)
            .ConfigureAwait(false);
        }
        else
        {
            stream.Seek(0, SeekOrigin.End);
        }
    }
예제 #30
0
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            ResolveValueType();

            // skip over if null (this may happen if subtypes are unknown during deserialization)
            if (_valueType != null)
            {
                GenerateChildren();
                ThrowIfUnordered();

                try
                {
                    ObjectDeserializeOverride(stream, eventShuttle);
                }
                catch (EndOfStreamException)
                {
                    // this is ok but we can't consider this object fully formed.
                    _valueType = null;
                }
            }

            SkipPadding(stream);
        }