using System; using System.IO; using System.Text; using SharpCompress.Compressors.LZMA; namespace SharpCompress.Common.SevenZip { internal class DataReader { #region Static Methods public static uint Get32(byte[] buffer, int offset) { return buffer[offset] + ((uint)buffer[offset + 1] << 8) + ((uint)buffer[offset + 2] << 16) + ((uint)buffer[offset + 3] << 24); } public static ulong Get64(byte[] buffer, int offset) { return buffer[offset] + ((ulong)buffer[offset + 1] << 8) + ((ulong)buffer[offset + 2] << 16) + ((ulong)buffer[offset + 3] << 24) + ((ulong)buffer[offset + 4] << 32) + ((ulong)buffer[offset + 5] << 40) + ((ulong)buffer[offset + 6] << 48) + ((ulong)buffer[offset + 7] << 56); } #endregion #region Variables private readonly byte[] _buffer; private readonly int _ending; #endregion #region Public Methods public DataReader(byte[] buffer, int offset, int length) { _buffer = buffer; Offset = offset; _ending = offset + length; } public int Offset { get; private set; } public Byte ReadByte() { if (Offset >= _ending) { throw new EndOfStreamException(); } return _buffer[Offset++]; } public void ReadBytes(byte[] buffer, int offset, int length) { if (length > _ending - Offset) { throw new EndOfStreamException(); } while (length-- > 0) { buffer[offset++] = _buffer[Offset++]; } } public void SkipData(long size) { if (size > _ending - Offset) { throw new EndOfStreamException(); } Offset += (int)size; #if DEBUG Log.WriteLine("SkipData {0}", size); #endif } public void SkipData() { SkipData(checked((long)ReadNumber())); } public ulong ReadNumber() { if (Offset >= _ending) { throw new EndOfStreamException(); } byte firstByte = _buffer[Offset++]; byte mask = 0x80; ulong value = 0; for (int i = 0; i < 8; i++) { if ((firstByte & mask) == 0) { ulong highPart = firstByte & (mask - 1u); value += highPart << (i * 8); return value; } if (Offset >= _ending) { throw new EndOfStreamException(); } value |= (ulong)_buffer[Offset++] << (8 * i); mask >>= 1; } return value; } public int ReadNum() { ulong value = ReadNumber(); if (value > Int32.MaxValue) { throw new NotSupportedException(); } return (int)value; } public uint ReadUInt32() { if (Offset + 4 > _ending) { throw new EndOfStreamException(); } uint res = Get32(_buffer, Offset); Offset += 4; return res; } public ulong ReadUInt64() { if (Offset + 8 > _ending) { throw new EndOfStreamException(); } ulong res = Get64(_buffer, Offset); Offset += 8; return res; } public string ReadString() { int ending = Offset; for (;;) { if (ending + 2 > _ending) { throw new EndOfStreamException(); } if (_buffer[ending] == 0 && _buffer[ending + 1] == 0) { break; } ending += 2; } string str = Encoding.Unicode.GetString(_buffer, Offset, ending - Offset); Offset = ending + 2; return str; } #endregion } }