...
1
2
3
4
5 package gensupport
6
7 import (
8 "bytes"
9 "io"
10
11 "google.golang.org/api/googleapi"
12 )
13
14
15
16 type MediaBuffer struct {
17 media io.Reader
18
19 chunk []byte
20 err error
21
22
23 off int64
24 }
25
26
27 func NewMediaBuffer(media io.Reader, chunkSize int) *MediaBuffer {
28 return &MediaBuffer{media: media, chunk: make([]byte, 0, chunkSize)}
29 }
30
31
32
33
34 func (mb *MediaBuffer) Chunk() (chunk io.Reader, off int64, size int, err error) {
35
36 if mb.err == nil && len(mb.chunk) == 0 {
37 mb.err = mb.loadChunk()
38 }
39 return bytes.NewReader(mb.chunk), mb.off, len(mb.chunk), mb.err
40 }
41
42
43 func (mb *MediaBuffer) loadChunk() error {
44 bufSize := cap(mb.chunk)
45 mb.chunk = mb.chunk[:bufSize]
46
47 read := 0
48 var err error
49 for err == nil && read < bufSize {
50 var n int
51 n, err = mb.media.Read(mb.chunk[read:])
52 read += n
53 }
54 mb.chunk = mb.chunk[:read]
55 return err
56 }
57
58
59
60 func (mb *MediaBuffer) Next() {
61 mb.off += int64(len(mb.chunk))
62 mb.chunk = mb.chunk[0:0]
63 }
64
65 type readerTyper struct {
66 io.Reader
67 googleapi.ContentTyper
68 }
69
70
71
72
73 func ReaderAtToReader(ra io.ReaderAt, size int64) io.Reader {
74 r := io.NewSectionReader(ra, 0, size)
75 if typer, ok := ra.(googleapi.ContentTyper); ok {
76 return readerTyper{r, typer}
77 }
78 return r
79 }
80
View as plain text