github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/git/odb/blob.go (about)

     1  package odb
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  )
     7  
     8  // Blob represents a Git object of type "blob".
     9  type Blob struct {
    10  	// Size is the total uncompressed size of the blob's contents.
    11  	Size int64
    12  	// Contents is a reader that yields the uncompressed blob contents. It
    13  	// may only be read once. It may or may not implement io.ReadSeeker.
    14  	Contents io.Reader
    15  
    16  	// closeFn is a function that is called to free any resources held by
    17  	// the Blob.  In particular, this will close a file, if the Blob is
    18  	// being read from a file on disk.
    19  	closeFn func() error
    20  }
    21  
    22  // NewBlobFromBytes returns a new *Blob that yields the data given.
    23  func NewBlobFromBytes(contents []byte) *Blob {
    24  	return &Blob{
    25  		Contents: bytes.NewReader(contents),
    26  		Size:     int64(len(contents)),
    27  	}
    28  }
    29  
    30  // Type implements Object.ObjectType by returning the correct object type for
    31  // Blobs, BlobObjectType.
    32  func (b *Blob) Type() ObjectType { return BlobObjectType }
    33  
    34  // Decode implements Object.Decode and decodes the uncompressed blob contents
    35  // being read. It returns the number of bytes that it consumed off of the
    36  // stream, which is always zero.
    37  //
    38  // If any errors are encountered while reading the blob, they will be returned.
    39  func (b *Blob) Decode(r io.Reader, size int64) (n int, err error) {
    40  	b.Size = size
    41  	b.Contents = io.LimitReader(r, size)
    42  
    43  	b.closeFn = func() error {
    44  		if closer, ok := r.(io.Closer); ok {
    45  			return closer.Close()
    46  		}
    47  		return nil
    48  	}
    49  
    50  	return 0, nil
    51  }
    52  
    53  // Encode encodes the blob's contents to the given io.Writer, "w". If there was
    54  // any error copying the blob's contents, that error will be returned.
    55  //
    56  // Otherwise, the number of bytes written will be returned.
    57  func (b *Blob) Encode(to io.Writer) (n int, err error) {
    58  	nn, err := io.Copy(to, b.Contents)
    59  
    60  	return int(nn), err
    61  }
    62  
    63  // Closes closes any resources held by the open Blob, or returns nil if there
    64  // were no errors.
    65  func (b *Blob) Close() error {
    66  	if b.closeFn == nil {
    67  		return nil
    68  	}
    69  	return b.closeFn()
    70  }
    71  
    72  // Equal returns whether the receiving and given blobs are equal, or in other
    73  // words, whether they are represented by the same SHA-1 when saved to the
    74  // object database.
    75  func (b *Blob) Equal(other *Blob) bool {
    76  	if (b == nil) != (other == nil) {
    77  		return false
    78  	}
    79  
    80  	if b != nil {
    81  		return b.Contents == other.Contents &&
    82  			b.Size == other.Size
    83  	}
    84  	return true
    85  }