You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

blob.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package git
  6. import (
  7. "bytes"
  8. "encoding/base64"
  9. "io"
  10. "io/ioutil"
  11. "github.com/go-git/go-git/v5/plumbing"
  12. )
  13. // Blob represents a Git object.
  14. type Blob struct {
  15. ID SHA1
  16. gogitEncodedObj plumbing.EncodedObject
  17. name string
  18. }
  19. // DataAsync gets a ReadCloser for the contents of a blob without reading it all.
  20. // Calling the Close function on the result will discard all unread output.
  21. func (b *Blob) DataAsync() (io.ReadCloser, error) {
  22. return b.gogitEncodedObj.Reader()
  23. }
  24. // Size returns the uncompressed size of the blob
  25. func (b *Blob) Size() int64 {
  26. return b.gogitEncodedObj.Size()
  27. }
  28. // Name returns name of the tree entry this blob object was created from (or empty string)
  29. func (b *Blob) Name() string {
  30. return b.name
  31. }
  32. // GetBlobContent Gets the content of the blob as raw text
  33. func (b *Blob) GetBlobContent() (string, error) {
  34. dataRc, err := b.DataAsync()
  35. if err != nil {
  36. return "", err
  37. }
  38. defer dataRc.Close()
  39. buf := make([]byte, 1024)
  40. n, _ := dataRc.Read(buf)
  41. buf = buf[:n]
  42. return string(buf), nil
  43. }
  44. // GetBlobLineCount gets line count of lob as raw text
  45. func (b *Blob) GetBlobLineCount() (int, error) {
  46. reader, err := b.DataAsync()
  47. if err != nil {
  48. return 0, err
  49. }
  50. defer reader.Close()
  51. buf := make([]byte, 32*1024)
  52. count := 0
  53. lineSep := []byte{'\n'}
  54. for {
  55. c, err := reader.Read(buf)
  56. count += bytes.Count(buf[:c], lineSep)
  57. switch {
  58. case err == io.EOF:
  59. return count, nil
  60. case err != nil:
  61. return count, err
  62. }
  63. }
  64. }
  65. // GetBlobContentBase64 Reads the content of the blob with a base64 encode and returns the encoded string
  66. func (b *Blob) GetBlobContentBase64() (string, error) {
  67. dataRc, err := b.DataAsync()
  68. if err != nil {
  69. return "", err
  70. }
  71. defer dataRc.Close()
  72. pr, pw := io.Pipe()
  73. encoder := base64.NewEncoder(base64.StdEncoding, pw)
  74. go func() {
  75. _, err := io.Copy(encoder, dataRc)
  76. _ = encoder.Close()
  77. if err != nil {
  78. _ = pw.CloseWithError(err)
  79. } else {
  80. _ = pw.Close()
  81. }
  82. }()
  83. out, err := ioutil.ReadAll(pr)
  84. if err != nil {
  85. return "", err
  86. }
  87. return string(out), nil
  88. }