| 26 | } |
| 27 | |
| 28 | func NewReader(r io.Reader, max int64, path string) (ReadSeekSizeCloser, error) { |
| 29 | buf := make([]byte, max+1) |
| 30 | n, err := io.ReadFull(r, buf) |
| 31 | if err == nil { |
| 32 | f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o666) |
| 33 | if err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | var ok bool |
| 37 | defer func() { |
| 38 | if !ok { |
| 39 | _ = f.Close() |
| 40 | _ = os.Remove(path) |
| 41 | } |
| 42 | }() |
| 43 | if _, err := f.Write(buf[:n]); err != nil { |
| 44 | return nil, err |
| 45 | } |
| 46 | cn, err := io.Copy(f, r) |
| 47 | if err != nil { |
| 48 | return nil, err |
| 49 | } |
| 50 | if _, err := f.Seek(0, io.SeekStart); err != nil { |
| 51 | return nil, err |
| 52 | } |
| 53 | ok = true |
| 54 | return &fileBuffer{ |
| 55 | f: f, |
| 56 | n: cn + int64(n), |
| 57 | }, nil |
| 58 | } else if err == io.EOF || err == io.ErrUnexpectedEOF { |
| 59 | return &memoryBuffer{ |
| 60 | r: bytes.NewReader(buf[:n]), |
| 61 | }, nil |
| 62 | } else { |
| 63 | return nil, err |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | type fileBuffer struct { |
| 68 | n int64 |