Beispiel #1
0
        async ValueTask ReadChunks(long chunkTableOffset, int chunkCount)
        {
            if (ChunkReader is null)
            {
                throw new InvalidOperationException();
            }

            var chunkTable = new byte[(chunkCount + 1) * (4 + sizeof(long))];

            if (await ChunkReader.ReadAtAsync(chunkTableOffset, chunkTable).ConfigureAwait(false) != chunkTable.Length)
            {
                return;
            }

            _chunks = Enumerable.Range(0, chunkCount + 1).Select(i => new Chunk
            {
                Name     = (i < chunkCount) ? Encoding.ASCII.GetString(chunkTable, 12 * i, 4) : null,
                Position = NetBitConverter.ToInt64(chunkTable, 12 * i + 4)
            }).ToArray();

            for (int i = 0; i < chunkCount; i++)
            {
                _chunks[i].Length = _chunks[i + 1].Position - _chunks[i].Position;
            }

            FanOut = await ReadFanOutAsync().ConfigureAwait(false);
        }
Beispiel #2
0
        protected override async ValueTask <(GitIdType IdType, int ChunkCount, long ChunkTableOffset)> ReadHeaderAsync()
        {
            if (ChunkReader is null)
            {
                throw new InvalidOperationException();
            }

            var headerBuffer = new byte[8];

            if (await ChunkReader.ReadAtAsync(0, headerBuffer).ConfigureAwait(false) != headerBuffer.Length)
            {
                return(GitIdType.None, 0, -1);
            }

            if (!"CGPH\x01".Select(x => (byte)x).SequenceEqual(headerBuffer.Take(5)))
            {
                return(GitIdType.None, 0, -1);
            }

            var idType           = (GitIdType)headerBuffer[5];
            int chunkCount       = headerBuffer[6];
            int baseCommitGraphs = headerBuffer[7];

            if (baseCommitGraphs <= 0)
            {
                _baseCommitGraphs = -1;
            }
            else
            {
                _baseCommitGraphs = baseCommitGraphs;
            }

            return(idType, chunkCount, headerBuffer.Length);
        }
Beispiel #3
0
        protected ValueTask <int> ReadFromChunkAsync(string chunkType, long position, byte[] buffer, int length)
        {
            if (_chunks == null || ChunkReader == null)
            {
                return(new ValueTask <int>(0));
            }
            else if (length <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(length));
            }

            Chunk?ch = null;

            foreach (var c in _chunks)
            {
                if (c.Name == chunkType)
                {
                    ch = c;
                    break;
                }
            }
            if (ch == null)
            {
                return(new ValueTask <int>(0));
            }

            int requested = (int)Math.Min(length, ch.Value.Length - position);

            if (requested <= 0)
            {
                return(new ValueTask <int>(0));
            }

            return(ChunkReader.ReadAtAsync(ch.Value.Position + position, buffer, requested));
        }
        async ValueTask <bool> GetHasBitmap()
        {
            if (ChunkReader is null)
            {
                return(false);
            }

            byte[] multiPackId = new byte[Repository.InternalConfig.IdType.HashLength()];
            if (multiPackId.Length != (await ChunkReader.ReadAtAsync(AfterChunkPosition, multiPackId).ConfigureAwait(false)))
            {
                return(false);
            }

            GitId id = new GitId(Repository.InternalConfig.IdType, multiPackId);

            _multiPackBitmapPath = Path.Combine(_dir, $"multi-pack-index-{id}.bitmap");
            return(File.Exists(_multiPackBitmapPath));
        }