github.com/gogf/gf@v1.16.9/container/gtype/bytes.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 gtype 8 9 import ( 10 "bytes" 11 "encoding/base64" 12 "sync/atomic" 13 14 "github.com/gogf/gf/util/gconv" 15 ) 16 17 // Bytes is a struct for concurrent-safe operation for type []byte. 18 type Bytes struct { 19 value atomic.Value 20 } 21 22 // NewBytes creates and returns a concurrent-safe object for []byte type, 23 // with given initial value <value>. 24 func NewBytes(value ...[]byte) *Bytes { 25 t := &Bytes{} 26 if len(value) > 0 { 27 t.value.Store(value[0]) 28 } 29 return t 30 } 31 32 // Clone clones and returns a new concurrent-safe object for []byte type. 33 func (v *Bytes) Clone() *Bytes { 34 return NewBytes(v.Val()) 35 } 36 37 // Set atomically stores <value> into t.value and returns the previous value of t.value. 38 // Note: The parameter <value> cannot be nil. 39 func (v *Bytes) Set(value []byte) (old []byte) { 40 old = v.Val() 41 v.value.Store(value) 42 return 43 } 44 45 // Val atomically loads and returns t.value. 46 func (v *Bytes) Val() []byte { 47 if s := v.value.Load(); s != nil { 48 return s.([]byte) 49 } 50 return nil 51 } 52 53 // String implements String interface for string printing. 54 func (v *Bytes) String() string { 55 return string(v.Val()) 56 } 57 58 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 59 func (v *Bytes) MarshalJSON() ([]byte, error) { 60 val := v.Val() 61 dst := make([]byte, base64.StdEncoding.EncodedLen(len(val))) 62 base64.StdEncoding.Encode(dst, val) 63 return []byte(`"` + string(dst) + `"`), nil 64 } 65 66 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 67 func (v *Bytes) UnmarshalJSON(b []byte) error { 68 src := make([]byte, base64.StdEncoding.DecodedLen(len(b))) 69 n, err := base64.StdEncoding.Decode(src, bytes.Trim(b, `"`)) 70 if err != nil { 71 return nil 72 } 73 v.Set(src[:n]) 74 return nil 75 } 76 77 // UnmarshalValue is an interface implement which sets any type of value for <v>. 78 func (v *Bytes) UnmarshalValue(value interface{}) error { 79 v.Set(gconv.Bytes(value)) 80 return nil 81 }