github.com/Files-com/files-sdk-go/v3@v3.1.81/file/offset.go (about)

     1  package file
     2  
     3  import (
     4  	"context"
     5  	"math"
     6  	"sync"
     7  	"time"
     8  
     9  	files_sdk "github.com/Files-com/files-sdk-go/v3"
    10  	"github.com/Files-com/files-sdk-go/v3/lib"
    11  )
    12  
    13  type OffSet struct {
    14  	off int64
    15  	len int64
    16  }
    17  
    18  type Part struct {
    19  	OffSet
    20  	files_sdk.EtagsParam
    21  	bytes    int64
    22  	requests []time.Time
    23  	error
    24  	number     int
    25  	processing bool
    26  	context.Context
    27  	context.CancelFunc
    28  	*sync.RWMutex
    29  	final bool
    30  	files_sdk.FileUploadPart
    31  	ProxyReader
    32  }
    33  
    34  func (p *Part) Done() *Part {
    35  	p.processing = false
    36  	return p
    37  }
    38  
    39  func (p *Part) Start(ctx ...context.Context) *Part {
    40  	p.Touch()
    41  	p.processing = true
    42  	if len(ctx) == 1 {
    43  		p.WithContext(ctx[0])
    44  	}
    45  	return p
    46  }
    47  
    48  func (p *Part) WithContext(ctx context.Context) *Part {
    49  	p.RWMutex = &sync.RWMutex{}
    50  	p.Context, p.CancelFunc = context.WithCancel(ctx)
    51  	return p
    52  }
    53  
    54  func (p *Part) Touch() {
    55  	p.requests = append(p.requests, time.Now())
    56  }
    57  
    58  func (p *Part) Successful() bool {
    59  	return p.bytes == p.len && p.error == nil
    60  }
    61  
    62  func (p *Part) Clear() {
    63  	p.bytes = 0
    64  	p.error = nil
    65  }
    66  
    67  func (p *Part) SetError(err error) {
    68  	p.Lock()
    69  	defer p.Unlock()
    70  	p.error = err
    71  }
    72  
    73  func (p *Part) Err() error {
    74  	p.RLock()
    75  	defer p.RUnlock()
    76  	if p.error != nil {
    77  		return p.error
    78  	}
    79  
    80  	return p.Context.Err()
    81  }
    82  
    83  type Parts []*Part
    84  
    85  func (p Parts) SuccessfulBytes() (b int64) {
    86  	for _, part := range p {
    87  		if part.Successful() {
    88  			b += part.bytes
    89  		}
    90  	}
    91  
    92  	return b
    93  }
    94  
    95  type ByteOffset struct {
    96  	PartSizes []int64
    97  }
    98  
    99  func (b ByteOffset) WithDefaultChunkSize(size *int64, off int64, index int, defaultChunkSize int64) Iterator {
   100  	return func() (OffSet, Iterator, int) {
   101  		// if size is nil or off is still less than size
   102  		if size == nil || off < *size {
   103  			endRange := off + b.PartSizes[index]
   104  
   105  			if size != nil && *size > endRange {
   106  				endRange = defaultChunkSize
   107  			}
   108  
   109  			// if size is not nil, limit endRange by size
   110  			if size != nil {
   111  				endRange = int64(math.Min(float64(endRange), float64(*size)))
   112  			}
   113  
   114  			offset := OffSet{off: off, len: endRange - off}
   115  
   116  			off = endRange
   117  
   118  			// if there are no more partSizes or off is already more than size, return nil iterator
   119  			if index >= len(lib.PartSizes)-1 || (size != nil && off >= *size) {
   120  				return offset, nil, index + 1
   121  			}
   122  
   123  			return offset, b.Resume(size, off, index+1), index
   124  		}
   125  
   126  		return OffSet{}, nil, index
   127  	}
   128  }
   129  
   130  func (b ByteOffset) BySize(size *int64) Iterator {
   131  	return b.Resume(size, 0, 0)
   132  }
   133  
   134  func (b ByteOffset) Resume(size *int64, off int64, index int) Iterator {
   135  	return func() (OffSet, Iterator, int) {
   136  		// if size is nil or off is still less than size
   137  		if size == nil || off < *size {
   138  			endRange := off + b.PartSizes[index]
   139  
   140  			// if size is not nil, limit endRange by size
   141  			if size != nil {
   142  				endRange = int64(math.Min(float64(endRange), float64(*size)))
   143  			}
   144  
   145  			offset := OffSet{off: off, len: endRange - off}
   146  
   147  			off = endRange
   148  
   149  			// if there are no more partSizes or off is already more than size, return nil iterator
   150  			if index >= len(lib.PartSizes)-1 || (size != nil && off >= *size) {
   151  				return offset, nil, index
   152  			}
   153  
   154  			return offset, b.Resume(size, off, index+1), index
   155  		}
   156  
   157  		return OffSet{}, nil, index
   158  	}
   159  }
   160  
   161  type Iterator func() (OffSet, Iterator, int)