コード例 #1
0
        private bool PrepareMetadata(StreamScope scope)
        {
            // The metadata stream can either be inlined or compressed
            var token = ReadToken();

            if (token == ArchiveMetadataToken.PackedHeader)
            {
                var streams = ReadPackedStreams();

                // Compressed metadata without content is odd but allowed.
                if (streams.IsDefaultOrEmpty)
                {
                    return(false);
                }

                // Compressed metadata with multiple streams is not allowed.
                if (streams.Length != 1)
                {
                    throw new InvalidDataException();
                }

                // Switch over to the decoded metadata stream.
                scope.SetSource(streams[0]);
                token = ReadToken();
            }

            // The metadata stream must start with this token.
            if (token != ArchiveMetadataToken.Header)
            {
                throw new InvalidDataException();
            }

            return(true);
        }
コード例 #2
0
        /// <summary>
        /// This method is called when a stream is disposed.
        /// </summary>
        void IODataStreamListener.StreamDisposed()
        {
            Debug.Assert(this.State == ODataReaderState.Stream, "Stream was disposed when not in ReaderState.Stream state.");
            StreamScope scope = this.CurrentScope as StreamScope;

            Debug.Assert(scope != null, "Stream disposed when not in stream scope");
            Debug.Assert(scope.StreamingState == StreamingState.Streaming, "StreamDisposed called when reader was not streaming");
            scope.StreamingState = StreamingState.Completed;
        }
コード例 #3
0
        /// <summary>
        /// Creates a stream for reading an inline stream property.
        /// </summary>
        /// <returns>A stream for reading the stream property.</returns>
        public override sealed Stream CreateReadStream()
        {
            if (this.State != ODataReaderState.Stream)
            {
                throw new ODataException(Strings.ODataReaderCore_CreateReadStreamCalledInInvalidState);
            }

            StreamScope scope = this.CurrentScope as StreamScope;

            Debug.Assert(scope != null, "ODataReaderState.Stream when Scope is not a StreamScope");
            if (scope.StreamingState != StreamingState.None)
            {
                throw new ODataException(Strings.ODataReaderCore_CreateReadStreamCalledInInvalidState);
            }

            scope.StreamingState = StreamingState.Streaming;
            return(new ODataNotificationStream(this.InterceptException(this.CreateReadStreamImplementation), this));
        }
コード例 #4
0
        /// <summary>
        /// Verifies that calling Read is valid.
        /// </summary>
        /// <param name="synchronousCall">true if the call is to be synchronous; false otherwise.</param>
        private void VerifyCanRead(bool synchronousCall)
        {
            this.inputContext.VerifyNotDisposed();
            this.VerifyCallAllowed(synchronousCall);

            if (this.State == ODataReaderState.Exception || this.State == ODataReaderState.Completed)
            {
                throw new ODataException(Strings.ODataReaderCore_ReadOrReadAsyncCalledInInvalidState(this.State));
            }

            if (this.State == ODataReaderState.Stream)
            {
                StreamScope scope = this.CurrentScope as StreamScope;
                Debug.Assert(scope != null, "In stream state without a stream scope");
                if (scope.StreamingState != StreamingState.Completed)
                {
                    throw new ODataException(Strings.ODataReaderCore_ReadCalledWithOpenStream);
                }
            }
        }
コード例 #5
0
        /// <summary>Asynchronously creates a <see cref="TextReader"/> for reading an inline string property.</summary>
        /// <returns>
        /// A task that represents the asynchronous operation.
        /// The value of the TResult parameter contains a <see cref="TextReader"/> for reading the string property.
        /// </returns>
        public override async Task <TextReader> CreateTextReaderAsync()
        {
            if (this.State != ODataReaderState.Stream)
            {
                throw new ODataException(Strings.ODataReaderCore_CreateTextReaderCalledInInvalidState);
            }

            StreamScope scope = this.CurrentScope as StreamScope;

            Debug.Assert(scope != null, "ODataReaderState.Stream when Scope is not a StreamScope");
            if (scope.StreamingState != StreamingState.None)
            {
                throw new ODataException(Strings.ODataReaderCore_CreateReadStreamCalledInInvalidState);
            }

            scope.StreamingState = StreamingState.Streaming;
            return(new ODataNotificationReader(
                       textReader: await this.InterceptExceptionAsync(thisParam => thisParam.CreateTextReaderImplementationAsync()).ConfigureAwait(false),
                       listener: this,
                       synchronous: false));
        }
コード例 #6
0
        private StreamScope SelectStream(ImmutableArray <Stream> streams)
        {
            var switchStream = ReadByte();

            if (switchStream == 0)
            {
                return(null);
            }

            var streamIndex = ReadNumberAsInt32();

            if (streamIndex < 0 || streamIndex >= streams.Length)
            {
                throw new InvalidDataException();
            }

            var stream = streams[streamIndex];
            var scope  = new StreamScope(this);

            scope.SetSource(stream);
            return(scope);
        }
