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  }