예제 #1
0
        public async Task <KeyValuePair <BlobChunkVerificationResultInfo, IEnumerable <BlobObject> > > EnumerateChunksAsync(
            BlobSystem blobSystem,
            bool throwOnUnhandledChunk = true,
            BlobTransportStreamAuthentication expectedAuthentication = BlobTransportStreamAuthentication.None,
            bool authenticateBlob = true)
        {
            Contract.Requires <ArgumentNullException>(blobSystem != null);
            Contract.Requires <InvalidOperationException>(!IsClosed);
            Contract.Requires <InvalidOperationException>(UnderlyingStream.CanRead);

            IEnumerable <BlobObject> objects = null;

            IList <KeyValuePair <BlobChunkHeader, byte[]> > chunks;
            var result_info = EnumerateStream(out chunks, expectedAuthentication,
                                              GetEnumerateStreamResultBytes, getResultValueConsumesChunk: true);

            if (result_info.IsValid &&
                mFooter.Authentication > BlobTransportStreamAuthentication.None && authenticateBlob)
            {
                result_info = VerifyEofAuthentication();
            }

            if (result_info.IsValid)
            {
                var tasks = EnumerateChunksReadObjectsAsync(blobSystem, throwOnUnhandledChunk, chunks);
                await Task.WhenAll(tasks).ConfigureAwait(true);

                objects = from task in tasks
                          select task.Result;
            }

            return(new KeyValuePair <BlobChunkVerificationResultInfo, IEnumerable <BlobObject> >(result_info, objects));
        }
예제 #2
0
        public BlobChunkVerificationResultInfo EnumerateChunks(BlobSystem blobSystem,
                                                               out IEnumerable <BlobObject> objects, bool throwOnUnhandledChunk = true,
                                                               BlobTransportStreamAuthentication expectedAuthentication         = BlobTransportStreamAuthentication.None,
                                                               bool authenticateBlob = true)
        {
            Contract.Requires <ArgumentNullException>(blobSystem != null);
            Contract.Requires <InvalidOperationException>(!IsClosed);
            Contract.Requires <InvalidOperationException>(UnderlyingStream.CanRead);

            objects = null;

            IList <KeyValuePair <BlobChunkHeader, byte[]> > chunks;
            var result_info = EnumerateStream(out chunks, expectedAuthentication,
                                              GetEnumerateStreamResultBytes, getResultValueConsumesChunk: true);

            if (result_info.IsValid &&
                mFooter.Authentication > BlobTransportStreamAuthentication.None && authenticateBlob)
            {
                result_info = VerifyEofAuthentication();
            }

            if (result_info.IsValid)
            {
                objects = EnumerateChunksReadObjectsSync(blobSystem, throwOnUnhandledChunk, chunks);
            }

            return(result_info);
        }
예제 #3
0
        IEnumerable <BlobObject> EnumerateChunksReadObjectsSync(BlobSystem blobSystem,
                                                                bool throwOnUnhandledChunk, IList <KeyValuePair <BlobChunkHeader, byte[]> > chunks)
        {
            var results = new List <BlobObject>(chunks.Count);

            foreach (var kv in chunks)
            {
                var       header = kv.Key;
                BlobGroup blob_group;
                BlobGroupVersionAndBuildInfo info_for_version;
                if (blobSystem.TryGetBlobGroup(header.Signature, header.DataSize, header.Version, out blob_group, out info_for_version))
                {
                    if (!info_for_version.BuildHandle.IsWithinSameBranch(GameTarget.Build))
                    {
                        EnumerateChunksReadObjectFoundBuildIncompatibility(blobSystem, header, blob_group,
                                                                           info_for_version.BuildHandle, GameTarget.Build);
                    }

                    var obj = EnumerateChunksReadObject(blobSystem, blob_group, info_for_version, header, kv.Value);
                    results.Add(obj);
                }
                else
                {
                    EnumerateChunksReadObjectFoundUnknownChunk(blobSystem, header, throwOnUnhandledChunk);
                }
            }

            return(results);
        }
