gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

graceful_copy.go (1133B)


      1 package rifs
      2 
      3 import (
      4 	"fmt"
      5 	"io"
      6 )
      7 
      8 const (
      9 	defaultCopyBufferSize = 1024 * 1024
     10 )
     11 
     12 // GracefulCopy willcopy while enduring lesser normal issues.
     13 //
     14 // - We'll ignore EOF if the read byte-count is more than zero. Only an EOF when
     15 //   zero bytes were read will terminate the loop.
     16 //
     17 // - Ignore short-writes. If less bytes were written than the bytes that were
     18 //   given, we'll keep trying until done.
     19 func GracefulCopy(w io.Writer, r io.Reader, buffer []byte) (copyCount int, err error) {
     20 	if buffer == nil {
     21 		buffer = make([]byte, defaultCopyBufferSize)
     22 	}
     23 
     24 	for {
     25 		readCount, err := r.Read(buffer)
     26 		if err != nil {
     27 			if err != io.EOF {
     28 				err = fmt.Errorf("read error: %s", err.Error())
     29 				return 0, err
     30 			}
     31 
     32 			// Only break on EOF if no bytes were actually read.
     33 			if readCount == 0 {
     34 				break
     35 			}
     36 		}
     37 
     38 		writeBuffer := buffer[:readCount]
     39 
     40 		for len(writeBuffer) > 0 {
     41 			writtenCount, err := w.Write(writeBuffer)
     42 			if err != nil {
     43 				err = fmt.Errorf("write error: %s", err.Error())
     44 				return 0, err
     45 			}
     46 
     47 			writeBuffer = writeBuffer[writtenCount:]
     48 		}
     49 
     50 		copyCount += readCount
     51 	}
     52 
     53 	return copyCount, nil
     54 }