public static bool TryRead(Stream logStream, out LogEntry entry) { long position = logStream.Position; byte[] sectorBuffer = new byte[LogSectorSize]; Utilities.ReadFully(logStream, sectorBuffer, 0, sectorBuffer.Length); uint sig = Utilities.ToUInt32LittleEndian(sectorBuffer, 0); if (sig != LogEntryHeader.LogEntrySignature) { entry = null; return false; } LogEntryHeader header = new LogEntryHeader(); header.ReadFrom(sectorBuffer, 0); if (!header.IsValid || header.EntryLength > logStream.Length) { entry = null; return false; } byte[] logEntryBuffer = new byte[header.EntryLength]; Array.Copy(sectorBuffer, logEntryBuffer, LogSectorSize); Utilities.ReadFully(logStream, logEntryBuffer, LogSectorSize, logEntryBuffer.Length - LogSectorSize); Utilities.WriteBytesLittleEndian((int)0, logEntryBuffer, 4); if (header.Checksum != Crc32LittleEndian.Compute(Crc32Algorithm.Castagnoli, logEntryBuffer, 0, (int)header.EntryLength)) { entry = null; return false; } int dataPos = Utilities.RoundUp(((int)header.DescriptorCount * 32) + 64, LogSectorSize); List<Descriptor> descriptors = new List<Descriptor>(); for (int i = 0; i < header.DescriptorCount; ++i) { int offset = (i * 32) + 64; Descriptor descriptor; uint descriptorSig = Utilities.ToUInt32LittleEndian(logEntryBuffer, offset); switch (descriptorSig) { case Descriptor.ZeroDescriptorSignature: descriptor = new ZeroDescriptor(); break; case Descriptor.DataDescriptorSignature: descriptor = new DataDescriptor(logEntryBuffer, dataPos); dataPos += LogSectorSize; break; default: entry = null; return false; } descriptor.ReadFrom(logEntryBuffer, offset); if (!descriptor.IsValid(header.SequenceNumber)) { entry = null; return false; } descriptors.Add(descriptor); } entry = new LogEntry(position, header, descriptors); return true; }
internal LogEntryInfo(LogEntry entry) { _entry = entry; }