prow/spyglass/gcsartifact.go
func (a *GCSArtifact) ReadAt(p []byte, off int64) (n int, err error) {
	gzipped, err := a.gzipped()
	if err != nil {
		return 0, fmt.Errorf("error checking artifact for gzip compression: %v", err)
	}
	if gzipped {
		return 0, lenses.ErrGzipOffsetRead
	}
	artifactSize, err := a.Size()
	if err != nil {
		return 0, fmt.Errorf("error getting artifact size: %v", err)
	}
	if off >= artifactSize {
		return 0, fmt.Errorf("offset must be less than artifact size")
	}
	var gotEOF bool
	toRead := int64(len(p))
	if toRead+off > artifactSize {
		return 0, fmt.Errorf("read range exceeds artifact contents")
	} else if toRead+off == artifactSize {
		gotEOF = true
	}
	reader, err := a.handle.NewRangeReader(a.ctx, off, toRead)
	defer reader.Close()
	if err != nil {
		return 0, fmt.Errorf("error getting artifact reader: %v", err)
	}
	// We need to keep reading until we fill the buffer or hit EOF.
	offset := 0
	for offset < len(p) {
		n, err = reader.Read(p[offset:])
		offset += n
		if err != nil {
			if err == io.EOF && gotEOF {
				break
			}
			return 0, fmt.Errorf("error reading from artifact: %v", err)
		}
	}
	if gotEOF {
		return offset, io.EOF
	}
	return offset, nil
}
func (a *GCSArtifact) ReadAt(p []byte, off int64) (n int, err error) {
	gzipped, err := a.gzipped()
	if err != nil {
		return 0, fmt.Errorf("error checking artifact for gzip compression: %v", err)
	}
	if gzipped {
		return 0, lenses.ErrGzipOffsetRead
	}
	artifactSize, err := a.Size()
	if err != nil {
		return 0, fmt.Errorf("error getting artifact size: %v", err)
	}
	if off >= artifactSize {
		return 0, fmt.Errorf("offset must be less than artifact size")
	}
	var gotEOF bool
	toRead := int64(len(p))
	if toRead+off > artifactSize {
		return 0, fmt.Errorf("read range exceeds artifact contents")
	} else if toRead+off == artifactSize {
		gotEOF = true
	}
	reader, err := a.handle.NewRangeReader(a.ctx, off, toRead)
	defer reader.Close()
	if err != nil {
		return 0, fmt.Errorf("error getting artifact reader: %v", err)
	}
	// We need to keep reading until we fill the buffer or hit EOF.
	offset := 0
	for offset < len(p) {
		n, err = reader.Read(p[offset:])
		offset += n
		if err != nil {
			if err == io.EOF && gotEOF {
				break
			}
			return 0, fmt.Errorf("error reading from artifact: %v", err)
		}
	}
	if gotEOF {
		return offset, io.EOF
	}
	return offset, nil
}
// ReadAt reads len(p) bytes from a file in GCS at offset off