github.com/gogf/gf@v1.16.9/internal/utils/utils_io.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package utils 8 9 import ( 10 "io" 11 "io/ioutil" 12 ) 13 14 // ReadCloser implements the io.ReadCloser interface 15 // which is used for reading request body content multiple times. 16 // 17 // Note that it cannot be closed. 18 type ReadCloser struct { 19 index int // Current read position. 20 content []byte // Content. 21 repeatable bool 22 } 23 24 // NewReadCloser creates and returns a RepeatReadCloser object. 25 func NewReadCloser(content []byte, repeatable bool) io.ReadCloser { 26 return &ReadCloser{ 27 content: content, 28 repeatable: repeatable, 29 } 30 } 31 32 // NewReadCloserWithReadCloser creates and returns a RepeatReadCloser object 33 // with given io.ReadCloser. 34 func NewReadCloserWithReadCloser(r io.ReadCloser, repeatable bool) (io.ReadCloser, error) { 35 content, err := ioutil.ReadAll(r) 36 if err != nil { 37 return nil, err 38 } 39 defer r.Close() 40 return &ReadCloser{ 41 content: content, 42 repeatable: repeatable, 43 }, nil 44 } 45 46 // Read implements the io.ReadCloser interface. 47 func (b *ReadCloser) Read(p []byte) (n int, err error) { 48 n = copy(p, b.content[b.index:]) 49 b.index += n 50 if b.index >= len(b.content) { 51 // Make it repeatable reading. 52 if b.repeatable { 53 b.index = 0 54 } 55 return n, io.EOF 56 } 57 return n, nil 58 } 59 60 // Close implements the io.ReadCloser interface. 61 func (b *ReadCloser) Close() error { 62 return nil 63 }