Example #1
0
        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;
        }
Example #2
0
        public static bool TryRead(Stream logStream, out LogEntry entry)
        {
            long position = logStream.Position;

            byte[] sectorBuffer = new byte[LogSectorSize];
            StreamUtilities.ReadFully(logStream, sectorBuffer, 0, sectorBuffer.Length);

            uint sig = EndianUtilities.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);

            StreamUtilities.ReadFully(logStream, logEntryBuffer, LogSectorSize, logEntryBuffer.Length - LogSectorSize);

            EndianUtilities.WriteBytesLittleEndian(0, logEntryBuffer, 4);
            if (header.Checksum !=
                Crc32LittleEndian.Compute(Crc32Algorithm.Castagnoli, logEntryBuffer, 0, (int)header.EntryLength))
            {
                entry = null;
                return(false);
            }

            int dataPos = MathUtilities.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 = EndianUtilities.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);
        }