github.com/Cloud-Foundations/Dominator@v0.3.4/lib/objectcache/read.go (about)

     1  package objectcache
     2  
     3  import (
     4  	"crypto/sha512"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  
    10  	"github.com/Cloud-Foundations/Dominator/lib/hash"
    11  )
    12  
    13  func readObject(reader io.Reader, length uint64, expectedHash *hash.Hash) (
    14  	hash.Hash, []byte, error) {
    15  	var hashVal hash.Hash
    16  	var data []byte
    17  	var err error
    18  	if length < 1 {
    19  		data, err = ioutil.ReadAll(reader)
    20  		if err != nil {
    21  			return hashVal, nil, err
    22  		}
    23  		if len(data) < 1 {
    24  			return hashVal, nil,
    25  				errors.New("zero length object cannot be added")
    26  		}
    27  	} else {
    28  		data = make([]byte, length)
    29  		nRead, err := io.ReadFull(reader, data)
    30  		if err != nil {
    31  			return hashVal, nil, err
    32  		}
    33  		if uint64(nRead) != length {
    34  			return hashVal, nil, fmt.Errorf(
    35  				"failed to read data, wanted: %d, got: %d bytes", length, nRead)
    36  		}
    37  	}
    38  	hasher := sha512.New()
    39  	if hasher.Size() != len(hashVal) {
    40  		return hashVal, nil, errors.New("incompatible hash size")
    41  	}
    42  	if _, err := hasher.Write(data); err != nil {
    43  		return hashVal, nil, err
    44  	}
    45  	copy(hashVal[:], hasher.Sum(nil))
    46  	if expectedHash != nil {
    47  		if hashVal != *expectedHash {
    48  			return hashVal, nil, fmt.Errorf(
    49  				"hash mismatch. Computed=%x, expected=%x",
    50  				hashVal, *expectedHash)
    51  		}
    52  	}
    53  	return hashVal, data, nil
    54  }