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