public static StorageFrameDecoded ReadFrame(Stream source) { using (var binary = new BitReader(source)) { var version = binary.ReadInt64(); var name = binary.ReadString(); var len = binary.Read7BitInt(); var bytes = binary.ReadBytes(len); var sha1Expected = binary.ReadBytes(20); var decoded = new StorageFrameDecoded(bytes, name, version); if (decoded.IsEmpty && sha1Expected.All(b => b == 0)) { // this looks like end of the stream. return decoded; } //SHA1. TODO: compute hash nicely var sha1Actual = EncodeFrame(name, bytes, version).Hash; if (!sha1Expected.SequenceEqual(sha1Actual)) throw new StorageFrameException("SHA mismatch in data frame"); return decoded; } }
public object ReadMessage(Stream stream) { using (var bin = new BitReader(stream)) { var contract = bin.ReadString(); Formatter formatter; if (!_formattersByContract.TryGetValue(contract, out formatter)) throw new InvalidOperationException(string.Format("Couldn't find contract type for name '{0}'", contract)); var length = bin.Read7BitInt(); var data = bin.ReadBytes(length); using (var inner = new MemoryStream(data, 0,length)) { return formatter.DeserializerDelegate(inner); } } }
public IEnumerable<DataRecord> ReadAll(long startOffset, int maxRecordCount) { if (startOffset < 0) throw new ArgumentOutOfRangeException("startOffset"); if (maxRecordCount < 0) throw new ArgumentOutOfRangeException("maxRecordCount"); var endOffset = GetEndOffset(); if (startOffset >= endOffset) yield break; if (!File.Exists(Path.Combine(_path, "stream.dat"))) throw new InvalidOperationException("File stream.chk found but stream.dat file does not exist"); using (_dataStream = new FileStream(Path.Combine(_path, "stream.dat"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (_dataBits = new BitReader(_dataStream)) { _dataStream.Seek(startOffset, SeekOrigin.Begin); int count = 0; while (_dataStream.Position < endOffset && count <= maxRecordCount) { var key = _dataBits.ReadString(); var length = _dataBits.Reader7BitInt(); if (_dataStream.Position + length > _dataStream.Length) throw new InvalidOperationException("Data length is out of range."); var data = _dataBits.ReadBytes(length); yield return new DataRecord(key, data, _dataStream.Position); if (count == maxRecordCount) break; count++; } } } }
protected static void DeserializeId(BitReader br, UniqueId uid) { if (uid.Type == UniqueIdType.Steam) { uid.Id = br.ReadBytes(8); } else if (uid.Type == UniqueIdType.PS4) { uid.Id = br.ReadBytes(32); } else if (uid.Type == UniqueIdType.Unknown) { uid.Id = br.ReadBytes(3); // Will be 0 if (uid.Id.Sum(x => x) != 0) { throw new Exception("Unknown id isn't 0, might be lost"); } } else if (uid.Type == UniqueIdType.Xbox) { uid.Id = br.ReadBytes(8); } else { throw new ArgumentException(string.Format("Invalid type: {0}. Next bits are {1}", ((int)uid.Type).ToString(), br.GetBits(br.Position, Math.Min(4096, br.Length - br.Position)).ToBinaryString())); } uid.PlayerNumber = br.ReadByte(); }