Package binary implements sintax-sugar functions on top of the standard library binary package
package binary

import (
	
	
	

	
)
Read reads structured binary data from r into data. Bytes are read and decoded in BigEndian order https://golang.org/pkg/encoding/binary/#Read
func ( io.Reader,  ...interface{}) error {
	for ,  := range  {
		if  := binary.Read(, binary.BigEndian, );  != nil {
			return 
		}
	}

	return nil
}
ReadUntil reads from r untin delim is found
func ( io.Reader,  byte) ([]byte, error) {
	if ,  := .(*bufio.Reader);  {
		return ReadUntilFromBufioReader(, )
	}

	var  [1]byte
	 := make([]byte, 0, 16)
	for {
		if ,  := io.ReadFull(, [:]);  != nil {
			if  == io.EOF {
				return nil, 
			}

			return nil, 
		}

		if [0] ==  {
			return , nil
		}

		 = append(, [0])
	}
}
ReadUntilFromBufioReader is like bufio.ReadBytes but drops the delimiter from the result.
func ( *bufio.Reader,  byte) ([]byte, error) {
	,  := .ReadBytes()
	if  != nil || len() == 0 {
		return nil, 
	}

	return [:len()-1], nil
}
ReadVariableWidthInt reads and returns an int in Git VLQ special format: Ordinary VLQ has some redundancies, example: the number 358 can be encoded as the 2-octet VLQ 0x8166 or the 3-octet VLQ 0x808166 or the 4-octet VLQ 0x80808166 and so forth. To avoid these redundancies, the VLQ format used in Git removes this prepending redundancy and extends the representable range of shorter VLQs by adding an offset to VLQs of 2 or more octets in such a way that the lowest possible value for such an (N+1)-octet VLQ becomes exactly one more than the maximum possible value for an N-octet VLQ. In particular, since a 1-octet VLQ can store a maximum value of 127, the minimum 2-octet VLQ (0x8000) is assigned the value 128 instead of 0. Conversely, the maximum value of such a 2-octet VLQ (0xff7f) is 16511 instead of just 16383. Similarly, the minimum 3-octet VLQ (0x808000) has a value of 16512 instead of zero, which means that the maximum 3-octet VLQ (0xffff7f) is 2113663 instead of just 2097151. And so forth. This is how the offset is saved in C: dheader[pos] = ofs & 127; while (ofs >>= 7) dheader[--pos] = 128 | (--ofs & 127);
func ( io.Reader) (int64, error) {
	var  byte
	if  := Read(, &);  != nil {
		return 0, 
	}

	var  = int64( & maskLength)
	for &maskContinue > 0 {
		++
		if  := Read(, &);  != nil {
			return 0, 
		}

		 = ( << lengthBits) + int64(&maskLength)
	}

	return , nil
}

const (
	maskContinue = uint8(128) // 1000 000
	maskLength   = uint8(127) // 0111 1111
	lengthBits   = uint8(7)   // subsequent bytes has 7 bits to store the length
)
ReadUint64 reads 8 bytes and returns them as a BigEndian uint32
func ( io.Reader) (uint64, error) {
	var  uint64
	if  := binary.Read(, binary.BigEndian, &);  != nil {
		return 0, 
	}

	return , nil
}
ReadUint32 reads 4 bytes and returns them as a BigEndian uint32
func ( io.Reader) (uint32, error) {
	var  uint32
	if  := binary.Read(, binary.BigEndian, &);  != nil {
		return 0, 
	}

	return , nil
}
ReadUint16 reads 2 bytes and returns them as a BigEndian uint16
func ( io.Reader) (uint16, error) {
	var  uint16
	if  := binary.Read(, binary.BigEndian, &);  != nil {
		return 0, 
	}

	return , nil
}
ReadHash reads a plumbing.Hash from r
func ( io.Reader) (plumbing.Hash, error) {
	var  plumbing.Hash
	if  := binary.Read(, binary.BigEndian, [:]);  != nil {
		return plumbing.ZeroHash, 
	}

	return , nil
}

const sniffLen = 8000
IsBinary detects if data is a binary value based on: http://git.kernel.org/cgit/git/git.git/tree/xdiff-interface.c?id=HEAD#n198
func ( io.Reader) (bool, error) {
	 := bufio.NewReader()
	 := 0
	for {
		if  == sniffLen {
			break
		}

		,  := .ReadByte()
		if  == io.EOF {
			break
		}
		if  != nil {
			return false, 
		}

		if  == byte(0) {
			return true, nil
		}

		++
	}

	return false, nil