github.com/cyverse/go-irodsclient@v0.13.2/irods/util/io.go (about)

     1  package util
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/cyverse/go-irodsclient/irods/common"
     7  	"golang.org/x/xerrors"
     8  )
     9  
    10  // ReadBytes reads data from socket in a particular size
    11  func ReadBytes(socket net.Conn, buffer []byte, size int) (int, error) {
    12  	readLen, err := ReadBytesWithTrackerCallBack(socket, buffer, size, nil)
    13  	if err != nil {
    14  		return readLen, xerrors.Errorf("failed to read bytes from socket: %w", err)
    15  	}
    16  	return readLen, nil
    17  }
    18  
    19  // ReadBytesWithTrackerCallBack reads data from socket in a particular size
    20  func ReadBytesWithTrackerCallBack(socket net.Conn, buffer []byte, size int, callback common.TrackerCallBack) (int, error) {
    21  	totalSizeToRead := size
    22  	sizeLeft := size
    23  	actualRead := 0
    24  
    25  	for sizeLeft > 0 {
    26  		sizeRead, err := socket.Read(buffer[actualRead:size])
    27  		if err != nil {
    28  			return actualRead, xerrors.Errorf("failed to read from socket: %w", err)
    29  		}
    30  
    31  		sizeLeft -= sizeRead
    32  		actualRead += sizeRead
    33  
    34  		if callback != nil {
    35  			callback(int64(actualRead), int64(totalSizeToRead))
    36  		}
    37  	}
    38  
    39  	if sizeLeft < 0 {
    40  		return actualRead, xerrors.Errorf("received more bytes than requested, %d requested, but %d read", size, actualRead)
    41  	}
    42  
    43  	return actualRead, nil
    44  }
    45  
    46  // WriteBytes writes data to socket
    47  func WriteBytes(socket net.Conn, buffer []byte, size int) error {
    48  	err := WriteBytesWithTrackerCallBack(socket, buffer, size, nil)
    49  	if err != nil {
    50  		return xerrors.Errorf("failed to write bytes to socket: %w", err)
    51  	}
    52  	return nil
    53  }
    54  
    55  // WriteBytesWithTrackerCallBack writes data to socket
    56  func WriteBytesWithTrackerCallBack(socket net.Conn, buffer []byte, size int, callback common.TrackerCallBack) error {
    57  	totalSizeToSend := len(buffer)
    58  	sizeLeft := totalSizeToSend
    59  	actualWrite := 0
    60  
    61  	for sizeLeft > 0 {
    62  		sizeWrite, err := socket.Write(buffer[actualWrite:size])
    63  		if err != nil {
    64  			return xerrors.Errorf("failed to write to socket: %w", err)
    65  		}
    66  
    67  		sizeLeft -= sizeWrite
    68  		actualWrite += sizeWrite
    69  
    70  		if callback != nil {
    71  			callback(int64(actualWrite), int64(totalSizeToSend))
    72  		}
    73  	}
    74  
    75  	return nil
    76  }