Example #1
0
 public Chunk(ChunkReader reader, long pos, ChunkHeader header)
 {
     _reader       = reader;
     _header       = header;
     BeginPosition = pos;
 }
Example #2
0
        async Task <Meter?> ReadMeter(long pos)
        {
            Debug.Assert(pos >= 0 && pos % MeterInterval == 0);
            if (pos == 0)
            {
                return new Meter()
                       {
                           ChunkBeginPosition = 0
                       }
            }
            ;
            _reader.Seek(pos);
            if (await _reader.ReadAsync(_meter, 0, _meter.Length) != _meter.Length)
            {
                return(null);
            }
            var res = new Meter();

            if (!res.ReadFrom(_meter))
            {
                return(null);
            }
            if (res.ChunkBeginPosition > pos)
            {
                return(null);
            }
            return(res);
        }

        async Task <ChunkHeader?> ReadChunkHeader(long pos)
        {
            if (!await ReadMetered(pos, _header, 0, _header.Length))
            {
                return(null);
            }
            var res = new ChunkHeader();

            if (!res.ReadFrom(_header))
            {
                return(null);
            }
            if (!res.EndPosition(pos).HasValue)
            {
                return(null);
            }
            return(res);
        }

        async Task <bool> ReadMetered(long pos, byte[] array, int offset, int count)
        {
            Debug.Assert(array != null);
            Debug.Assert(offset >= 0);
            Debug.Assert(array.Length - offset >= count);
            if (!(MeteredPosition(pos, count) <= Length))
            {
                return(false);
            }
            while (count > 0)
            {
                Debug.Assert(IsValidPosition(pos));
                if (pos % MeterInterval == 0)
                {
                    pos += Meter.Size;
                }
                _reader.Seek(pos);
                int n = Math.Min(count, MeterInterval - (int)(pos % MeterInterval));
                if (await _reader.ReadAsync(array, offset, n) != n)
                {
                    return(false);
                }
                pos    += n;
                offset += n;
                count  -= n;
            }
            return(true);
        }