...

Source file src/github.com/golang/groupcache/byteview.go

Documentation: github.com/golang/groupcache

     1  /*
     2  Copyright 2012 Google Inc.
     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 groupcache
    18  
    19  import (
    20  	"bytes"
    21  	"errors"
    22  	"io"
    23  	"strings"
    24  )
    25  
    26  // A ByteView holds an immutable view of bytes.
    27  // Internally it wraps either a []byte or a string,
    28  // but that detail is invisible to callers.
    29  //
    30  // A ByteView is meant to be used as a value type, not
    31  // a pointer (like a time.Time).
    32  type ByteView struct {
    33  	// If b is non-nil, b is used, else s is used.
    34  	b []byte
    35  	s string
    36  }
    37  
    38  // Len returns the view's length.
    39  func (v ByteView) Len() int {
    40  	if v.b != nil {
    41  		return len(v.b)
    42  	}
    43  	return len(v.s)
    44  }
    45  
    46  // ByteSlice returns a copy of the data as a byte slice.
    47  func (v ByteView) ByteSlice() []byte {
    48  	if v.b != nil {
    49  		return cloneBytes(v.b)
    50  	}
    51  	return []byte(v.s)
    52  }
    53  
    54  // String returns the data as a string, making a copy if necessary.
    55  func (v ByteView) String() string {
    56  	if v.b != nil {
    57  		return string(v.b)
    58  	}
    59  	return v.s
    60  }
    61  
    62  // At returns the byte at index i.
    63  func (v ByteView) At(i int) byte {
    64  	if v.b != nil {
    65  		return v.b[i]
    66  	}
    67  	return v.s[i]
    68  }
    69  
    70  // Slice slices the view between the provided from and to indices.
    71  func (v ByteView) Slice(from, to int) ByteView {
    72  	if v.b != nil {
    73  		return ByteView{b: v.b[from:to]}
    74  	}
    75  	return ByteView{s: v.s[from:to]}
    76  }
    77  
    78  // SliceFrom slices the view from the provided index until the end.
    79  func (v ByteView) SliceFrom(from int) ByteView {
    80  	if v.b != nil {
    81  		return ByteView{b: v.b[from:]}
    82  	}
    83  	return ByteView{s: v.s[from:]}
    84  }
    85  
    86  // Copy copies b into dest and returns the number of bytes copied.
    87  func (v ByteView) Copy(dest []byte) int {
    88  	if v.b != nil {
    89  		return copy(dest, v.b)
    90  	}
    91  	return copy(dest, v.s)
    92  }
    93  
    94  // Equal returns whether the bytes in b are the same as the bytes in
    95  // b2.
    96  func (v ByteView) Equal(b2 ByteView) bool {
    97  	if b2.b == nil {
    98  		return v.EqualString(b2.s)
    99  	}
   100  	return v.EqualBytes(b2.b)
   101  }
   102  
   103  // EqualString returns whether the bytes in b are the same as the bytes
   104  // in s.
   105  func (v ByteView) EqualString(s string) bool {
   106  	if v.b == nil {
   107  		return v.s == s
   108  	}
   109  	l := v.Len()
   110  	if len(s) != l {
   111  		return false
   112  	}
   113  	for i, bi := range v.b {
   114  		if bi != s[i] {
   115  			return false
   116  		}
   117  	}
   118  	return true
   119  }
   120  
   121  // EqualBytes returns whether the bytes in b are the same as the bytes
   122  // in b2.
   123  func (v ByteView) EqualBytes(b2 []byte) bool {
   124  	if v.b != nil {
   125  		return bytes.Equal(v.b, b2)
   126  	}
   127  	l := v.Len()
   128  	if len(b2) != l {
   129  		return false
   130  	}
   131  	for i, bi := range b2 {
   132  		if bi != v.s[i] {
   133  			return false
   134  		}
   135  	}
   136  	return true
   137  }
   138  
   139  // Reader returns an io.ReadSeeker for the bytes in v.
   140  func (v ByteView) Reader() io.ReadSeeker {
   141  	if v.b != nil {
   142  		return bytes.NewReader(v.b)
   143  	}
   144  	return strings.NewReader(v.s)
   145  }
   146  
   147  // ReadAt implements io.ReaderAt on the bytes in v.
   148  func (v ByteView) ReadAt(p []byte, off int64) (n int, err error) {
   149  	if off < 0 {
   150  		return 0, errors.New("view: invalid offset")
   151  	}
   152  	if off >= int64(v.Len()) {
   153  		return 0, io.EOF
   154  	}
   155  	n = v.SliceFrom(int(off)).Copy(p)
   156  	if n < len(p) {
   157  		err = io.EOF
   158  	}
   159  	return
   160  }
   161  
   162  // WriteTo implements io.WriterTo on the bytes in v.
   163  func (v ByteView) WriteTo(w io.Writer) (n int64, err error) {
   164  	var m int
   165  	if v.b != nil {
   166  		m, err = w.Write(v.b)
   167  	} else {
   168  		m, err = io.WriteString(w, v.s)
   169  	}
   170  	if err == nil && m < v.Len() {
   171  		err = io.ErrShortWrite
   172  	}
   173  	n = int64(m)
   174  	return
   175  }
   176  

View as plain text