gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

bytes.go (7037B)


      1 package bytes
      2 
      3 import (
      4 	"bytes"
      5 	"reflect"
      6 	"unsafe"
      7 )
      8 
      9 var (
     10 	_ Bytes = &Buffer{}
     11 	_ Bytes = bytesType{}
     12 )
     13 
     14 // Bytes defines a standard way of retrieving the content of a
     15 // byte buffer of some-kind.
     16 type Bytes interface {
     17 	// Bytes returns the byte slice content
     18 	Bytes() []byte
     19 
     20 	// String returns byte slice cast directly to string, this
     21 	// will cause an allocation but comes with the safety of
     22 	// being an immutable Go string
     23 	String() string
     24 
     25 	// StringPtr returns byte slice cast to string via the unsafe
     26 	// package. This comes with the same caveats of accessing via
     27 	// .Bytes() in that the content is liable change and is NOT
     28 	// immutable, despite being a string type
     29 	StringPtr() string
     30 }
     31 
     32 type bytesType []byte
     33 
     34 func (b bytesType) Bytes() []byte {
     35 	return b
     36 }
     37 
     38 func (b bytesType) String() string {
     39 	return string(b)
     40 }
     41 
     42 func (b bytesType) StringPtr() string {
     43 	return BytesToString(b)
     44 }
     45 
     46 // ToBytes casts the provided byte slice as the simplest possible
     47 // Bytes interface implementation
     48 func ToBytes(b []byte) Bytes {
     49 	return bytesType(b)
     50 }
     51 
     52 // Copy returns a new copy of slice b, does NOT maintain nil values
     53 func Copy(b []byte) []byte {
     54 	p := make([]byte, len(b))
     55 	copy(p, b)
     56 	return p
     57 }
     58 
     59 // BytesToString returns byte slice cast to string via the "unsafe" package
     60 func BytesToString(b []byte) string {
     61 	return *(*string)(unsafe.Pointer(&b))
     62 }
     63 
     64 // StringToBytes returns the string cast to string via the "unsafe" and "reflect" packages
     65 func StringToBytes(s string) []byte {
     66 	// thank you to https://github.com/valyala/fasthttp/blob/master/bytesconv.go
     67 	var b []byte
     68 
     69 	// Get byte + string headers
     70 	bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
     71 	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
     72 
     73 	// Manually set bytes to string
     74 	bh.Data = sh.Data
     75 	bh.Len = sh.Len
     76 	bh.Cap = sh.Len
     77 
     78 	return b
     79 }
     80 
     81 // // InsertByte inserts the supplied byte into the slice at provided position
     82 // func InsertByte(b []byte, at int, c byte) []byte {
     83 // 	return append(append(b[:at], c), b[at:]...)
     84 // }
     85 
     86 // // Insert inserts the supplied byte slice into the slice at provided position
     87 // func Insert(b []byte, at int, s []byte) []byte {
     88 // 	return append(append(b[:at], s...), b[at:]...)
     89 // }
     90 
     91 // ToUpper offers a faster ToUpper implementation using a lookup table
     92 func ToUpper(b []byte) {
     93 	for i := 0; i < len(b); i++ {
     94 		c := &b[i]
     95 		*c = toUpperTable[*c]
     96 	}
     97 }
     98 
     99 // ToLower offers a faster ToLower implementation using a lookup table
    100 func ToLower(b []byte) {
    101 	for i := 0; i < len(b); i++ {
    102 		c := &b[i]
    103 		*c = toLowerTable[*c]
    104 	}
    105 }
    106 
    107 // HasBytePrefix returns whether b has the provided byte prefix
    108 func HasBytePrefix(b []byte, c byte) bool {
    109 	return (len(b) > 0) && (b[0] == c)
    110 }
    111 
    112 // HasByteSuffix returns whether b has the provided byte suffix
    113 func HasByteSuffix(b []byte, c byte) bool {
    114 	return (len(b) > 0) && (b[len(b)-1] == c)
    115 }
    116 
    117 // HasBytePrefix returns b without the provided leading byte
    118 func TrimBytePrefix(b []byte, c byte) []byte {
    119 	if HasBytePrefix(b, c) {
    120 		return b[1:]
    121 	}
    122 	return b
    123 }
    124 
    125 // TrimByteSuffix returns b without the provided trailing byte
    126 func TrimByteSuffix(b []byte, c byte) []byte {
    127 	if HasByteSuffix(b, c) {
    128 		return b[:len(b)-1]
    129 	}
    130 	return b
    131 }
    132 
    133 // Compare is a direct call-through to standard library bytes.Compare()
    134 func Compare(b, s []byte) int {
    135 	return bytes.Compare(b, s)
    136 }
    137 
    138 // Contains is a direct call-through to standard library bytes.Contains()
    139 func Contains(b, s []byte) bool {
    140 	return bytes.Contains(b, s)
    141 }
    142 
    143 // TrimPrefix is a direct call-through to standard library bytes.TrimPrefix()
    144 func TrimPrefix(b, s []byte) []byte {
    145 	return bytes.TrimPrefix(b, s)
    146 }
    147 
    148 // TrimSuffix is a direct call-through to standard library bytes.TrimSuffix()
    149 func TrimSuffix(b, s []byte) []byte {
    150 	return bytes.TrimSuffix(b, s)
    151 }
    152 
    153 // Equal is a direct call-through to standard library bytes.Equal()
    154 func Equal(b, s []byte) bool {
    155 	return bytes.Equal(b, s)
    156 }
    157 
    158 // EqualFold is a direct call-through to standard library bytes.EqualFold()
    159 func EqualFold(b, s []byte) bool {
    160 	return bytes.EqualFold(b, s)
    161 }
    162 
    163 // Fields is a direct call-through to standard library bytes.Fields()
    164 func Fields(b []byte) [][]byte {
    165 	return bytes.Fields(b)
    166 }
    167 
    168 // FieldsFunc is a direct call-through to standard library bytes.FieldsFunc()
    169 func FieldsFunc(b []byte, fn func(rune) bool) [][]byte {
    170 	return bytes.FieldsFunc(b, fn)
    171 }
    172 
    173 // HasPrefix is a direct call-through to standard library bytes.HasPrefix()
    174 func HasPrefix(b, s []byte) bool {
    175 	return bytes.HasPrefix(b, s)
    176 }
    177 
    178 // HasSuffix is a direct call-through to standard library bytes.HasSuffix()
    179 func HasSuffix(b, s []byte) bool {
    180 	return bytes.HasSuffix(b, s)
    181 }
    182 
    183 // Index is a direct call-through to standard library bytes.Index()
    184 func Index(b, s []byte) int {
    185 	return bytes.Index(b, s)
    186 }
    187 
    188 // IndexByte is a direct call-through to standard library bytes.IndexByte()
    189 func IndexByte(b []byte, c byte) int {
    190 	return bytes.IndexByte(b, c)
    191 }
    192 
    193 // IndexAny is a direct call-through to standard library bytes.IndexAny()
    194 func IndexAny(b []byte, s string) int {
    195 	return bytes.IndexAny(b, s)
    196 }
    197 
    198 // IndexRune is a direct call-through to standard library bytes.IndexRune()
    199 func IndexRune(b []byte, r rune) int {
    200 	return bytes.IndexRune(b, r)
    201 }
    202 
    203 // IndexFunc is a direct call-through to standard library bytes.IndexFunc()
    204 func IndexFunc(b []byte, fn func(rune) bool) int {
    205 	return bytes.IndexFunc(b, fn)
    206 }
    207 
    208 // LastIndex is a direct call-through to standard library bytes.LastIndex()
    209 func LastIndex(b, s []byte) int {
    210 	return bytes.LastIndex(b, s)
    211 }
    212 
    213 // LastIndexByte is a direct call-through to standard library bytes.LastIndexByte()
    214 func LastIndexByte(b []byte, c byte) int {
    215 	return bytes.LastIndexByte(b, c)
    216 }
    217 
    218 // LastIndexAny is a direct call-through to standard library bytes.LastIndexAny()
    219 func LastIndexAny(b []byte, s string) int {
    220 	return bytes.LastIndexAny(b, s)
    221 }
    222 
    223 // LastIndexFunc is a direct call-through to standard library bytes.LastIndexFunc()
    224 func LastIndexFunc(b []byte, fn func(rune) bool) int {
    225 	return bytes.LastIndexFunc(b, fn)
    226 }
    227 
    228 // Replace is a direct call-through to standard library bytes.Replace()
    229 func Replace(b, s, r []byte, c int) []byte {
    230 	return bytes.Replace(b, s, r, c)
    231 }
    232 
    233 // ReplaceAll is a direct call-through to standard library bytes.ReplaceAll()
    234 func ReplaceAll(b, s, r []byte) []byte {
    235 	return bytes.ReplaceAll(b, s, r)
    236 }
    237 
    238 // Split is a direct call-through to standard library bytes.Split()
    239 func Split(b, s []byte) [][]byte {
    240 	return bytes.Split(b, s)
    241 }
    242 
    243 // SplitAfter is a direct call-through to standard library bytes.SplitAfter()
    244 func SplitAfter(b, s []byte) [][]byte {
    245 	return bytes.SplitAfter(b, s)
    246 }
    247 
    248 // SplitN is a direct call-through to standard library bytes.SplitN()
    249 func SplitN(b, s []byte, c int) [][]byte {
    250 	return bytes.SplitN(b, s, c)
    251 }
    252 
    253 // SplitAfterN is a direct call-through to standard library bytes.SplitAfterN()
    254 func SplitAfterN(b, s []byte, c int) [][]byte {
    255 	return bytes.SplitAfterN(b, s, c)
    256 }
    257 
    258 // NewReader is a direct call-through to standard library bytes.NewReader()
    259 func NewReader(b []byte) *bytes.Reader {
    260 	return bytes.NewReader(b)
    261 }