-
Notifications
You must be signed in to change notification settings - Fork 390
/
io.go
86 lines (71 loc) · 2.03 KB
/
io.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information
package sync2
import (
"io"
"os"
"sync/atomic"
"github.com/zeebo/errs"
)
// ReadAtWriteAtCloser implements all io.ReaderAt, io.WriterAt and io.Closer
type ReadAtWriteAtCloser interface {
io.ReaderAt
io.WriterAt
io.Closer
}
// PipeWriter allows closing the writer with an error
type PipeWriter interface {
io.WriteCloser
CloseWithError(reason error) error
}
// PipeReader allows closing the reader with an error
type PipeReader interface {
io.ReadCloser
CloseWithError(reason error) error
}
// memory implements ReadAtWriteAtCloser on a memory buffer
type memory []byte
// Size returns size of memory buffer
func (memory memory) Size() int { return len(memory) }
// ReadAt implements io.ReaderAt methods
func (memory memory) ReadAt(data []byte, at int64) (amount int, err error) {
if at > int64(len(memory)) {
return 0, io.ErrClosedPipe
}
amount = copy(data, memory[at:])
return amount, nil
}
// WriteAt implements io.WriterAt methods
func (memory memory) WriteAt(data []byte, at int64) (amount int, err error) {
if at > int64(len(memory)) {
return 0, io.ErrClosedPipe
}
amount = copy(memory[at:], data)
return amount, nil
}
// Close implements io.Closer implementation
func (memory memory) Close() error { return nil }
// offsetFile implements ReadAt, WriteAt offset to the file with reference counting
type offsetFile struct {
file *os.File
offset int64
open *int64 // number of handles open
}
// ReadAt implements io.ReaderAt methods
func (file offsetFile) ReadAt(data []byte, at int64) (amount int, err error) {
return file.file.ReadAt(data, file.offset+at)
}
// WriteAt implements io.WriterAt methods
func (file offsetFile) WriteAt(data []byte, at int64) (amount int, err error) {
return file.file.WriteAt(data, file.offset+at)
}
// Close implements io.Closer methods
func (file offsetFile) Close() error {
if atomic.AddInt64(file.open, -1) == 0 {
return errs.Combine(
file.file.Close(),
os.Remove(file.file.Name()),
)
}
return nil
}