// Code generated by go run decgen.go -output dec_helpers.go; DO NOT EDIT.

// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]bool](v)
	if !ok {
		// It is kind bool but not type bool. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		slice[i] = state.decodeUint() != 0
	}
	return true
}

func decComplex64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]complex64](v)
	if !ok {
		// It is kind complex64 but not type complex64. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]complex128](v)
	if !ok {
		// It is kind complex128 but not type complex128. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]float32](v)
	if !ok {
		// It is kind float32 but not type float32. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]float64](v)
	if !ok {
		// It is kind float64 but not type float64. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		slice[i] = float64FromBits(state.decodeUint())
	}
	return true
}

func decIntArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]int](v)
	if !ok {
		// It is kind int but not type int. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		x := state.decodeInt()
		// MinInt and MaxInt
		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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]int16](v)
	if !ok {
		// It is kind int16 but not type int16. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]int32](v)
	if !ok {
		// It is kind int32 but not type int32. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]int64](v)
	if !ok {
		// It is kind int64 but not type int64. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		slice[i] = state.decodeInt()
	}
	return true
}

func decInt8Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]int8](v)
	if !ok {
		// It is kind int8 but not type int8. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]string](v)
	if !ok {
		// It is kind string but not type string. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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)
		}
		// Read the data.
		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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]uint](v)
	if !ok {
		// It is kind uint but not type uint. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		x := state.decodeUint()
		/*TODO if math.MaxUint32 < x {
			error_(ovfl)
		}*/
		slice[i] = uint(x)
	}
	return true
}

func decUint16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]uint16](v)
	if !ok {
		// It is kind uint16 but not type uint16. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]uint32](v)
	if !ok {
		// It is kind uint32 but not type uint32. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			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 {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]uint64](v)
	if !ok {
		// It is kind uint64 but not type uint64. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		slice[i] = state.decodeUint()
	}
	return true
}

func decUintptrArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
	// Can only slice if it is addressable.
	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 := reflect.TypeAssert[[]uintptr](v)
	if !ok {
		// It is kind uintptr but not type uintptr. TODO: We can handle this unsafely.
		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) {
			// This is a slice that we only partially allocated.
			growSlice(v, &slice, length)
		}
		x := state.decodeUint()
		if uint64(^uintptr(0)) < x {
			error_(ovfl)
		}
		slice[i] = uintptr(x)
	}
	return true
}

// growSlice is called for a slice that we only partially allocated,
// to grow it up to length.
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
}
