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)