コード例 #7
0
        protected ArchiveMetadata ReadMetadataCore(Stream stream, PasswordStorage password)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead || !stream.CanSeek)
            {
                throw new InvalidOperationException("Stream must support reading and seeking.");
            }

            if (mStream != null)
            {
                throw new InvalidOperationException("Recursive invocation.");
            }

            try
            {
                mPassword        = password;
                mStream          = stream;
                mStream.Position = 0;
                mStreamLength    = stream.Length;

                var exception = ReadFileHeader(mStream, mStreamLength, out mMajorVersion, out mMinorVersion, out mMetadataOffset, out mMetadataLength, out mMetadataChecksum);
                if (exception != null)
                {
                    throw exception;
                }

                if (mMetadataLength == 0)
                {
                    return(new ArchiveMetadata());
                }

                // TODO: validate metadata stream checksum

                using (var metadataStream = new ConstrainedReadStream(mStream, ArchiveMetadataFormat.kHeaderLength + mMetadataOffset, mMetadataLength))
                    using (var scope = new StreamScope(this))
                    {
                        scope.SetSource(metadataStream);

                        if (!PrepareMetadata(scope))
                        {
                            return(new ArchiveMetadata());
                        }

                        return(ReadArchive());
                    }
            }
            finally
            {
                // Drop references to password and stream so they aren't retained.
                mPassword = null;
                mStream   = null;

                // It is also important to reset optional values to their defaults. Otherwise if
                // the next archive we are reading doesn't contain some of the optional values
                // we could mistake the values from the previous archive as current values.
                //mFileCount = 0;
            }
        }
コード例 #8
0
 public StreamScope(ArchiveMetadataReader reader)
 {
     mReader       = reader;
     mOuterScope   = reader.mScope;
     reader.mScope = this;
 }
コード例 #9
0
        private bool PrepareMetadata(StreamScope scope)
        {
            // The metadata stream can either be inlined or compressed
            var token = ReadToken();
            if (token == ArchiveMetadataToken.PackedHeader)
            {
                var streams = ReadPackedStreams();

                // Compressed metadata without content is odd but allowed.
                if (streams.IsDefaultOrEmpty)
                    return false;

                // Compressed metadata with multiple streams is not allowed.
                if (streams.Length != 1)
                    throw new InvalidDataException();

                // Switch over to the decoded metadata stream.
                scope.SetSource(streams[0]);
                token = ReadToken();
            }

            // The metadata stream must start with this token.
            if (token != ArchiveMetadataToken.Header)
                throw new InvalidDataException();

            return true;
        }
コード例 #10
0
        protected ArchiveMetadata ReadMetadataCore(Stream stream, PasswordStorage password)
        {
            if (stream == null)
                throw new ArgumentNullException(nameof(stream));

            if (!stream.CanRead || !stream.CanSeek)
                throw new InvalidOperationException("Stream must support reading and seeking.");

            if (mStream != null)
                throw new InvalidOperationException("Recursive invocation.");

            try
            {
                mPassword = password;
                mStream = stream;
                mStream.Position = 0;
                mStreamLength = stream.Length;

                var exception = ReadFileHeader(mStream, mStreamLength, out mMajorVersion, out mMinorVersion, out mMetadataOffset, out mMetadataLength, out mMetadataChecksum);
                if (exception != null)
                    throw exception;

                if (mMetadataLength == 0)
                    return new ArchiveMetadata();

                // TODO: validate metadata stream checksum

                using (var metadataStream = new ConstrainedReadStream(mStream, ArchiveMetadataFormat.kHeaderLength + mMetadataOffset, mMetadataLength))
                using (var scope = new StreamScope(this))
                {
                    scope.SetSource(metadataStream);

                    if (!PrepareMetadata(scope))
                        return new ArchiveMetadata();

                    return ReadArchive();
                }
            }
            finally
            {
                // Drop references to password and stream so they aren't retained.
                mPassword = null;
                mStream = null;

                // It is also important to reset optional values to their defaults. Otherwise if
                // the next archive we are reading doesn't contain some of the optional values
                // we could mistake the values from the previous archive as current values.
                //mFileCount = 0;
            }
        }
コード例 #11
0
 public StreamScope(ArchiveMetadataReader reader)
 {
     mReader = reader;
     mOuterScope = reader.mScope;
     reader.mScope = this;
 }
コード例 #12
0
        private StreamScope SelectStream(ImmutableArray<Stream> streams)
        {
            var switchStream = ReadByte();
            if (switchStream == 0)
                return null;

            var streamIndex = ReadNumberAsInt32();
            if (streamIndex < 0 || streamIndex >= streams.Length)
                throw new InvalidDataException();

            var stream = streams[streamIndex];
            var scope = new StreamScope(this);
            scope.SetSource(stream);
            return scope;
        }