You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: helpers.go
    path of file: ./repos/rclone/backend/hidrive
    
    the code of the file until where you have to start completion: package hidrive

// This file is for helper-functions which may provide more general and
// specialized functionality than the generic interfaces.
// There are two sections:
// 1. methods bound to Fs
// 2. other functions independent from Fs used throughout the package

// NOTE: Functions accessing paths expect any relative paths
// to be resolved prior to execution with resolvePath(...).

import (
	"bytes"
	"context"
	"errors"
	"io"
	"net/http"
	"path"
	"strconv"
	"sync"
	"time"

	"github.com/rclone/rclone/backend/hidrive/api"
	"github.com/rclone/rclone/fs"
	"github.com/rclone/rclone/fs/accounting"
	"github.com/rclone/rclone/fs/fserrors"
	"github.com/rclone/rclone/lib/ranges"
	"github.com/rclone/rclone/lib/readers"
	"github.com/rclone/rclone/lib/rest"
	"golang.org/x/sync/errgroup"
	"golang.org/x/sync/semaphore"
)

const (
	// MaximumUploadBytes represents the maximum amount of bytes
	// a single upload-operation will support.
	MaximumUploadBytes = 2147483647 // = 2GiB - 1
	// iterationChunkSize represents the chunk size used to iterate directory contents.
	iterationChunkSize = 5000
)

var (
	// retryErrorCodes is a slice of error codes that we will always retry.
	retryErrorCodes = []int{
		429, // Too Many Requests
		500, // Internal Server Error
		502, // Bad Gateway
		503, // Service Unavailable
		504, // Gateway Timeout
		509, // Bandwidth Limit Exceeded
	}
	// ErrorFileExists is returned when a query tries to create a file
	// that already exists.
	ErrorFileExists = errors.New("destination file already exists")
)

// MemberType represents the possible types of entries a directory can contain.
type MemberType string

// possible values for MemberType
const (
	AllMembers       MemberType = "all"
	NoMembers        MemberType = "none"
	DirectoryMembers MemberType = api.HiDriveObjectTypeDirectory
	FileMembers      MemberType = api.HiDriveObjectTypeFile
	SymlinkMembers   MemberType = api.HiDriveObjectTypeSymlink
)

// SortByField represents possibl
    
func (f *Fs) updateFileChunked(ctx context.Context, path string, content io.Reader, offset uint64, chunkSize int, transferLimit int64) (okSize uint64, err error) {
	var (
		okChunksMu sync.Mutex // protects the variables below
		okChunks   []ranges.Range
	)
	g, gCtx := errgroup.WithContext(ctx)
	transferSemaphore := semaphore.NewWeighted(transferLimit)

	var readErr error
	startMoreTransfers := true
	zeroTime := time.Time{}
	for chunk := uint64(0); startMoreTransfers; chunk++ {
		// Acquire semaphore to limit number of transfers in parallel.
		readErr = transferSemaphore.Acquire(gCtx, 1)
		if readErr != nil {
			break
		}

		// Read a chunk of data.
		chunkReader, bytesRead, readErr := readerForChunk(content, chunkSize)
		if bytesRead < chunkSize {
			startMoreTransfers = false
		}
		if readErr != nil || bytesRead <= 0 {
			break
		}

		// Transfer the chunk.
		chunkOffset := uint64(chunkSize)*chunk + offset
		g.Go(func() error {
			// After this upload is done,
			// signal that another transfer can be started.
			defer transferSemaphore.Release(1)
			uploadErr := f.patchFile(gCtx, path, cachedReader(chunkReader), chunkOffset, zeroTime)
			if uploadErr == nil {
				// Remember successfully written chunks.
				okChunksMu.Lock()
				okChunks = append(okChunks, ranges.Range{Pos: int64(chunkOffset), Size: int64(bytesRead)})
				okChunksMu.Unlock()
				fs.Debugf(f, "Done uploading chunk of size %v at offset %v.", bytesRead, chunkOffset)
			} else {
				fs.Infof(f, "Error while uploading chunk at offset %v. Error is %v.", chunkOffset, uploadErr)
			}
			return uploadErr
		})
	}

	if readErr != nil {
		// Log the error in case it is later ignored because of an upload-error.
		fs.Infof(f, "Error while reading/preparing to upload a chunk. Error is %v.", readErr)
	}

	err = g.Wait()

	// Compute the first continuous range of the file content,
	// which does not contain any failed chunks.
	// Do not forget to add the file content up to the starting offset,
	// which is presumed to be already correct.
	rs := ranges.Ranges{}
	rs.Insert(ranges.Range{Pos: 0, Size: int64(offset)})
	for _, chunkRange := range okChunks {
		rs.Insert(chunkRange)
	}
	if len(rs) > 0 && rs[0].Pos == 0 {
		okSize = uint64(rs[0].Size)
	}

	if err != nil {
		return okSize, err
	}
	if readErr != nil {
		return okSize, readErr
	}

	return okSize, nil
}