本站源代码
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.

145 lines
3.3KB

  1. package object
  2. import (
  3. "io"
  4. "gopkg.in/src-d/go-git.v4/plumbing"
  5. "gopkg.in/src-d/go-git.v4/plumbing/storer"
  6. "gopkg.in/src-d/go-git.v4/utils/ioutil"
  7. )
  8. // Blob is used to store arbitrary data - it is generally a file.
  9. type Blob struct {
  10. // Hash of the blob.
  11. Hash plumbing.Hash
  12. // Size of the (uncompressed) blob.
  13. Size int64
  14. obj plumbing.EncodedObject
  15. }
  16. // GetBlob gets a blob from an object storer and decodes it.
  17. func GetBlob(s storer.EncodedObjectStorer, h plumbing.Hash) (*Blob, error) {
  18. o, err := s.EncodedObject(plumbing.BlobObject, h)
  19. if err != nil {
  20. return nil, err
  21. }
  22. return DecodeBlob(o)
  23. }
  24. // DecodeObject decodes an encoded object into a *Blob.
  25. func DecodeBlob(o plumbing.EncodedObject) (*Blob, error) {
  26. b := &Blob{}
  27. if err := b.Decode(o); err != nil {
  28. return nil, err
  29. }
  30. return b, nil
  31. }
  32. // ID returns the object ID of the blob. The returned value will always match
  33. // the current value of Blob.Hash.
  34. //
  35. // ID is present to fulfill the Object interface.
  36. func (b *Blob) ID() plumbing.Hash {
  37. return b.Hash
  38. }
  39. // Type returns the type of object. It always returns plumbing.BlobObject.
  40. //
  41. // Type is present to fulfill the Object interface.
  42. func (b *Blob) Type() plumbing.ObjectType {
  43. return plumbing.BlobObject
  44. }
  45. // Decode transforms a plumbing.EncodedObject into a Blob struct.
  46. func (b *Blob) Decode(o plumbing.EncodedObject) error {
  47. if o.Type() != plumbing.BlobObject {
  48. return ErrUnsupportedObject
  49. }
  50. b.Hash = o.Hash()
  51. b.Size = o.Size()
  52. b.obj = o
  53. return nil
  54. }
  55. // Encode transforms a Blob into a plumbing.EncodedObject.
  56. func (b *Blob) Encode(o plumbing.EncodedObject) (err error) {
  57. o.SetType(plumbing.BlobObject)
  58. w, err := o.Writer()
  59. if err != nil {
  60. return err
  61. }
  62. defer ioutil.CheckClose(w, &err)
  63. r, err := b.Reader()
  64. if err != nil {
  65. return err
  66. }
  67. defer ioutil.CheckClose(r, &err)
  68. _, err = io.Copy(w, r)
  69. return err
  70. }
  71. // Reader returns a reader allow the access to the content of the blob
  72. func (b *Blob) Reader() (io.ReadCloser, error) {
  73. return b.obj.Reader()
  74. }
  75. // BlobIter provides an iterator for a set of blobs.
  76. type BlobIter struct {
  77. storer.EncodedObjectIter
  78. s storer.EncodedObjectStorer
  79. }
  80. // NewBlobIter takes a storer.EncodedObjectStorer and a
  81. // storer.EncodedObjectIter and returns a *BlobIter that iterates over all
  82. // blobs contained in the storer.EncodedObjectIter.
  83. //
  84. // Any non-blob object returned by the storer.EncodedObjectIter is skipped.
  85. func NewBlobIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *BlobIter {
  86. return &BlobIter{iter, s}
  87. }
  88. // Next moves the iterator to the next blob and returns a pointer to it. If
  89. // there are no more blobs, it returns io.EOF.
  90. func (iter *BlobIter) Next() (*Blob, error) {
  91. for {
  92. obj, err := iter.EncodedObjectIter.Next()
  93. if err != nil {
  94. return nil, err
  95. }
  96. if obj.Type() != plumbing.BlobObject {
  97. continue
  98. }
  99. return DecodeBlob(obj)
  100. }
  101. }
  102. // ForEach call the cb function for each blob contained on this iter until
  103. // an error happens or the end of the iter is reached. If ErrStop is sent
  104. // the iteration is stop but no error is returned. The iterator is closed.
  105. func (iter *BlobIter) ForEach(cb func(*Blob) error) error {
  106. return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
  107. if obj.Type() != plumbing.BlobObject {
  108. return nil
  109. }
  110. b, err := DecodeBlob(obj)
  111. if err != nil {
  112. return err
  113. }
  114. return cb(b)
  115. })
  116. }
上海开阖软件有限公司 沪ICP备12045867号-1