github.com/qiniu/x@v1.11.9/bytes/bytes.go (about)

     1  /*
     2   Copyright 2020 Qiniu Limited (qiniu.com)
     3  
     4   Licensed under the Apache License, Version 2.0 (the "License");
     5   you may not use this file except in compliance with the License.
     6   You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10   Unless required by applicable law or agreed to in writing, software
    11   distributed under the License is distributed on an "AS IS" BASIS,
    12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   See the License for the specific language governing permissions and
    14   limitations under the License.
    15  */
    16  
    17  package bytes
    18  
    19  import (
    20  	"io"
    21  	"syscall"
    22  )
    23  
    24  // ---------------------------------------------------
    25  
    26  // Unlike the standard library's bytes.Reader, this Reader supports Seek.
    27  type Reader struct {
    28  	b   []byte
    29  	off int
    30  }
    31  
    32  // NewReader create a readonly stream for byte slice:
    33  //
    34  //	 var slice []byte
    35  //	 ...
    36  //	 r := bytes.NewReader(slice)
    37  //	 ...
    38  //	 r.Seek(0, 0) // r.SeekToBegin()
    39  //	 ...
    40  //
    41  // Unlike the standard library's bytes.Reader, the returned Reader supports Seek.
    42  func NewReader(val []byte) *Reader {
    43  	return &Reader{val, 0}
    44  }
    45  
    46  func (r *Reader) Len() int {
    47  	if r.off >= len(r.b) {
    48  		return 0
    49  	}
    50  	return len(r.b) - r.off
    51  }
    52  
    53  func (r *Reader) Bytes() []byte {
    54  	return r.b[r.off:]
    55  }
    56  
    57  func (r *Reader) SeekToBegin() (err error) {
    58  	r.off = 0
    59  	return
    60  }
    61  
    62  func (r *Reader) Seek(offset int64, whence int) (ret int64, err error) {
    63  	switch whence {
    64  	case 0:
    65  	case 1:
    66  		offset += int64(r.off)
    67  	case 2:
    68  		offset += int64(len(r.b))
    69  	default:
    70  		err = syscall.EINVAL
    71  		return
    72  	}
    73  	if offset < 0 {
    74  		err = syscall.EINVAL
    75  		return
    76  	}
    77  	if offset >= int64(len(r.b)) {
    78  		r.off = len(r.b)
    79  	} else {
    80  		r.off = int(offset)
    81  	}
    82  	ret = int64(r.off)
    83  	return
    84  }
    85  
    86  func (r *Reader) Read(val []byte) (n int, err error) {
    87  	n = copy(val, r.b[r.off:])
    88  	if n == 0 && len(val) != 0 {
    89  		err = io.EOF
    90  		return
    91  	}
    92  	r.off += n
    93  	return
    94  }
    95  
    96  func (r *Reader) Close() (err error) {
    97  	return
    98  }
    99  
   100  // ---------------------------------------------------
   101  
   102  // Writer implements a write stream with a limited capacity.
   103  type Writer struct {
   104  	b []byte
   105  	n int
   106  }
   107  
   108  // NewWriter NewWriter creates a write stream with a limited capacity:
   109  //
   110  //	 slice := make([]byte, 1024)
   111  //	 w := bytes.NewWriter(slice)
   112  //	 ...
   113  //	 writtenData := w.Bytes()
   114  //
   115  // If we write more than 1024 bytes of data to w, the excess data will be discarded.
   116  func NewWriter(buff []byte) *Writer {
   117  	return &Writer{buff, 0}
   118  }
   119  
   120  func (p *Writer) Write(val []byte) (n int, err error) {
   121  	n = copy(p.b[p.n:], val)
   122  	if n == 0 && len(val) > 0 {
   123  		err = io.EOF
   124  		return
   125  	}
   126  	p.n += n
   127  	return
   128  }
   129  
   130  func (p *Writer) Len() int {
   131  	return p.n
   132  }
   133  
   134  func (p *Writer) Bytes() []byte {
   135  	return p.b[:p.n]
   136  }
   137  
   138  // Reset deletes all written data.
   139  func (p *Writer) Reset() {
   140  	p.n = 0
   141  }
   142  
   143  // ---------------------------------------------------
   144  
   145  type Buffer struct {
   146  	b []byte
   147  }
   148  
   149  // NewBuffer creates a random read/write memory file that supports ReadAt/WriteAt
   150  // methods instead of Read/Write:
   151  //
   152  //	 b := bytes.NewBuffer()
   153  //	 b.Truncate(100)
   154  //	 b.WriteAt([]byte("hello"), 100)
   155  //	 slice := make([]byte, 105)
   156  //	 n, err := b.ReadAt(slice, 0)
   157  //	 ...
   158  //
   159  func NewBuffer() *Buffer {
   160  	return new(Buffer)
   161  }
   162  
   163  func (p *Buffer) ReadAt(buf []byte, off int64) (n int, err error) {
   164  	ioff := int(off)
   165  	if len(p.b) <= ioff {
   166  		return 0, io.EOF
   167  	}
   168  	n = copy(buf, p.b[ioff:])
   169  	if n != len(buf) {
   170  		err = io.EOF
   171  	}
   172  	return
   173  }
   174  
   175  func (p *Buffer) WriteAt(buf []byte, off int64) (n int, err error) {
   176  	ioff := int(off)
   177  	iend := ioff + len(buf)
   178  	if len(p.b) < iend {
   179  		if len(p.b) == ioff {
   180  			p.b = append(p.b, buf...)
   181  			return len(buf), nil
   182  		}
   183  		zero := make([]byte, iend-len(p.b))
   184  		p.b = append(p.b, zero...)
   185  	}
   186  	copy(p.b[ioff:], buf)
   187  	return len(buf), nil
   188  }
   189  
   190  func (p *Buffer) WriteStringAt(buf string, off int64) (n int, err error) {
   191  	ioff := int(off)
   192  	iend := ioff + len(buf)
   193  	if len(p.b) < iend {
   194  		if len(p.b) == ioff {
   195  			p.b = append(p.b, buf...)
   196  			return len(buf), nil
   197  		}
   198  		zero := make([]byte, iend-len(p.b))
   199  		p.b = append(p.b, zero...)
   200  	}
   201  	copy(p.b[ioff:], buf)
   202  	return len(buf), nil
   203  }
   204  
   205  func (p *Buffer) Truncate(fsize int64) (err error) {
   206  	size := int(fsize)
   207  	if len(p.b) < size {
   208  		zero := make([]byte, size-len(p.b))
   209  		p.b = append(p.b, zero...)
   210  	} else {
   211  		p.b = p.b[:size]
   212  	}
   213  	return nil
   214  }
   215  
   216  func (p *Buffer) Buffer() []byte {
   217  	return p.b
   218  }
   219  
   220  func (p *Buffer) Len() int {
   221  	return len(p.b)
   222  }
   223  
   224  // ---------------------------------------------------