package gob
import (
"math"
"reflect"
)
var decArrayHelper = map [reflect .Kind ]decHelper {
reflect .Bool : decBoolArray ,
reflect .Complex64 : decComplex64Array ,
reflect .Complex128 : decComplex128Array ,
reflect .Float32 : decFloat32Array ,
reflect .Float64 : decFloat64Array ,
reflect .Int : decIntArray ,
reflect .Int16 : decInt16Array ,
reflect .Int32 : decInt32Array ,
reflect .Int64 : decInt64Array ,
reflect .Int8 : decInt8Array ,
reflect .String : decStringArray ,
reflect .Uint : decUintArray ,
reflect .Uint16 : decUint16Array ,
reflect .Uint32 : decUint32Array ,
reflect .Uint64 : decUint64Array ,
reflect .Uintptr : decUintptrArray ,
}
var decSliceHelper = map [reflect .Kind ]decHelper {
reflect .Bool : decBoolSlice ,
reflect .Complex64 : decComplex64Slice ,
reflect .Complex128 : decComplex128Slice ,
reflect .Float32 : decFloat32Slice ,
reflect .Float64 : decFloat64Slice ,
reflect .Int : decIntSlice ,
reflect .Int16 : decInt16Slice ,
reflect .Int32 : decInt32Slice ,
reflect .Int64 : decInt64Slice ,
reflect .Int8 : decInt8Slice ,
reflect .String : decStringSlice ,
reflect .Uint : decUintSlice ,
reflect .Uint16 : decUint16Slice ,
reflect .Uint32 : decUint32Slice ,
reflect .Uint64 : decUint64Slice ,
reflect .Uintptr : decUintptrSlice ,
}
func decBoolArray(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decBoolSlice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decBoolSlice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]bool )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding bool array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
slice [i ] = state .decodeUint () != 0
}
return true
}
func decComplex64Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decComplex64Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decComplex64Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]complex64 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding complex64 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
real := float32FromBits (state .decodeUint (), ovfl )
imag := float32FromBits (state .decodeUint (), ovfl )
slice [i ] = complex (float32 (real ), float32 (imag ))
}
return true
}
func decComplex128Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decComplex128Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decComplex128Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]complex128 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding complex128 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
real := float64FromBits (state .decodeUint ())
imag := float64FromBits (state .decodeUint ())
slice [i ] = complex (real , imag )
}
return true
}
func decFloat32Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decFloat32Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decFloat32Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]float32 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding float32 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
slice [i ] = float32 (float32FromBits (state .decodeUint (), ovfl ))
}
return true
}
func decFloat64Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decFloat64Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decFloat64Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]float64 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding float64 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
slice [i ] = float64FromBits (state .decodeUint ())
}
return true
}
func decIntArray(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decIntSlice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decIntSlice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]int )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding int array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeInt ()
if x < ^int64 (^uint (0 )>>1 ) || int64 (^uint (0 )>>1 ) < x {
error_ (ovfl )
}
slice [i ] = int (x )
}
return true
}
func decInt16Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decInt16Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decInt16Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]int16 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding int16 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeInt ()
if x < math .MinInt16 || math .MaxInt16 < x {
error_ (ovfl )
}
slice [i ] = int16 (x )
}
return true
}
func decInt32Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decInt32Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decInt32Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]int32 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding int32 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeInt ()
if x < math .MinInt32 || math .MaxInt32 < x {
error_ (ovfl )
}
slice [i ] = int32 (x )
}
return true
}
func decInt64Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decInt64Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decInt64Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]int64 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding int64 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
slice [i ] = state .decodeInt ()
}
return true
}
func decInt8Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decInt8Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decInt8Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]int8 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding int8 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeInt ()
if x < math .MinInt8 || math .MaxInt8 < x {
error_ (ovfl )
}
slice [i ] = int8 (x )
}
return true
}
func decStringArray(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decStringSlice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decStringSlice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]string )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding string array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
u := state .decodeUint ()
n := int (u )
if n < 0 || uint64 (n ) != u || n > state .b .Len () {
errorf ("length of string exceeds input size (%d bytes)" , u )
}
if n > state .b .Len () {
errorf ("string data too long for buffer: %d" , n )
}
data := state .b .Bytes ()
if len (data ) < n {
errorf ("invalid string length %d: exceeds input size %d" , n , len (data ))
}
slice [i ] = string (data [:n ])
state .b .Drop (n )
}
return true
}
func decUintArray(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decUintSlice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decUintSlice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]uint )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding uint array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeUint ()
slice [i ] = uint (x )
}
return true
}
func decUint16Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decUint16Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decUint16Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]uint16 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding uint16 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeUint ()
if math .MaxUint16 < x {
error_ (ovfl )
}
slice [i ] = uint16 (x )
}
return true
}
func decUint32Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decUint32Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decUint32Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]uint32 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding uint32 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeUint ()
if math .MaxUint32 < x {
error_ (ovfl )
}
slice [i ] = uint32 (x )
}
return true
}
func decUint64Array(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decUint64Slice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decUint64Slice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]uint64 )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding uint64 array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
slice [i ] = state .decodeUint ()
}
return true
}
func decUintptrArray(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
if !v .CanAddr () {
return false
}
return decUintptrSlice (state , v .Slice (0 , v .Len ()), length , ovfl )
}
func decUintptrSlice(state *decoderState , v reflect .Value , length int , ovfl error ) bool {
slice , ok := v .Interface ().([]uintptr )
if !ok {
return false
}
for i := 0 ; i < length ; i ++ {
if state .b .Len () == 0 {
errorf ("decoding uintptr array or slice: length exceeds input size (%d elements)" , length )
}
if i >= len (slice ) {
growSlice (v , &slice , length )
}
x := state .decodeUint ()
if uint64 (^uintptr (0 )) < x {
error_ (ovfl )
}
slice [i ] = uintptr (x )
}
return true
}
func growSlice[E any ](v reflect .Value , ps *[]E , length int ) {
var zero E
s := *ps
s = append (s , zero )
cp := cap (s )
if cp > length {
cp = length
}
s = s [:cp ]
v .Set (reflect .ValueOf (s ))
*ps = s
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .