func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) {
	buf := make([]byte, 2*blockSize)
	sparseHeader := buf[:blockSize]

	// readDecimal is a helper function to read a decimal integer from the sparse map
	// while making sure to read from the file in blocks of size blockSize
	readDecimal := func() (int64, error) {
		// Look for newline
		nl := bytes.IndexByte(sparseHeader, '\n')
		if nl == -1 {
			if len(sparseHeader) >= blockSize {
				// This is an error
				return 0, ErrHeader
			}
			oldLen := len(sparseHeader)
			newLen := oldLen + blockSize
			if cap(sparseHeader) < newLen {
				// There's more header, but we need to make room for the next block
				copy(buf, sparseHeader)
				sparseHeader = buf[:newLen]
			} else {
				// There's more header, and we can just reslice
				sparseHeader = sparseHeader[:newLen]
			}

			// Now that sparseHeader is large enough, read next block
			if _, err := io.ReadFull(r, sparseHeader[oldLen:newLen]); err != nil {
				return 0, err
			}

			// Look for a newline in the new data
			nl = bytes.IndexByte(sparseHeader[oldLen:newLen], '\n')
			if nl == -1 {
				// This is an error
				return 0, ErrHeader
			}
			nl += oldLen // We want the position from the beginning
		}
		// Now that we've found a newline, read a number
		n, err := strconv.ParseInt(string(sparseHeader[:nl]), 10, 0)
		if err != nil {
			return 0, ErrHeader
		}

		// Update sparseHeader to consume this number
		sparseHeader = sparseHeader[nl+1:]
		return n, nil
	}

	// Read the first block
	if _, err := io.ReadFull(r, sparseHeader); err != nil {
		return nil, err
	}

	// The first line contains the number of entries
	numEntries, err := readDecimal()
	if err != nil {
		return nil, err
	}

	// Read all the entries
	sp := make([]sparseEntry, 0, numEntries)
	for i := int64(0); i < numEntries; i++ {
		// Read the offset
		offset, err := readDecimal()
		if err != nil {
			return nil, err
		}
		// Read numBytes
		numBytes, err := readDecimal()
		if err != nil {
			return nil, err
		}

		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
	}

	return sp, nil
}
// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0.
// The sparse map is stored just before the file data and padded out to the nearest block boundary.
readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0.
The sparse map is stored just before the file data and padded out to the nearest block boundary.
// readGNUSparseMap1x0 reads the sparse map as stored in GNU ' s PAX sparse format version 1 . 0 . // The sparse map is stored just before the file data and padded out to the nearest block boundary .
func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) {
	buf := make([]byte, 2*blockSize)
	sparseHeader := buf[:blockSize]
	readDecimal := func() (int64, error) {
		nl := bytes.IndexByte(sparseHeader, '\n')
		if nl == -1 {
			if len(sparseHeader) >= blockSize {
				return 0, ErrHeader
			}
			oldLen := len(sparseHeader)
			newLen := oldLen + blockSize
			if cap(sparseHeader) < newLen {
				copy(buf, sparseHeader)
				sparseHeader = buf[:newLen]
			} else {
				sparseHeader = sparseHeader[:newLen]
			}
			if _, err := io.ReadFull(r, sparseHeader[oldLen:newLen]); err != nil {
				return 0, err
			}
			nl = bytes.IndexByte(sparseHeader[oldLen:newLen], '\n')
			if nl == -1 {
				return 0, ErrHeader
			}
			nl += oldLen 
		}
		n, err := strconv.ParseInt(string(sparseHeader[:nl]), 10, 0)
		if err != nil {
			return 0, ErrHeader
		}
		sparseHeader = sparseHeader[nl+1:]
		return n, nil
	}
	if _, err := io.ReadFull(r, sparseHeader); err != nil {
		return nil, err
	}
	numEntries, err := readDecimal()
	if err != nil {
		return nil, err
	}
	sp := make([]sparseEntry, 0, numEntries)
	for i := int64(0); i < numEntries; i++ {
		offset, err := readDecimal()
		if err != nil {
			return nil, err
		}
		numBytes, err := readDecimal()
		if err != nil {
			return nil, err
		}
		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
	}
	return sp, nil
}
func readGNUSparseMap1x0 ( r io . Reader ) ( [ ] sparseEntry , error ) { buf := make ( [ ] byte , 2 * blockSize ) sparseHeader := buf [ : blockSize ] readDecimal := func ( ) ( int64 , error ) { nl := bytes . IndexByte ( sparseHeader , '\n' ) if nl == - 1 { if len ( sparseHeader ) >= blockSize { return 0 , ErrHeader } oldLen := len ( sparseHeader ) newLen := oldLen + blockSize if cap ( sparseHeader ) < newLen { copy ( buf , sparseHeader ) sparseHeader = buf [ : newLen ] } else { sparseHeader = sparseHeader [ : newLen ] } if _ , err := io . ReadFull ( r , sparseHeader [ oldLen : newLen ] ) ; err != nil { return 0 , err } nl = bytes . IndexByte ( sparseHeader [ oldLen : newLen ] , '\n' ) if nl == - 1 { return 0 , ErrHeader } nl += oldLen } n , err := strconv . ParseInt ( string ( sparseHeader [ : nl ] ) , 10 , 0 ) if err != nil { return 0 , ErrHeader } sparseHeader = sparseHeader [ nl + 1 : ] return n , nil } if _ , err := io . ReadFull ( r , sparseHeader ) ; err != nil { return nil , err } numEntries , err := readDecimal ( ) if err != nil { return nil , err } sp := make ( [ ] sparseEntry , 0 , numEntries ) for i := int64 ( 0 ) ; i < numEntries ; i ++ { offset , err := readDecimal ( ) if err != nil { return nil , err } numBytes , err := readDecimal ( ) if err != nil { return nil , err } sp = append ( sp , sparseEntry { offset : offset , numBytes : numBytes } ) } return sp , nil }
readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0.
readGNUSparseMap1x0 reads the sparse map as stored in GNU ' s PAX sparse format version 1 . 0 .
// readDecimal is a helper function to read a decimal integer from the sparse map // while making sure to read from the file in blocks of size blockSize // Look for newline // This is an error // There's more header, but we need to make room for the next block // There's more header, and we can just reslice // Now that sparseHeader is large enough, read next block // Look for a newline in the new data // This is an error // We want the position from the beginning // Now that we've found a newline, read a number // Update sparseHeader to consume this number // Read the first block // The first line contains the number of entries // Read all the entries // Read the offset // Read numBytes