Example #1
0
        private bool BytesMatch(long offset,
                                int toCheck,
                                Stream source,
                                Stream target,
                                IFileResource sourceResource,
                                IFileResource targetResource)
        {
            using var sourceResetter = new StreamResetter(source);
            using var sourceData     = BufferPool.Borrow(toCheck);
            if (!TryReadBytes(source, offset, toCheck, sourceData.Data, sourceResource))
            {
                Log($"can't read bytes {offset} - {toCheck} of source {sourceResource.RelativePath}");
                return(false);
            }

            using var targetResetter = new StreamResetter(target);
            using var targetData     = BufferPool.Borrow(toCheck);
            if (!TryReadBytes(target, offset, toCheck, targetData.Data, targetResource))
            {
                Log($"can't read bytes {offset} - {toCheck} of target {targetResource.RelativePath}");
                return(false);
            }

            // buffer-pool can give back a bigger buffer than required
            // -> have to ensure that we only check byte-for-byte against
            //    the tail {toCheck} bytes
            return(sourceData.Data
                   .Take(toCheck)
                   .SequenceEqual(
                       targetData.Data.Take(toCheck)
                       ));
        }
        public override void DeserializeOverride(StreamLimiter stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            var count = TypeNode.FieldCountBinding != null?Convert.ToInt32(TypeNode.FieldCountBinding.GetValue(this)) : int.MaxValue;

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

            for (int i = 0; i < count; i++)
            {
                if (ShouldTerminate(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;
                        }
                    }
                }

                var child = typeNode.Child.CreateSerializer(this);
                child.Deserialize(stream, eventShuttle);

                /* Check child termination case */
                if (TypeNode.ItemSerializeUntilBinding != null)
                {
                    var itemTerminationValue = TypeNode.ItemSerializeUntilBinding.GetValue(this);
                    var itemTerminationChild = child.GetChild(TypeNode.ItemSerializeUntilAttribute.ItemValuePath);

                    if (itemTerminationChild.Value.Equals(itemTerminationValue))
                    {
                        if (!TypeNode.ItemSerializeUntilAttribute.ExcludeLastItem)
                        {
                            Children.Add(child);
                        }
                        break;
                    }
                }

                Children.Add(child);
            }
        }
        internal override async Task DeserializeOverrideAsync(BoundedStream stream, EventShuttle eventShuttle,
                                                              CancellationToken cancellationToken)
        {
            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))
                    {
                        await child.DeserializeAsync(childStream, eventShuttle, cancellationToken)
                        .ConfigureAwait(false);

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

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

                        streamResetter.CancelReset();
                    }

                    Children.Add(child);
                }
            }
        }
        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);
        }
        private void ProcessLastItem(StreamResetter streamResetter, ValueNode child)
        {
            switch (TypeNode.ItemSerializeUntilAttribute.LastItemMode)
            {
            case LastItemMode.Include:
                streamResetter.CancelReset();
                Children.Add(child);
                break;

            case LastItemMode.Discard:
                streamResetter.CancelReset();
                break;

            case LastItemMode.Defer:
                // stream will reset
                break;
            }
        }
        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));
            }
        }
        public override void DeserializeOverride(StreamLimiter stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            var count = TypeNode.FieldCountBinding != null ? Convert.ToInt32(TypeNode.FieldCountBinding.GetValue(this)) : int.MaxValue;

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

            IEnumerable<int> itemLengths = null;
            if (TypeNode.ItemLengthBinding != null)
            {
                var itemLengthValue = TypeNode.ItemLengthBinding.GetValue(this);

                var enumerableItemLengthValue = itemLengthValue as IEnumerable;

                itemLengths = enumerableItemLengthValue != null ?
                    enumerableItemLengthValue.Cast<object>().Select(Convert.ToInt32) :
                    GetInfiniteSequence(Convert.ToInt32(itemLengthValue));
            }

            IEnumerator<int> itemLengthEnumerator = null;

            try
            {
                if (itemLengths != null)
                    itemLengthEnumerator = itemLengths.GetEnumerator();

                for (int i = 0; i < count; i++)
                {
                    if (ShouldTerminate(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;
                            }
                        }
                    }

                    var child = typeNode.Child.CreateSerializer(this);

                    if (itemLengthEnumerator != null)
                        itemLengthEnumerator.MoveNext();

                    var childStream = itemLengthEnumerator == null
                        ? stream
                        : new StreamLimiter(stream, itemLengthEnumerator.Current);

                    child.Deserialize(childStream, eventShuttle);

                    /* Check child termination case */
                    if (TypeNode.ItemSerializeUntilBinding != null)
                    {
                        var itemTerminationValue = TypeNode.ItemSerializeUntilBinding.GetValue(this);
                        var itemTerminationChild = child.GetChild(TypeNode.ItemSerializeUntilAttribute.ItemValuePath);

                        if (itemTerminationChild.Value.Equals(itemTerminationValue))
                        {
                            if (!TypeNode.ItemSerializeUntilAttribute.ExcludeLastItem)
                            {
                                Children.Add(child);
                            }
                            break;
                        }
                    }

                    Children.Add(child);
                }
            }
            finally
            {
                if (itemLengthEnumerator != null)
                    itemLengthEnumerator.Dispose();
            }
        }
        public override void DeserializeOverride(StreamLimiter stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            /* Create temporary list */
            Type collectionType = typeof(List<>).MakeGenericType(typeNode.ChildType);
            var collection = (IList)Activator.CreateInstance(collectionType);

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

            var reader = new EndianAwareBinaryReader(stream, Endianness);
            var childSerializedType = childSerializer.TypeNode.GetSerializedType();

            var count = TypeNode.FieldCountBinding != null ? Convert.ToInt32(TypeNode.FieldCountBinding.GetValue(this)) : int.MaxValue;

            int? itemLength = null;
            if (TypeNode.ItemLengthBinding != null)
                itemLength = Convert.ToInt32(TypeNode.ItemLengthBinding.GetValue(this));

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

            int itemCount = 0;
            for (int i = 0; i < count; i++)
            {
                if (ShouldTerminate(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;
                        }
                    }
                }

                var value = childSerializer.Deserialize(reader, childSerializedType, itemLength);
                collection.Add(value);

                itemCount++;
            }

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

            /* Copy temp list into final collection */
            for (int i = 0; i < itemCount; i++)
                SetCollectionValue(collection[i], i);
        }
