JStream ParseBStream(byte typeId) { if (debugWriter != null) { debugWriter.WriteLine($"{PsbTokenType.BStream} {typeId} <"); ++debugWriter.Indent; debugWriter.Write("index - "); } uint index = ParseUInt((byte)(typeId - 21)); if (debugWriter != null) { debugWriter.WriteLine("* offset - 0x{0:x8}", bStreamsOffsets[index]); debugWriter.WriteLine("* length - 0x{0:x8}", bStreamsSizes[index]); --debugWriter.Indent; debugWriter.WriteLine(">"); } var js = new JStream(index, true, this); if (!lazyStreamLoading) { long oldPos = stream.Position; stream.Seek(bStreamsBlobOffset + bStreamsOffsets[index], SeekOrigin.Begin); byte[] data = br.ReadBytes((int)bStreamsSizes[index]); stream.Position = oldPos; js.BinaryData = data; js.Reader = null; } BStreamCache[index] = js; return(js); }
internal byte[] GetStreamData(JStream js) { if (js.Reader != this) { throw new ArgumentException("Stream does not belong to this reader.", nameof(js)); } CheckDisposed(); if (js.IsBStream) { stream.Seek(bStreamsBlobOffset + bStreamsOffsets[js.Index], SeekOrigin.Begin); return(br.ReadBytes((int)bStreamsSizes[js.Index])); } else { stream.Seek(streamsBlobOffset + streamsOffsets[js.Index], SeekOrigin.Begin); return(br.ReadBytes((int)streamsSizes[js.Index])); } }
void PrepareNode(JToken node) { if (node.Type == JTokenType.String) { var stringValue = (string)node; if ((stringValue.StartsWith("_stream:") || stringValue.StartsWith("_bstream:")) && !(node is JStream)) { // Replace stream string representation with a JStream var newNode = JStream.CreateFromStringRepresentation(stringValue); ((JValue)node).Value = string.Empty; // Invalidate old node so replacement goes through node.Replace(newNode); node = newNode; } if (node is JStream stream) { PrepareStream(stream); } else { PrepareString(stringValue); } } else if (node is JArray array) { foreach (var token in array) { PrepareNode(token); } } else if (node is JObject obj) { foreach (var prop in obj) { keyNamesGen.AddString(prop.Key); PrepareNode(prop.Value); } } }
void Write(BinaryWriter bw, JStream stream) { Write(bw, stream.Index, stream.IsBStream ? 34 : 25); }
void PrepareStream(JStream stream) { if (stream.IsBStream && Version < 4) { stream.IsBStream = false; } var cache = stream.IsBStream ? bStreamsCache : streamsCache; bool doOptimize = Optimize; byte[] hash = null; long length; if (stream.BinaryData != null) { if (doOptimize) { hash = hasher.ComputeHash(stream.BinaryData); } length = stream.BinaryData.Length; } else if (streamSource != null) { using (Stream dataStream = streamSource.GetStream((string)stream)) { if (doOptimize) { hash = hasher.ComputeHash(dataStream); } length = dataStream.Length; } } else { throw new Exception("No binary data for stream"); } if (doOptimize) { string hashString = BitConverter.ToString(hash).Replace("-", string.Empty); if (cache.TryGetValue(hashString, out var entry)) { entry.Streams.Add(stream); } else { cache.Add(hashString, new StreamCacheEntry { OrigValue = (string)stream, Streams = new List <JStream> { stream }, Length = length }); } } else { cache.Add(cache.Count.ToString(), new StreamCacheEntry { OrigValue = (string)stream, Streams = new List <JStream> { stream }, Length = length }); } }