mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-10-19 13:49:53 +00:00
76 lines
2.0 KiB
Go
76 lines
2.0 KiB
Go
|
//go:build go1.18
|
||
|
// +build go1.18
|
||
|
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// Licensed under the MIT License.
|
||
|
|
||
|
package streaming
|
||
|
|
||
|
import (
|
||
|
"io"
|
||
|
|
||
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||
|
)
|
||
|
|
||
|
type progress struct {
|
||
|
rc io.ReadCloser
|
||
|
rsc io.ReadSeekCloser
|
||
|
pr func(bytesTransferred int64)
|
||
|
offset int64
|
||
|
}
|
||
|
|
||
|
// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker.
|
||
|
// In addition to adding a Close method to an io.ReadSeeker, this can also be used to wrap an
|
||
|
// io.ReadSeekCloser with a no-op Close method to allow explicit control of when the io.ReedSeekCloser
|
||
|
// has its underlying stream closed.
|
||
|
func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser {
|
||
|
return exported.NopCloser(rs)
|
||
|
}
|
||
|
|
||
|
// NewRequestProgress adds progress reporting to an HTTP request's body stream.
|
||
|
func NewRequestProgress(body io.ReadSeekCloser, pr func(bytesTransferred int64)) io.ReadSeekCloser {
|
||
|
return &progress{
|
||
|
rc: body,
|
||
|
rsc: body,
|
||
|
pr: pr,
|
||
|
offset: 0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// NewResponseProgress adds progress reporting to an HTTP response's body stream.
|
||
|
func NewResponseProgress(body io.ReadCloser, pr func(bytesTransferred int64)) io.ReadCloser {
|
||
|
return &progress{
|
||
|
rc: body,
|
||
|
rsc: nil,
|
||
|
pr: pr,
|
||
|
offset: 0,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Read reads a block of data from an inner stream and reports progress
|
||
|
func (p *progress) Read(b []byte) (n int, err error) {
|
||
|
n, err = p.rc.Read(b)
|
||
|
if err != nil && err != io.EOF {
|
||
|
return
|
||
|
}
|
||
|
p.offset += int64(n)
|
||
|
// Invokes the user's callback method to report progress
|
||
|
p.pr(p.offset)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Seek only expects a zero or from beginning.
|
||
|
func (p *progress) Seek(offset int64, whence int) (int64, error) {
|
||
|
// This should only ever be called with offset = 0 and whence = io.SeekStart
|
||
|
n, err := p.rsc.Seek(offset, whence)
|
||
|
if err == nil {
|
||
|
p.offset = int64(n)
|
||
|
}
|
||
|
return n, err
|
||
|
}
|
||
|
|
||
|
// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it.
|
||
|
func (p *progress) Close() error {
|
||
|
return p.rc.Close()
|
||
|
}
|