예제 #4
0
        Task <BlobObject>[] EnumerateChunksReadObjectsAsync(BlobSystem blobSystem,
                                                            bool throwOnUnhandledChunk, IList <KeyValuePair <BlobChunkHeader, byte[]> > chunks)
        {
            var task_list = new List <Task <BlobObject> >(chunks.Count);

            foreach (var kv in chunks)
            {
                var       header = kv.Key;
                BlobGroup blob_group;
                BlobGroupVersionAndBuildInfo info_for_version;
                if (blobSystem.TryGetBlobGroup(header.Signature, header.DataSize, header.Version, out blob_group, out info_for_version))
                {
                    if (!info_for_version.BuildHandle.IsWithinSameBranch(GameTarget.Build))
                    {
                        EnumerateChunksReadObjectFoundBuildIncompatibility(blobSystem, header, blob_group,
                                                                           info_for_version.BuildHandle, GameTarget.Build);
                    }

                    var task = Task <BlobObject> .Factory.StartNew(s =>
                                                                   (s as BlobTransportStream).EnumerateChunksReadObject(blobSystem, blob_group, info_for_version, header, kv.Value),
                                                                   this);

                    task_list.Add(task);
                }
                else
                {
                    EnumerateChunksReadObjectFoundUnknownChunk(blobSystem, header, throwOnUnhandledChunk);
                }
            }

            return(task_list.ToArray());
        }
예제 #5
0
 void EnumerateChunksReadObjectFoundBuildIncompatibility(BlobSystem blobSystem,
                                                         BlobChunkHeader header, BlobGroup blobGroup,
                                                         Engine.EngineBuildHandle buildForBlobVersion, Engine.EngineBuildHandle actualBuild)
 {
     throw new InvalidOperationException(string.Format(
                                             "Build incompatibility for chunk {0} v{1} sizeof({2}) which uses build={3} " +
                                             "but we're using build={4} for {5}",
                                             blobGroup.GroupTag.TagString, header.Version, header.DataSize, buildForBlobVersion.ToDisplayString(),
                                             actualBuild.ToDisplayString(), UnderlyingStream.StreamName));
 }
예제 #6
0
        void EnumerateChunksReadObjectFoundUnknownChunk(BlobSystem blobSystem,
                                                        BlobChunkHeader header, bool throwOnUnhandledChunk)
        {
            const string kUnhandledChunkMessageFormat = " chunk {0} v{1} sizeof({2}) for target={3}";

            string tag_string = new string(Values.GroupTagData32.FromUInt(header.Signature));

            if (throwOnUnhandledChunk)
            {
                throw new InvalidDataException(string.Format("Unhandled" + kUnhandledChunkMessageFormat,
                                                             tag_string, header.Version, header.DataSize, GameTarget.ToDisplayString()));
            }

            Debug.Trace.Blob.TraceInformation("Ignoring" + kUnhandledChunkMessageFormat,
                                              tag_string, header.Version, header.DataSize, GameTarget.ToDisplayString());
        }
예제 #7
0
        internal void Initialize(BlobSystem system, Engine.BlamEngineTargetHandle gameTarget,
                                 BlobGroup blobGroup, int version)
        {
            SystemGroup = blobGroup;
            GameTarget  = gameTarget;
            Version     = version;

            BlobGroupVersionAndBuildInfo info_for_version;

            if (SystemGroup.VersionAndBuildMap.TryGetValue(Version, out info_for_version))
            {
                SystemGroupVersionInfo = info_for_version;
            }
            else
            {
                throw new KSoft.Debug.UnreachableException();
            }

            InitializeExplicitlyForGame(gameTarget);
        }
예제 #8
0
        BlobObject EnumerateChunksReadObject(BlobSystem blobSystem, BlobGroup blobGroup, BlobGroupVersionAndBuildInfo infoForVersion,
                                             BlobChunkHeader header, byte[] data)
        {
            Contract.Requires <InvalidOperationException>(!GameTarget.IsNone);

            var obj = blobSystem.CreateObject(GameTarget, blobGroup, header.Version, header.Size);

            var byte_order = UnderlyingStream.ByteOrder;

            if (infoForVersion.ForceLittleEndian)
            {
                byte_order = Shell.EndianFormat.Little;
            }

            using (var ms = new System.IO.MemoryStream(data))
                using (var es = new IO.EndianStream(ms, byte_order, this, blobGroup.GroupTag.Name, FileAccess.Read))
                {
                    es.StreamMode = FileAccess.Read;

                    obj.Serialize(es);
                }

            return(obj);
        }