forked from navi-tt/storage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
base.go
116 lines (93 loc) · 1.74 KB
/
base.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package storage
import (
"io"
"os"
"path"
"runtime"
"strings"
"time"
"unicode/utf8"
)
type StorageType string
const (
FS StorageType = "fs"
COS StorageType = "cos"
QS StorageType = "qs"
)
// 长度在1-1023字节之间
// 第一个字符不能是 '\'
// 必须是UTF-8编码
// 不能包含 ' '、'\t'、'\r'或者'\n'等字符
func ValidKey(key string) bool {
system := strings.ToLower(runtime.GOOS)
_, fn := path.Split(key)
if system == "ubuntu" {
if strings.Contains(fn, "(") || strings.Contains(fn, ")") {
return false
}
}
if len(fn) == 0 || fn[0] == '\\' || fn[0] == '/' || len(fn) >= 1024 {
return false
}
for i := range fn {
if fn[i] == ' ' || fn[i] == '\t' || fn[i] == '\r' || fn[i] == '\n' {
return false
}
}
return utf8.ValidString(fn)
}
type FileInfo struct {
Size int64
ModTime time.Time
Mode os.FileMode
}
func OpenLocal(key string) (*os.File, os.FileInfo, error) {
var (
err error
fd *os.File
stat os.FileInfo
)
if !ValidKey(key) {
return nil, nil, ErrObjectKeyInvalid
}
fd, err = os.Open(key)
if err != nil {
if os.IsNotExist(err) {
return nil, nil, ErrObjectNotFound
}
if os.IsPermission(err) {
return nil, nil, ErrObjectReadPermissionDeny
}
return nil, nil, err
}
stat, err = fd.Stat()
if err != nil {
return nil, nil, err
}
if stat.Size() == 0 {
return nil, nil, ErrObjectEmptyContent
}
return fd, stat, nil
}
func Copy(wa io.WriterAt, r io.Reader) error {
var (
buf = make([]byte, 1024)
off int64 = 0
)
for {
n, err1 := r.Read(buf)
buf := buf[:n]
n, err2 := wa.WriteAt(buf, off)
if err2 != nil {
return err2
}
off += int64(n)
if err1 != nil {
if err1 == io.EOF {
break
}
return err1
}
}
return nil
}