package gob
import (
)
var (
errBadUint = errors.New("gob: encoded unsigned integer out of range")
errBadType = errors.New("gob: unknown type id or corrupted data")
errRange = errors.New("gob: bad data: field numbers out of bounds")
)
type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool
type decoderState struct {
dec *Decoder
b *decBuffer
fieldnum int
next *decoderState
}
type decBuffer struct {
data []byte
offset int
}
func ( *decBuffer) ( []byte) (int, error) {
:= copy(, .data[.offset:])
if == 0 && len() != 0 {
return 0, io.EOF
}
.offset +=
return , nil
}
func ( *decBuffer) ( int) {
if > .Len() {
panic("drop")
}
.offset +=
}
func ( *decBuffer) ( int) {
.Reset()
if cap(.data) < {
.data = make([]byte, )
} else {
.data = .data[0:]
}
}
func ( *decBuffer) () (byte, error) {
if .offset >= len(.data) {
return 0, io.EOF
}
:= .data[.offset]
.offset++
return , nil
}
func ( *decBuffer) () int {
return len(.data) - .offset
}
func ( *decBuffer) () []byte {
return .data[.offset:]
}
func ( *decBuffer) () {
.data = .data[0:0]
.offset = 0
}
func ( *Decoder) ( *decBuffer) *decoderState {
:= .freeList
if == nil {
= new(decoderState)
.dec =
} else {
.freeList = .next
}
.b =
return
}
func ( *Decoder) ( *decoderState) {
.next = .freeList
.freeList =
}
func ( string) error {
return errors.New(`value for "` + + `" out of range`)
}
func ( io.Reader, []byte) ( uint64, int, error) {
= 1
, := io.ReadFull(, [0:])
if == 0 {
return
}
:= [0]
if <= 0x7f {
return uint64(), , nil
}
= -int(int8())
if > uint64Size {
= errBadUint
return
}
, = io.ReadFull(, [0:])
if != nil {
if == io.EOF {
= io.ErrUnexpectedEOF
}
return
}
for , := range [0:] {
= <<8 | uint64()
}
++
return
}
func ( *decoderState) () ( uint64) {
, := .b.ReadByte()
if != nil {
error_()
}
if <= 0x7f {
return uint64()
}
:= -int(int8())
if > uint64Size {
error_(errBadUint)
}
:= .b.Bytes()
if len() < {
errorf("invalid uint data length %d: exceeds input size %d", , len())
}
for , := range [0:] {
= <<8 | uint64()
}
.b.Drop()
return
}
func ( *decoderState) () int64 {
:= .decodeUint()
if &1 != 0 {
return ^int64( >> 1)
}
return int64( >> 1)
}
func ( *decoderState) () (int, bool) {
:= int(.decodeUint())
if < 0 || .b.Len() < || tooBig <= {
return 0, false
}
return , true
}
type decOp func(i *decInstr, state *decoderState, v reflect.Value)
type decInstr struct {
op decOp
field int
index []int
ovfl error
}
func ( *decInstr, *decoderState, reflect.Value) {
.decodeUint()
}
func ( *decInstr, *decoderState, reflect.Value) {
.decodeUint()
.decodeUint()
}
func ( reflect.Value) reflect.Value {
for .Kind() == reflect.Ptr {
if .IsNil() {
.Set(reflect.New(.Type().Elem()))
}
= .Elem()
}
return
}
func ( *decInstr, *decoderState, reflect.Value) {
.SetBool(.decodeUint() != 0)
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeInt()
if < math.MinInt8 || math.MaxInt8 < {
error_(.ovfl)
}
.SetInt()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeUint()
if math.MaxUint8 < {
error_(.ovfl)
}
.SetUint()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeInt()
if < math.MinInt16 || math.MaxInt16 < {
error_(.ovfl)
}
.SetInt()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeUint()
if math.MaxUint16 < {
error_(.ovfl)
}
.SetUint()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeInt()
if < math.MinInt32 || math.MaxInt32 < {
error_(.ovfl)
}
.SetInt()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeUint()
if math.MaxUint32 < {
error_(.ovfl)
}
.SetUint()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeInt()
.SetInt()
}
func ( *decInstr, *decoderState, reflect.Value) {
:= .decodeUint()
.SetUint()
}
func ( uint64) float64 {
:= bits.ReverseBytes64()
return math.Float64frombits()
}
func ( uint64, error) float64 {
:= float64FromBits()
:=
if < 0 {
= -
}
if math.MaxFloat32 < && <= math.MaxFloat64 {
error_()
}
return
}
func ( *decInstr, *decoderState, reflect.Value) {
.SetFloat(float32FromBits(.decodeUint(), .ovfl))
}
func ( *decInstr, *decoderState, reflect.Value) {
.SetFloat(float64FromBits(.decodeUint()))
}
func ( *decInstr, *decoderState, reflect.Value) {
:= float32FromBits(.decodeUint(), .ovfl)
:= float32FromBits(.decodeUint(), .ovfl)
.SetComplex(complex(, ))
}
func ( *decInstr, *decoderState, reflect.Value) {
:= float64FromBits(.decodeUint())
:= float64FromBits(.decodeUint())
.SetComplex(complex(, ))
}
func ( *decInstr, *decoderState, reflect.Value) {
, := .getLength()
if ! {
errorf("bad %s slice length: %d", .Type(), )
}
if .Cap() < {
.Set(reflect.MakeSlice(.Type(), , ))
} else {
.Set(.Slice(0, ))
}
if , := .b.Read(.Bytes()); != nil {
errorf("error decoding []byte: %s", )
}
}
func ( *decInstr, *decoderState, reflect.Value) {
, := .getLength()
if ! {
errorf("bad %s slice length: %d", .Type(), )
}
:= .b.Bytes()
if len() < {
errorf("invalid string length %d: exceeds input size %d", , len())
}
:= string([:])
.b.Drop()
.SetString()
}
func ( *decInstr, *decoderState, reflect.Value) {
, := .getLength()
if ! {
errorf("slice length too large")
}
:= .b.Len()
if < {
errorf("invalid slice length %d: exceeds input size %d", , )
}
.b.Drop()
}
type decEngine struct {
instr []decInstr
numInstr int
}
func ( *Decoder) ( *decEngine, reflect.Value) {
:= .newDecoderState(&.buf)
defer .freeDecoderState()
.fieldnum = singletonField
if .decodeUint() != 0 {
errorf("decode: corrupted data: non-zero delta for singleton")
}
:= &.instr[singletonField]
.op(, , )
}
func ( *Decoder) ( *decEngine, reflect.Value) {
:= .newDecoderState(&.buf)
defer .freeDecoderState()
.fieldnum = -1
for .b.Len() > 0 {
:= int(.decodeUint())
if < 0 {
errorf("decode: corrupted data: negative delta")
}
if == 0 {
break
}
:= .fieldnum +
if >= len(.instr) {
error_(errRange)
break
}
:= &.instr[]
var reflect.Value
if .index != nil {
= .FieldByIndex(.index)
if .Kind() == reflect.Ptr {
= decAlloc()
}
}
.op(, , )
.fieldnum =
}
}
var noValue reflect.Value
func ( *Decoder) ( *decEngine) {
:= .newDecoderState(&.buf)
defer .freeDecoderState()
.fieldnum = -1
for .b.Len() > 0 {
:= int(.decodeUint())
if < 0 {
errorf("ignore decode: corrupted data: negative delta")
}
if == 0 {
break
}
:= .fieldnum +
if >= len(.instr) {
error_(errRange)
}
:= &.instr[]
.op(, , noValue)
.fieldnum =
}
}
func ( *Decoder) ( *decEngine) {
:= .newDecoderState(&.buf)
defer .freeDecoderState()
.fieldnum = singletonField
:= int(.decodeUint())
if != 0 {
errorf("decode: corrupted data: non-zero delta for singleton")
}
:= &.instr[singletonField]
.op(, , noValue)
}
func ( *Decoder) ( *decoderState, reflect.Value, decOp, int, error, decHelper) {
if != nil && (, , , ) {
return
}
:= &decInstr{, 0, nil, }
:= .Type().Elem().Kind() == reflect.Ptr
for := 0; < ; ++ {
if .b.Len() == 0 {
errorf("decoding array or slice: length exceeds input size (%d elements)", )
}
:= .Index()
if {
= decAlloc()
}
(, , )
}
}
func ( *Decoder) ( *decoderState, reflect.Value, decOp, int, error, decHelper) {
if := .decodeUint(); != uint64() {
errorf("length mismatch in decodeArray")
}
.decodeArrayHelper(, , , , , )
}
func ( *decoderState, decOp, bool, reflect.Value, *decInstr) reflect.Value {
:=
if {
= decAlloc()
}
(, , )
return
}
func ( *Decoder) ( reflect.Type, *decoderState, reflect.Value, , decOp, error) {
:= int(.decodeUint())
if .IsNil() {
.Set(reflect.MakeMapWithSize(, ))
}
:= .Key().Kind() == reflect.Ptr
:= .Elem().Kind() == reflect.Ptr
:= &decInstr{, 0, nil, }
:= &decInstr{, 0, nil, }
:= reflect.New(.Key())
:= reflect.Zero(.Key())
:= reflect.New(.Elem())
:= reflect.Zero(.Elem())
for := 0; < ; ++ {
:= decodeIntoValue(, , , .Elem(), )
:= decodeIntoValue(, , , .Elem(), )
.SetMapIndex(, )
.Elem().Set()
.Elem().Set()
}
}
func ( *Decoder) ( *decoderState, decOp, int) {
:= &decInstr{, 0, nil, errors.New("no error")}
for := 0; < ; ++ {
if .b.Len() == 0 {
errorf("decoding array or slice: length exceeds input size (%d elements)", )
}
(, , noValue)
}
}
func ( *Decoder) ( *decoderState, decOp, int) {
if := .decodeUint(); != uint64() {
errorf("length mismatch in ignoreArray")
}
.ignoreArrayHelper(, , )
}
func ( *Decoder) ( *decoderState, , decOp) {
:= int(.decodeUint())
:= &decInstr{, 0, nil, errors.New("no error")}
:= &decInstr{, 0, nil, errors.New("no error")}
for := 0; < ; ++ {
(, , noValue)
(, , noValue)
}
}
func ( *Decoder) ( *decoderState, reflect.Value, decOp, error, decHelper) {
:= .decodeUint()
:= .Type()
:= uint64(.Elem().Size())
:= *
:= int()
if < 0 || uint64() != || > tooBig || ( > 0 && / != ) {
errorf("%s slice too big: %d elements of %d bytes", .Elem(), , )
}
if .Cap() < {
.Set(reflect.MakeSlice(, , ))
} else {
.Set(.Slice(0, ))
}
.decodeArrayHelper(, , , , , )
}
func ( *Decoder) ( *decoderState, decOp) {
.ignoreArrayHelper(, , int(.decodeUint()))
}
func ( *Decoder) ( reflect.Type, *decoderState, reflect.Value) {
:= .decodeUint()
if > 1<<31 {
errorf("invalid type name length %d", )
}
if > uint64(.b.Len()) {
errorf("invalid type name length %d: exceeds input size", )
}
:= int()
:= .b.Bytes()[:]
.b.Drop()
if len() == 0 {
.Set(reflect.Zero(.Type()))
return
}
if len() > 1024 {
errorf("name too long (%d bytes): %.20q...", len(), )
}
, := nameToConcreteType.Load(string())
if ! {
errorf("name not registered for interface: %q", )
}
:= .(reflect.Type)
:= .decodeTypeSequence(true)
if < 0 {
error_(.err)
}
.decodeUint()
:= allocValue()
.decodeValue(, )
if .err != nil {
error_(.err)
}
if !.AssignableTo() {
errorf("%s is not assignable to type %s", , )
}
.Set()
}
func ( *Decoder) ( *decoderState) {
, := .getLength()
if ! {
errorf("bad interface encoding: name too large for buffer")
}
:= .b.Len()
if < {
errorf("invalid interface value length %d: exceeds input size %d", , )
}
.b.Drop()
:= .decodeTypeSequence(true)
if < 0 {
error_(.err)
}
, = .getLength()
if ! {
errorf("bad interface encoding: data length too large for buffer")
}
.b.Drop()
}
func ( *Decoder) ( *userTypeInfo, *decoderState, reflect.Value) {
, := .getLength()
if ! {
errorf("GobDecoder: length too large for buffer")
}
:= .b.Bytes()
if len() < {
errorf("GobDecoder: invalid data length %d: exceeds input size %d", , len())
}
= [:]
.b.Drop()
var error
switch .externalDec {
case xGob:
= .Interface().(GobDecoder).GobDecode()
case xBinary:
= .Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary()
case xText:
= .Interface().(encoding.TextUnmarshaler).UnmarshalText()
}
if != nil {
error_()
}
}
func ( *Decoder) ( *decoderState) {
, := .getLength()
if ! {
errorf("GobDecoder: length too large for buffer")
}
:= .b.Len()
if < {
errorf("GobDecoder: invalid data length %d: exceeds input size %d", , )
}
.b.Drop()
}
var decOpTable = [...]decOp{
reflect.Bool: decBool,
reflect.Int8: decInt8,
reflect.Int16: decInt16,
reflect.Int32: decInt32,
reflect.Int64: decInt64,
reflect.Uint8: decUint8,
reflect.Uint16: decUint16,
reflect.Uint32: decUint32,
reflect.Uint64: decUint64,
reflect.Float32: decFloat32,
reflect.Float64: decFloat64,
reflect.Complex64: decComplex64,
reflect.Complex128: decComplex128,
reflect.String: decString,
}
var decIgnoreOpMap = map[typeId]decOp{
tBool: ignoreUint,
tInt: ignoreUint,
tUint: ignoreUint,
tFloat: ignoreUint,
tBytes: ignoreUint8Array,
tString: ignoreUint8Array,
tComplex: ignoreTwoUints,
}
func ( *Decoder) ( typeId, reflect.Type, string, map[reflect.Type]*decOp) *decOp {
:= userType()
if .externalDec != 0 {
return .gobDecodeOpFor()
}
if := []; != nil {
return
}
:= .base
var decOp
:= .Kind()
if int() < len(decOpTable) {
= decOpTable[]
}
if == nil {
[] = &
switch := ; .Kind() {
case reflect.Array:
= "element of " +
:= .wireType[].ArrayT.Elem
:= .(, .Elem(), , )
:= overflow()
:= decArrayHelper[.Elem().Kind()]
= func( *decInstr, *decoderState, reflect.Value) {
.dec.decodeArray(, , *, .Len(), , )
}
case reflect.Map:
:= .wireType[].MapT.Key
:= .wireType[].MapT.Elem
:= .(, .Key(), "key of "+, )
:= .(, .Elem(), "element of "+, )
:= overflow()
= func( *decInstr, *decoderState, reflect.Value) {
.dec.decodeMap(, , , *, *, )
}
case reflect.Slice:
= "element of " +
if .Elem().Kind() == reflect.Uint8 {
= decUint8Slice
break
}
var typeId
if , := builtinIdToType[]; {
= .(*sliceType).Elem
} else {
= .wireType[].SliceT.Elem
}
:= .(, .Elem(), , )
:= overflow()
:= decSliceHelper[.Elem().Kind()]
= func( *decInstr, *decoderState, reflect.Value) {
.dec.decodeSlice(, , *, , )
}
case reflect.Struct:
:= userType()
, := .getDecEnginePtr(, )
if != nil {
error_()
}
= func( *decInstr, *decoderState, reflect.Value) {
.decodeStruct(*, )
}
case reflect.Interface:
= func( *decInstr, *decoderState, reflect.Value) {
.dec.decodeInterface(, , )
}
}
}
if == nil {
errorf("decode can't handle type %s", )
}
return &
}
func ( *Decoder) ( typeId, map[typeId]*decOp) *decOp {
if := []; != nil {
return
}
, := decIgnoreOpMap[]
if ! {
[] = &
if == tInterface {
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreInterface()
}
return &
}
:= .wireType[]
switch {
case == nil:
errorf("bad data: undefined type %s", .string())
case .ArrayT != nil:
:= .ArrayT.Elem
:= .(, )
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreArray(, *, .ArrayT.Len)
}
case .MapT != nil:
:= .wireType[].MapT.Key
:= .wireType[].MapT.Elem
:= .(, )
:= .(, )
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreMap(, *, *)
}
case .SliceT != nil:
:= .SliceT.Elem
:= .(, )
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreSlice(, *)
}
case .StructT != nil:
, := .getIgnoreEnginePtr()
if != nil {
error_()
}
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreStruct(*)
}
case .GobEncoderT != nil, .BinaryMarshalerT != nil, .TextMarshalerT != nil:
= func( *decInstr, *decoderState, reflect.Value) {
.dec.ignoreGobDecoder()
}
}
}
if == nil {
errorf("bad data: ignore can't handle type %s", .string())
}
return &
}
func ( *Decoder) ( *userTypeInfo) *decOp {
:= .user
if .decIndir == -1 {
= reflect.PtrTo()
} else if .decIndir > 0 {
for := int8(0); < .decIndir; ++ {
= .Elem()
}
}
var decOp
= func( *decInstr, *decoderState, reflect.Value) {
if .Kind() != reflect.Ptr && .Kind() == reflect.Ptr {
= .Addr()
}
.dec.decodeGobDecoder(, , )
}
return &
}
func ( *Decoder) ( reflect.Type, typeId, map[reflect.Type]typeId) bool {
if , := []; {
return ==
}
[] =
:= userType()
, := .wireType[]
if (.externalDec == xGob) != ( && .GobEncoderT != nil) ||
(.externalDec == xBinary) != ( && .BinaryMarshalerT != nil) ||
(.externalDec == xText) != ( && .TextMarshalerT != nil) {
return false
}
if .externalDec != 0 {
return true
}
switch := .base; .Kind() {
default:
return false
case reflect.Bool:
return == tBool
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return == tInt
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return == tUint
case reflect.Float32, reflect.Float64:
return == tFloat
case reflect.Complex64, reflect.Complex128:
return == tComplex
case reflect.String:
return == tString
case reflect.Interface:
return == tInterface
case reflect.Array:
if ! || .ArrayT == nil {
return false
}
:= .ArrayT
return .Len() == .Len && .(.Elem(), .Elem, )
case reflect.Map:
if ! || .MapT == nil {
return false
}
:= .MapT
return .(.Key(), .Key, ) && .(.Elem(), .Elem, )
case reflect.Slice:
if .Elem().Kind() == reflect.Uint8 {
return == tBytes
}
var *sliceType
if , := builtinIdToType[]; {
, _ = .(*sliceType)
} else if != nil {
= .SliceT
}
:= userType(.Elem()).base
return != nil && .(, .Elem, )
case reflect.Struct:
return true
}
}
func ( *Decoder) ( typeId) string {
typeLock.Lock()
defer typeLock.Unlock()
if := idToType[]; != nil {
return .string()
}
return .wireType[].string()
}
func ( *Decoder) ( typeId, *userTypeInfo) ( *decEngine, error) {
:= .user
= new(decEngine)
.instr = make([]decInstr, 1)
:= .String()
if !.compatibleType(, , make(map[reflect.Type]typeId)) {
:= .typeString()
if .base.Kind() == reflect.Interface && != tInterface {
return nil, errors.New("gob: local interface type " + + " can only be decoded from remote interface type; received concrete type " + )
}
return nil, errors.New("gob: decoding into local type " + + ", received remote type " + )
}
:= .decOpFor(, , , make(map[reflect.Type]*decOp))
:= errors.New(`value for "` + + `" out of range`)
.instr[singletonField] = decInstr{*, singletonField, nil, }
.numInstr = 1
return
}
func ( *Decoder) ( typeId) *decEngine {
:= new(decEngine)
.instr = make([]decInstr, 1)
:= .decIgnoreOpFor(, make(map[typeId]*decOp))
:= overflow(.typeString())
.instr[0] = decInstr{*, 0, nil, }
.numInstr = 1
return
}
func ( *Decoder) ( typeId, *userTypeInfo) ( *decEngine, error) {
defer catchError(&)
:= .base
:=
if .Kind() != reflect.Struct || .externalDec != 0 {
return .compileSingle(, )
}
var *structType
if , := builtinIdToType[]; {
, _ = .(*structType)
} else {
:= .wireType[]
if == nil {
error_(errBadType)
}
= .StructT
}
if == nil {
errorf("type mismatch in decoder: want struct type %s; got non-struct", )
}
= new(decEngine)
.instr = make([]decInstr, len(.Field))
:= make(map[reflect.Type]*decOp)
for := 0; < len(.Field); ++ {
:= .Field[]
if .Name == "" {
errorf("empty name for remote field of type %s", .Name)
}
:= overflow(.Name)
, := .FieldByName(.Name)
if ! || !isExported(.Name) {
:= .decIgnoreOpFor(.Id, make(map[typeId]*decOp))
.instr[] = decInstr{*, , nil, }
continue
}
if !.compatibleType(.Type, .Id, make(map[reflect.Type]typeId)) {
errorf("wrong type (%s) for received field %s.%s", .Type, .Name, .Name)
}
:= .decOpFor(.Id, .Type, .Name, )
.instr[] = decInstr{*, , .Index, }
.numInstr++
}
return
}
func ( *Decoder) ( typeId, *userTypeInfo) ( **decEngine, error) {
:= .user
, := .decoderCache[]
if ! {
= make(map[typeId]**decEngine)
.decoderCache[] =
}
if , = []; ! {
= new(*decEngine)
[] =
*, = .compileDec(, )
if != nil {
delete(, )
}
}
return
}
type emptyStruct struct{}
var emptyStructType = reflect.TypeOf(emptyStruct{})
func ( *Decoder) ( typeId) ( **decEngine, error) {
var bool
if , = .ignorerCache[]; ! {
= new(*decEngine)
.ignorerCache[] =
:= .wireType[]
if != nil && .StructT != nil {
*, = .compileDec(, userType(emptyStructType))
} else {
* = .compileIgnoreSingle()
}
if != nil {
delete(.ignorerCache, )
}
}
return
}
func ( *Decoder) ( typeId, reflect.Value) {
defer catchError(&.err)
if !.IsValid() {
.decodeIgnoredValue()
return
}
:= userType(.Type())
:= .base
var **decEngine
, .err = .getDecEnginePtr(, )
if .err != nil {
return
}
= decAlloc()
:= *
if := ; .Kind() == reflect.Struct && .externalDec == 0 {
:= .wireType[]
if .numInstr == 0 && .NumField() > 0 &&
!= nil && len(.StructT.Field) > 0 {
:= .Name()
errorf("type mismatch: no fields matched compiling decoder for %s", )
}
.decodeStruct(, )
} else {
.decodeSingle(, )
}
}
func ( *Decoder) ( typeId) {
var **decEngine
, .err = .getIgnoreEnginePtr()
if .err != nil {
return
}
:= .wireType[]
if != nil && .StructT != nil {
.ignoreStruct(*)
} else {
.ignoreSingle(*)
}
}
func () {
var , decOp
switch reflect.TypeOf(int(0)).Bits() {
case 32:
= decInt32
= decUint32
case 64:
= decInt64
= decUint64
default:
panic("gob: unknown size of int/uint")
}
decOpTable[reflect.Int] =
decOpTable[reflect.Uint] =
switch reflect.TypeOf(uintptr(0)).Bits() {
case 32:
= decUint32
case 64:
= decUint64
default:
panic("gob: unknown size of uintptr")
}
decOpTable[reflect.Uintptr] =
}
func ( reflect.Type) reflect.Value {
return reflect.New().Elem()
}