This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knotmirror / xrpc / gitea / blob.go
1.4 kB 80 lines
1// Copyright 2021 The Gitea Authors. All rights reserved. 2// SPDX-License-Identifier: MIT 3 4package gitea 5 6import ( 7 "bufio" 8 "bytes" 9 "context" 10 "io" 11 12 "github.com/go-git/go-git/v5/plumbing" 13) 14 15// ReadBlob returns blob size and [io.ReadCloser] of that blob. 16func ReadBlob(ctx context.Context, repoPath string, hash plumbing.Hash) (int64, io.ReadCloser, error) { 17 wr, rd, cancel := CatFileBatch(ctx, repoPath) 18 19 _, err := wr.Write([]byte(hash.String() + "\n")) 20 if err != nil { 21 cancel() 22 return 0, nil, err 23 } 24 _, _, size, err := ReadBatchLine(rd) 25 if err != nil { 26 cancel() 27 return 0, nil, err 28 } 29 30 if size < 4096 { 31 bs, err := io.ReadAll(io.LimitReader(rd, size)) 32 defer cancel() 33 if err != nil { 34 return 0, nil, err 35 } 36 _, err = rd.Discard(1) 37 return size, io.NopCloser(bytes.NewReader(bs)), err 38 } 39 40 return size, &blobReader{ 41 rd: rd, 42 n: size, 43 cancel: cancel, 44 }, nil 45} 46 47type blobReader struct { 48 rd *bufio.Reader 49 n int64 50 cancel func() 51} 52 53func (b *blobReader) Read(p []byte) (n int, err error) { 54 if b.n <= 0 { 55 return 0, io.EOF 56 } 57 if int64(len(p)) > b.n { 58 p = p[0:b.n] 59 } 60 n, err = b.rd.Read(p) 61 b.n -= int64(n) 62 return n, err 63} 64 65// Close implements io.Closer 66func (b *blobReader) Close() error { 67 if b.rd == nil { 68 return nil 69 } 70 71 defer b.cancel() 72 73 if err := DiscardFull(b.rd, b.n+1); err != nil { 74 return err 75 } 76 77 b.rd = nil 78 79 return nil 80}