Example #9
0
        public override void DeserializeOverride(StreamLimiter stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            /* Create temporary list */
            Type collectionType = typeof(List <>).MakeGenericType(typeNode.ChildType);
            var  collection     = (IList)Activator.CreateInstance(collectionType);

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

            var reader = new EndianAwareBinaryReader(stream, Endianness);
            var childSerializedType = dummyChild.TypeNode.GetSerializedType();

            var count = TypeNode.FieldCountBinding != null?Convert.ToInt32(TypeNode.FieldCountBinding.GetValue(this)) : int.MaxValue;

            int?length = null;

            if (TypeNode.ItemLengthBinding != null)
            {
                length = Convert.ToInt32(TypeNode.ItemLengthBinding.GetValue(this));
            }

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

            int itemCount = 0;

            for (int i = 0; i < count; i++)
            {
                if (ShouldTerminate(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;
                        }
                    }
                }

                var value = dummyChild.Deserialize(reader, childSerializedType, length);
                collection.Add(value);

                itemCount++;
            }

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

            /* Copy temp list into final collection */
            for (int i = 0; i < itemCount; i++)
            {
                SetCollectionValue(collection[i], i);
            }
        }
Example #10
0
        internal override void DeserializeOverride(BoundedStream stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

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

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

            object itemTerminationValue = null;

            if (TypeNode.ItemSerializeUntilBinding != null)
            {
                itemTerminationValue = TypeNode.ItemSerializeUntilBinding.GetValue(this);
            }

            IEnumerable <long> itemLengths = null;

            if (TypeNode.ItemLengthBindings != null)
            {
                var itemLengthValue = TypeNode.ItemLengthBindings.GetValue(this);

                var enumerableItemLengthValue = itemLengthValue as IEnumerable;

                itemLengths = enumerableItemLengthValue?.Cast <object>().Select(Convert.ToInt64) ??
                              GetInfiniteSequence(Convert.ToInt64(itemLengthValue));
            }

            IEnumerator <long> itemLengthEnumerator = null;

            try
            {
                if (itemLengths != null)
                {
                    itemLengthEnumerator = itemLengths.GetEnumerator();
                }

                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;
                            }
                        }
                    }

                    var child = typeNode.Child.CreateSerializer(this);

                    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 ? stream : new BoundedStream(stream, () => itemLength);

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

                        /* Check child termination case */
                        if (TypeNode.ItemSerializeUntilBinding != null)
                        {
                            var itemTerminationChild = child.GetChild(TypeNode.ItemSerializeUntilAttribute.ItemValuePath);

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

                            if (itemTerminationChild.Value.Equals(convertedItemTerminationValue))
                            {
#pragma warning disable 618
                                if (TypeNode.ItemSerializeUntilAttribute.ExcludeLastItem)
#pragma warning restore 618
                                {
                                    streamResetter.CancelReset();
                                    break;
                                }

                                switch (TypeNode.ItemSerializeUntilAttribute.LastItemMode)
                                {
                                case LastItemMode.Include:
                                    streamResetter.CancelReset();
                                    Children.Add(child);
                                    break;

                                case LastItemMode.Discard:
                                    streamResetter.CancelReset();
                                    break;

                                case LastItemMode.Defer:
                                    // stream will reset
                                    break;
                                }

                                break;
                            }
                        }

                        streamResetter.CancelReset();
                    }

                    Children.Add(child);
                }
            }
            finally
            {
                itemLengthEnumerator?.Dispose();
            }
        }