| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- /*
- Copyright 2012 Google Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package groupcache
- import (
- "bytes"
- "errors"
- "io"
- "strings"
- )
- // A ByteView holds an immutable view of bytes.
- // Internally it wraps either a []byte or a string,
- // but that detail is invisible to callers.
- //
- // A ByteView is meant to be used as a value type, not
- // a pointer (like a time.Time).
- type ByteView struct {
- // If b is non-nil, b is used, else s is used.
- b []byte
- s string
- }
- // Len returns the view's length.
- func (v ByteView) Len() int {
- if v.b != nil {
- return len(v.b)
- }
- return len(v.s)
- }
- // ByteSlice returns a copy of the data as a byte slice.
- func (v ByteView) ByteSlice() []byte {
- if v.b != nil {
- return cloneBytes(v.b)
- }
- return []byte(v.s)
- }
- // String returns the data as a string, making a copy if necessary.
- func (v ByteView) String() string {
- if v.b != nil {
- return string(v.b)
- }
- return v.s
- }
- // At returns the byte at index i.
- func (v ByteView) At(i int) byte {
- if v.b != nil {
- return v.b[i]
- }
- return v.s[i]
- }
- // Slice slices the view between the provided from and to indices.
- func (v ByteView) Slice(from, to int) ByteView {
- if v.b != nil {
- return ByteView{b: v.b[from:to]}
- }
- return ByteView{s: v.s[from:to]}
- }
- // SliceFrom slices the view from the provided index until the end.
- func (v ByteView) SliceFrom(from int) ByteView {
- if v.b != nil {
- return ByteView{b: v.b[from:]}
- }
- return ByteView{s: v.s[from:]}
- }
- // Copy copies b into dest and returns the number of bytes copied.
- func (v ByteView) Copy(dest []byte) int {
- if v.b != nil {
- return copy(dest, v.b)
- }
- return copy(dest, v.s)
- }
- // Equal returns whether the bytes in b are the same as the bytes in
- // b2.
- func (v ByteView) Equal(b2 ByteView) bool {
- if b2.b == nil {
- return v.EqualString(b2.s)
- }
- return v.EqualBytes(b2.b)
- }
- // EqualString returns whether the bytes in b are the same as the bytes
- // in s.
- func (v ByteView) EqualString(s string) bool {
- if v.b == nil {
- return v.s == s
- }
- l := v.Len()
- if len(s) != l {
- return false
- }
- for i, bi := range v.b {
- if bi != s[i] {
- return false
- }
- }
- return true
- }
- // EqualBytes returns whether the bytes in b are the same as the bytes
- // in b2.
- func (v ByteView) EqualBytes(b2 []byte) bool {
- if v.b != nil {
- return bytes.Equal(v.b, b2)
- }
- l := v.Len()
- if len(b2) != l {
- return false
- }
- for i, bi := range b2 {
- if bi != v.s[i] {
- return false
- }
- }
- return true
- }
- // Reader returns an io.ReadSeeker for the bytes in v.
- func (v ByteView) Reader() io.ReadSeeker {
- if v.b != nil {
- return bytes.NewReader(v.b)
- }
- return strings.NewReader(v.s)
- }
- // ReadAt implements io.ReaderAt on the bytes in v.
- func (v ByteView) ReadAt(p []byte, off int64) (n int, err error) {
- if off < 0 {
- return 0, errors.New("view: invalid offset")
- }
- if off >= int64(v.Len()) {
- return 0, io.EOF
- }
- n = v.SliceFrom(int(off)).Copy(p)
- if n < len(p) {
- err = io.EOF
- }
- return
- }
|