-
Notifications
You must be signed in to change notification settings - Fork 4
/
byte_range.go
66 lines (51 loc) · 1.68 KB
/
byte_range.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
package objval
import (
"bytes"
"errors"
"fmt"
"strconv"
)
// ErrByteRangeRequired is returned when a function which requires a byte range hasn't been provided with one.
var ErrByteRangeRequired = errors.New("a byte range is required but hasn't been provided")
// InvalidByteRangeError is returned if a byte range is invalid for some reason.
type InvalidByteRangeError struct {
ByteRange *ByteRange
}
// Error implements the 'error' interface.
func (e *InvalidByteRangeError) Error() string {
return fmt.Sprintf("invalid byte range %d-%d", e.ByteRange.Start, e.ByteRange.End)
}
// ByteRange represents a byte range of an object in the HTTP range header format. For more information on the format
// see 'https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35'.
type ByteRange struct {
Start int64
End int64
}
// Valid returns an error if the byte range is invalid, <nil> otherwise.
func (b *ByteRange) Valid(required bool) error {
if b == nil && required {
return ErrByteRangeRequired
}
if b == nil || b.End == 0 || b.End >= b.Start {
return nil
}
return &InvalidByteRangeError{ByteRange: b}
}
// ToOffsetLength returns the offset/length representation of this byte range.
func (b *ByteRange) ToOffsetLength(length int64) (int64, int64) {
offset := b.Start
if b.End != 0 {
length = b.End - offset + 1
}
return offset, length
}
// ToRangeHeader returns the HTTP range header representation of this byte range.
func (b *ByteRange) ToRangeHeader() string {
buffer := &bytes.Buffer{}
buffer.WriteString("bytes=")
buffer.WriteString(strconv.FormatInt(b.Start, 10) + "-")
if b.End != 0 {
buffer.WriteString(strconv.FormatInt(b.End, 10))
}
return buffer.String()
}