gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. package git
  5. import (
  6. "bytes"
  7. "encoding/base64"
  8. "errors"
  9. "io"
  10. "strings"
  11. "code.gitea.io/gitea/modules/typesniffer"
  12. "code.gitea.io/gitea/modules/util"
  13. )
  14. // This file contains common functions between the gogit and !gogit variants for git Blobs
  15. // Name returns name of the tree entry this blob object was created from (or empty string)
  16. func (b *Blob) Name() string {
  17. return b.name
  18. }
  19. // GetBlobBytes Gets the limited content of the blob
  20. func (b *Blob) GetBlobBytes(limit int64) ([]byte, error) {
  21. if limit <= 0 {
  22. return nil, nil
  23. }
  24. dataRc, err := b.DataAsync()
  25. if err != nil {
  26. return nil, err
  27. }
  28. defer dataRc.Close()
  29. return util.ReadWithLimit(dataRc, int(limit))
  30. }
  31. // GetBlobContent Gets the limited content of the blob as raw text
  32. func (b *Blob) GetBlobContent(limit int64) (string, error) {
  33. buf, err := b.GetBlobBytes(limit)
  34. return string(buf), err
  35. }
  36. // GetBlobLineCount gets line count of the blob.
  37. // It will also try to write the content to w if it's not nil, then we could pre-fetch the content without reading it again.
  38. func (b *Blob) GetBlobLineCount(w io.Writer) (int, error) {
  39. reader, err := b.DataAsync()
  40. if err != nil {
  41. return 0, err
  42. }
  43. defer reader.Close()
  44. buf := make([]byte, 32*1024)
  45. count := 1
  46. lineSep := []byte{'\n'}
  47. for {
  48. c, err := reader.Read(buf)
  49. if w != nil {
  50. if _, err := w.Write(buf[:c]); err != nil {
  51. return count, err
  52. }
  53. }
  54. count += bytes.Count(buf[:c], lineSep)
  55. switch {
  56. case errors.Is(err, io.EOF):
  57. return count, nil
  58. case err != nil:
  59. return count, err
  60. }
  61. }
  62. }
  63. // GetBlobContentBase64 Reads the content of the blob with a base64 encoding and returns the encoded string
  64. func (b *Blob) GetBlobContentBase64(originContent *strings.Builder) (string, error) {
  65. dataRc, err := b.DataAsync()
  66. if err != nil {
  67. return "", err
  68. }
  69. defer dataRc.Close()
  70. base64buf := &strings.Builder{}
  71. encoder := base64.NewEncoder(base64.StdEncoding, base64buf)
  72. buf := make([]byte, 32*1024)
  73. loop:
  74. for {
  75. n, err := dataRc.Read(buf)
  76. if n > 0 {
  77. if originContent != nil {
  78. _, _ = originContent.Write(buf[:n])
  79. }
  80. if _, err := encoder.Write(buf[:n]); err != nil {
  81. return "", err
  82. }
  83. }
  84. switch {
  85. case errors.Is(err, io.EOF):
  86. break loop
  87. case err != nil:
  88. return "", err
  89. }
  90. }
  91. _ = encoder.Close()
  92. return base64buf.String(), nil
  93. }
  94. // GuessContentType guesses the content type of the blob.
  95. func (b *Blob) GuessContentType() (typesniffer.SniffedType, error) {
  96. buf, err := b.GetBlobBytes(typesniffer.SniffContentSize)
  97. if err != nil {
  98. return typesniffer.SniffedType{}, err
  99. }
  100. return typesniffer.DetectContentType(buf), nil
  101. }