Merge pull request #15072 from wojtek-t/update_to_ugorji_attempt2

Auto commit by PR queue bot
pull/6/head
k8s-merge-robot 2015-10-16 05:54:14 -07:00
commit c59d3fa755
25 changed files with 127326 additions and 2096 deletions

2
Godeps/Godeps.json generated
View File

@ -564,7 +564,7 @@
},
{
"ImportPath": "github.com/ugorji/go/codec",
"Rev": "2f4b94206aae781e63846a9bf02ad83c387d5296"
"Rev": "8a2a3a8c488c3ebd98f422a965260278267a0551"
},
{
"ImportPath": "github.com/vaughan0/go-ini",

View File

@ -41,10 +41,6 @@ package {{ $.PackageName }}
import (
{{ if not .CodecPkgFiles }}{{ .CodecPkgName }} "{{ .CodecImportPath }}"{{ end }}
{{/*
{{ if .Types }}"{{ .ImportPath }}"{{ end }}
"io"
*/}}
"os"
"reflect"
"bytes"
@ -52,14 +48,6 @@ import (
"go/format"
)
{{/* This is not used anymore. Remove it.
func write(w io.Writer, s string) {
if _, err := io.WriteString(w, s); err != nil {
panic(err)
}
}
*/}}
func CodecGenTempWrite{{ .RandString }}() {
fout, err := os.Create("{{ .OutFile }}")
if err != nil {

View File

@ -95,6 +95,14 @@ type DecodeOptions struct {
// If nil, we use []interface{}
SliceType reflect.Type
// MaxInitLen defines the initial length that we "make" a collection (slice, chan or map) with.
// If 0 or negative, we default to a sensible value based on the size of an element in the collection.
//
// For example, when decoding, a stream may say that it has MAX_UINT elements.
// We should not auto-matically provision a slice of that length, to prevent Out-Of-Memory crash.
// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
MaxInitLen int
// If ErrorIfNoField, return an error when decoding a map
// from a codec stream into a struct, and no matching struct field is found.
ErrorIfNoField bool
@ -107,13 +115,42 @@ type DecodeOptions struct {
// If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64).
SignedInteger bool
// MaxInitLen defines the initial length that we "make" a collection (slice, chan or map) with.
// If 0 or negative, we default to a sensible value based on the size of an element in the collection.
// MapValueReset controls how we decode into a map value.
//
// For example, when decoding, a stream may say that it has MAX_UINT elements.
// We should not auto-matically provision a slice of that length, to prevent Out-Of-Memory crash.
// Instead, we provision up to MaxInitLen, fill that up, and start appending after that.
MaxInitLen int
// By default, we MAY retrieve the mapping for a key, and then decode into that.
// However, especially with big maps, that retrieval may be expensive and unnecessary
// if the stream already contains all that is necessary to recreate the value.
//
// If true, we will never retrieve the previous mapping,
// but rather decode into a new value and set that in the map.
//
// If false, we will retrieve the previous mapping if necessary e.g.
// the previous mapping is a pointer, or is a struct or array with pre-set state,
// or is an interface.
MapValueReset bool
// InterfaceReset controls how we decode into an interface.
//
// By default, when we see a field that is an interface{...},
// or a map with interface{...} value, we will attempt decoding into the
// "contained" value.
//
// However, this prevents us from reading a string into an interface{}
// that formerly contained a number.
//
// If true, we will decode into a new "blank" value, and set that in the interface.
// If false, we will decode into whatever is contained in the interface.
InterfaceReset bool
// InternString controls interning of strings during decoding.
//
// Some handles, e.g. json, typically will read map keys as strings.
// If the set of keys are finite, it may help reduce allocation to
// look them up from a map (than to allocate them afresh).
//
// Note: Handles will be smart when using the intern functionality.
// So everything will not be interned.
InternString bool
}
// ------------------------------------
@ -582,25 +619,34 @@ func (f *decFnInfo) kInterface(rv reflect.Value) {
// to decode into what was there before.
// We do not replace with a generic value (as got from decodeNaked).
var rvn reflect.Value
if rv.IsNil() {
rvn := f.kInterfaceNaked()
rvn = f.kInterfaceNaked()
if rvn.IsValid() {
rv.Set(rvn)
}
} else if f.d.h.InterfaceReset {
rvn = f.kInterfaceNaked()
if rvn.IsValid() {
rv.Set(rvn)
} else {
// reset to zero value based on current type in there.
rv.Set(reflect.Zero(rv.Elem().Type()))
}
} else {
rve := rv.Elem()
rvn = rv.Elem()
// Note: interface{} is settable, but underlying type may not be.
// Consequently, we have to set the reflect.Value directly.
// if underlying type is settable (e.g. ptr or interface),
// we just decode into it.
// Else we create a settable value, decode into it, and set on the interface.
if rve.CanSet() {
f.d.decodeValue(rve, nil)
if rvn.CanSet() {
f.d.decodeValue(rvn, nil)
} else {
rve2 := reflect.New(rve.Type()).Elem()
rve2.Set(rve)
f.d.decodeValue(rve2, nil)
rv.Set(rve2)
rvn2 := reflect.New(rvn.Type()).Elem()
rvn2.Set(rvn)
f.d.decodeValue(rvn2, nil)
rv.Set(rvn2)
}
}
}
@ -887,22 +933,45 @@ func (f *decFnInfo) kMap(rv reflect.Value) {
for xtyp = vtype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() {
}
valFn = d.getDecFn(xtyp, true, true)
var mapGet bool
if !f.d.h.MapValueReset {
// if pointer, mapGet = true
// if interface, mapGet = true if !DecodeNakedAlways (else false)
// if builtin, mapGet = false
// else mapGet = true
vtypeKind := vtype.Kind()
if vtypeKind == reflect.Ptr {
mapGet = true
} else if vtypeKind == reflect.Interface {
if !f.d.h.InterfaceReset {
mapGet = true
}
} else if !isImmutableKind(vtypeKind) {
mapGet = true
}
}
var rvk, rvv reflect.Value
// for j := 0; j < containerLen; j++ {
if containerLen > 0 {
for j := 0; j < containerLen; j++ {
rvk := reflect.New(ktype).Elem()
rvk = reflect.New(ktype).Elem()
d.decodeValue(rvk, keyFn)
// special case if a byte array.
if ktypeId == intfTypId {
rvk = rvk.Elem()
if rvk.Type() == uint8SliceTyp {
rvk = reflect.ValueOf(string(rvk.Bytes()))
rvk = reflect.ValueOf(d.string(rvk.Bytes()))
}
}
rvv := rv.MapIndex(rvk)
// TODO: is !IsValid check required?
if !rvv.IsValid() {
if mapGet {
rvv = rv.MapIndex(rvk)
if !rvv.IsValid() {
rvv = reflect.New(vtype).Elem()
}
} else {
rvv = reflect.New(vtype).Elem()
}
d.decodeValue(rvv, valFn)
@ -910,18 +979,22 @@ func (f *decFnInfo) kMap(rv reflect.Value) {
}
} else {
for j := 0; !dd.CheckBreak(); j++ {
rvk := reflect.New(ktype).Elem()
rvk = reflect.New(ktype).Elem()
d.decodeValue(rvk, keyFn)
// special case if a byte array.
if ktypeId == intfTypId {
rvk = rvk.Elem()
if rvk.Type() == uint8SliceTyp {
rvk = reflect.ValueOf(string(rvk.Bytes()))
rvk = reflect.ValueOf(d.string(rvk.Bytes()))
}
}
rvv := rv.MapIndex(rvk)
if !rvv.IsValid() {
if mapGet {
rvv = rv.MapIndex(rvk)
if !rvv.IsValid() {
rvv = reflect.New(vtype).Elem()
}
} else {
rvv = reflect.New(vtype).Elem()
}
d.decodeValue(rvv, valFn)
@ -957,6 +1030,8 @@ type Decoder struct {
ri ioDecReader
f map[uintptr]*decFn
is map[string]string // used for interning strings
// _ uintptr // for alignment purposes, so next one starts from a cache line
b [scratchByteArrayLen]byte
@ -977,6 +1052,9 @@ func NewDecoder(r io.Reader, h Handle) (d *Decoder) {
d.ri.br = &d.ri.bs
}
d.r = &d.ri
if d.h.InternString {
d.is = make(map[string]string, 32)
}
_, d.js = h.(*JsonHandle)
d.d = h.newDecDriver(d)
return
@ -990,6 +1068,9 @@ func NewDecoderBytes(in []byte, h Handle) (d *Decoder) {
d.rb.b = in
d.rb.a = len(in)
d.r = &d.rb
if d.h.InternString {
d.is = make(map[string]string, 32)
}
_, d.js = h.(*JsonHandle)
d.d = h.newDecDriver(d)
// d.d = h.newDecDriver(decReaderT{true, &d.rb, &d.ri})
@ -1472,6 +1553,24 @@ func (d *Decoder) errorf(format string, params ...interface{}) {
panic(err)
}
func (d *Decoder) string(v []byte) (s string) {
if d.is != nil {
s, ok := d.is[string(v)] // no allocation here.
if !ok {
s = string(v)
d.is[s] = s
}
return s
}
return string(v) // don't return stringView, as we need a real string here.
}
func (d *Decoder) intern(s string) {
if d.is != nil {
d.is[s] = s
}
}
// --------------------------------------------------
// decSliceHelper assists when decoding into a slice, from a map or an array in the stream.

View File

@ -4,7 +4,6 @@
package codec
import (
"bytes"
"encoding"
"fmt"
"io"
@ -80,17 +79,6 @@ type encNoSeparator struct{}
func (_ encNoSeparator) EncodeEnd() {}
type encStructFieldBytesV struct {
b []byte
v reflect.Value
}
type encStructFieldBytesVslice []encStructFieldBytesV
func (p encStructFieldBytesVslice) Len() int { return len(p) }
func (p encStructFieldBytesVslice) Less(i, j int) bool { return bytes.Compare(p[i].b, p[j].b) == -1 }
func (p encStructFieldBytesVslice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type ioEncWriterWriter interface {
WriteByte(c byte) error
WriteString(s string) (n int, err error)
@ -109,8 +97,16 @@ type EncodeOptions struct {
// sequence of bytes.
//
// This only affects maps, as the iteration order for maps is random.
// In this case, the map keys will first be encoded into []byte, and then sorted,
// before writing the sorted keys and the corresponding map values to the stream.
//
// The implementation MAY use the natural sort order for the map keys if possible:
//
// - If there is a natural sort order (ie for number, bool, string or []byte keys),
// then the map keys are first sorted in natural order and then written
// with corresponding map values to the strema.
// - If there is no natural sort order, then the map keys will first be
// encoded into []byte, and then sorted,
// before writing the sorted keys and the corresponding map values to the stream.
//
Canonical bool
// AsSymbols defines what should be encoded as symbols.
@ -493,27 +489,27 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
tisfi = fti.sfi
}
newlen = 0
var kv encStructFieldKV
var kv stringRv
for _, si := range tisfi {
kv.v = si.field(rv, false)
kv.r = si.field(rv, false)
// if si.i != -1 {
// rvals[newlen] = rv.Field(int(si.i))
// } else {
// rvals[newlen] = rv.FieldByIndex(si.is)
// }
if toMap {
if si.omitEmpty && isEmptyValue(kv.v) {
if si.omitEmpty && isEmptyValue(kv.r) {
continue
}
kv.k = si.encName
kv.v = si.encName
} else {
// use the zero value.
// if a reference or struct, set to nil (so you do not output too much)
if si.omitEmpty && isEmptyValue(kv.v) {
switch kv.v.Kind() {
if si.omitEmpty && isEmptyValue(kv.r) {
switch kv.r.Kind() {
case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array,
reflect.Map, reflect.Slice:
kv.v = reflect.Value{} //encode as nil
kv.r = reflect.Value{} //encode as nil
}
}
}
@ -532,17 +528,17 @@ func (f *encFnInfo) kStruct(rv reflect.Value) {
for j := 0; j < newlen; j++ {
kv = fkvs[j]
if asSymbols {
ee.EncodeSymbol(kv.k)
ee.EncodeSymbol(kv.v)
} else {
ee.EncodeString(c_UTF8, kv.k)
ee.EncodeString(c_UTF8, kv.v)
}
e.encodeValue(kv.v, nil)
e.encodeValue(kv.r, nil)
}
} else {
ee.EncodeArrayStart(newlen)
for j := 0; j < newlen; j++ {
kv = fkvs[j]
e.encodeValue(kv.v, nil)
e.encodeValue(kv.r, nil)
}
}
ee.EncodeEnd()
@ -621,24 +617,9 @@ func (f *encFnInfo) kMap(rv reflect.Value) {
}
mks := rv.MapKeys()
// for j, lmks := 0, len(mks); j < lmks; j++ {
if e.h.Canonical {
// first encode each key to a []byte first, then sort them, then record
// println(">>>>>>>> CANONICAL <<<<<<<<")
var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
e2 := NewEncoderBytes(&mksv, e.hh)
mksbv := make([]encStructFieldBytesV, len(mks))
for i, k := range mks {
l := len(mksv)
e2.MustEncode(k)
mksbv[i].v = k
mksbv[i].b = mksv[l:]
// fmt.Printf(">>>>> %s\n", mksv[l:])
}
sort.Sort(encStructFieldBytesVslice(mksbv))
for j := range mksbv {
e.asis(mksbv[j].b)
e.encodeValue(rv.MapIndex(mksbv[j].v), valFn)
}
e.kMapCanonical(rtkeyid, rtkey, rv, mks, valFn, asSymbols)
} else {
for j := range mks {
if keyTypeIsString {
@ -653,9 +634,128 @@ func (f *encFnInfo) kMap(rv reflect.Value) {
e.encodeValue(rv.MapIndex(mks[j]), valFn)
}
}
ee.EncodeEnd()
}
func (e *Encoder) kMapCanonical(rtkeyid uintptr, rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *encFn, asSymbols bool) {
ee := e.e
// we previously did out-of-band if an extension was registered.
// This is not necessary, as the natural kind is sufficient for ordering.
if rtkeyid == uint8SliceTypId {
mksv := make([]bytesRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Bytes()
}
sort.Sort(bytesRvSlice(mksv))
for i := range mksv {
ee.EncodeStringBytes(c_RAW, mksv[i].v)
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
} else {
switch rtkey.Kind() {
case reflect.Bool:
mksv := make([]boolRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Bool()
}
sort.Sort(boolRvSlice(mksv))
for i := range mksv {
ee.EncodeBool(mksv[i].v)
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
case reflect.String:
mksv := make([]stringRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.String()
}
sort.Sort(stringRvSlice(mksv))
for i := range mksv {
if asSymbols {
ee.EncodeSymbol(mksv[i].v)
} else {
ee.EncodeString(c_UTF8, mksv[i].v)
}
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
mksv := make([]uintRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Uint()
}
sort.Sort(uintRvSlice(mksv))
for i := range mksv {
ee.EncodeUint(mksv[i].v)
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
mksv := make([]intRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Int()
}
sort.Sort(intRvSlice(mksv))
for i := range mksv {
ee.EncodeInt(mksv[i].v)
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
case reflect.Float32:
mksv := make([]floatRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Float()
}
sort.Sort(floatRvSlice(mksv))
for i := range mksv {
ee.EncodeFloat32(float32(mksv[i].v))
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
case reflect.Float64:
mksv := make([]floatRv, len(mks))
for i, k := range mks {
v := &mksv[i]
v.r = k
v.v = k.Float()
}
sort.Sort(floatRvSlice(mksv))
for i := range mksv {
ee.EncodeFloat64(mksv[i].v)
e.encodeValue(rv.MapIndex(mksv[i].r), valFn)
}
default:
// out-of-band
// first encode each key to a []byte first, then sort them, then record
var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding
e2 := NewEncoderBytes(&mksv, e.hh)
mksbv := make([]bytesRv, len(mks))
for i, k := range mks {
v := &mksbv[i]
l := len(mksv)
e2.MustEncode(k)
v.r = k
v.v = mksv[l:]
// fmt.Printf(">>>>> %s\n", mksv[l:])
}
sort.Sort(bytesRvSlice(mksbv))
for j := range mksbv {
e.asis(mksbv[j].v)
e.encodeValue(rv.MapIndex(mksbv[j].r), valFn)
}
}
}
}
// --------------------------------------------------
// encFn encapsulates the captured variables and the encode function.
@ -903,16 +1003,9 @@ func (e *Encoder) encode(iv interface{}) {
e.e.EncodeStringBytes(c_RAW, *v)
default:
// canonical mode is not supported for fastpath of maps (but is fine for slices)
const checkCodecSelfer1 = true // in case T is passed, where *T is a Selfer, still checkCodecSelfer
if e.h.Canonical {
if !fastpathEncodeTypeSwitchSlice(iv, e) {
e.encodeI(iv, false, checkCodecSelfer1)
}
} else {
if !fastpathEncodeTypeSwitch(iv, e) {
e.encodeI(iv, false, checkCodecSelfer1)
}
if !fastpathEncodeTypeSwitch(iv, e) {
e.encodeI(iv, false, checkCodecSelfer1)
}
}
}
@ -1019,8 +1112,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo
fn.f = (*encFnInfo).textMarshal
} else {
rk := rt.Kind()
// if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
if fastpathEnabled && checkFastpath && (rk == reflect.Slice || (rk == reflect.Map && !e.h.Canonical)) {
if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) {
if rt.PkgPath() == "" {
if idx := fastpathAV.index(rtid); idx != -1 {
fn.f = fastpathAV[idx].encfn
@ -1114,11 +1206,6 @@ func (e *Encoder) errorf(format string, params ...interface{}) {
// ----------------------------------------
type encStructFieldKV struct {
k string
v reflect.Value
}
const encStructPoolLen = 5
// encStructPool is an array of sync.Pool.
@ -1133,33 +1220,33 @@ const encStructPoolLen = 5
var encStructPool [encStructPoolLen]sync.Pool
func init() {
encStructPool[0].New = func() interface{} { return new([8]encStructFieldKV) }
encStructPool[1].New = func() interface{} { return new([16]encStructFieldKV) }
encStructPool[2].New = func() interface{} { return new([32]encStructFieldKV) }
encStructPool[3].New = func() interface{} { return new([64]encStructFieldKV) }
encStructPool[4].New = func() interface{} { return new([128]encStructFieldKV) }
encStructPool[0].New = func() interface{} { return new([8]stringRv) }
encStructPool[1].New = func() interface{} { return new([16]stringRv) }
encStructPool[2].New = func() interface{} { return new([32]stringRv) }
encStructPool[3].New = func() interface{} { return new([64]stringRv) }
encStructPool[4].New = func() interface{} { return new([128]stringRv) }
}
func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []encStructFieldKV) {
func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) {
// if encStructPoolLen != 5 { // constant chec, so removed at build time.
// panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed
// }
// idxpool := newlen / 8
// if pool == nil {
// fkvs = make([]encStructFieldKV, newlen)
// fkvs = make([]stringRv, newlen)
// } else {
// poolv = pool.Get()
// switch vv := poolv.(type) {
// case *[8]encStructFieldKV:
// case *[8]stringRv:
// fkvs = vv[:newlen]
// case *[16]encStructFieldKV:
// case *[16]stringRv:
// fkvs = vv[:newlen]
// case *[32]encStructFieldKV:
// case *[32]stringRv:
// fkvs = vv[:newlen]
// case *[64]encStructFieldKV:
// case *[64]stringRv:
// fkvs = vv[:newlen]
// case *[128]encStructFieldKV:
// case *[128]stringRv:
// fkvs = vv[:newlen]
// }
// }
@ -1167,25 +1254,25 @@ func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []encStructFie
if newlen <= 8 {
p = &encStructPool[0]
v = p.Get()
s = v.(*[8]encStructFieldKV)[:newlen]
s = v.(*[8]stringRv)[:newlen]
} else if newlen <= 16 {
p = &encStructPool[1]
v = p.Get()
s = v.(*[16]encStructFieldKV)[:newlen]
s = v.(*[16]stringRv)[:newlen]
} else if newlen <= 32 {
p = &encStructPool[2]
v = p.Get()
s = v.(*[32]encStructFieldKV)[:newlen]
s = v.(*[32]stringRv)[:newlen]
} else if newlen <= 64 {
p = &encStructPool[3]
v = p.Get()
s = v.(*[64]encStructFieldKV)[:newlen]
s = v.(*[64]stringRv)[:newlen]
} else if newlen <= 128 {
p = &encStructPool[4]
v = p.Get()
s = v.(*[128]encStructFieldKV)[:newlen]
s = v.(*[128]stringRv)[:newlen]
} else {
s = make([]encStructFieldKV, newlen)
s = make([]stringRv, newlen)
}
return
}

File diff suppressed because it is too large Load Diff

View File

@ -116,6 +116,7 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e)
{{end}}{{end}}
default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
return false
}
return true
@ -182,14 +183,50 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele
return
}
ee.EncodeMapStart(len(v))
{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0{{end}}
for k2, v2 := range v {
{{if eq .MapKey "string"}}if asSymbols {
ee.EncodeSymbol(k2)
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ encmd .MapKey "k2"}}{{end}}
{{ encmd .Elem "v2"}}
{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
{{end}}if e.h.Canonical {
{{if eq .MapKey "interface{}"}}{{/* out of band
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
e2 := NewEncoderBytes(&mksv, e.hh)
v2 := make([]bytesI, len(v))
var i, l int
var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
for k2, _ := range v {
l = len(mksv)
e2.MustEncode(k2)
vp = &v2[i]
vp.v = mksv[l:]
vp.i = k2
i++
}
sort.Sort(bytesISlice(v2))
for j := range v2 {
e.asis(v2[j].v)
e.encode(v[v2[j].i])
} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
var i int
for k, _ := range v {
v2[i] = {{ $x }}(k)
i++
}
sort.Sort({{ sorttype .MapKey false}}(v2))
for _, k2 := range v2 {
{{if eq .MapKey "string"}}if asSymbols {
ee.EncodeSymbol(k2)
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
} {{end}}
} else {
for k2, v2 := range v {
{{if eq .MapKey "string"}}if asSymbols {
ee.EncodeSymbol(k2)
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ encmd .MapKey "k2"}}{{end}}
{{ encmd .Elem "v2"}}
}
}
ee.EncodeEnd()
}
@ -382,30 +419,31 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele
v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
changed = true
}
{{ if eq .Elem "interface{}" }}mapGet := !d.h.MapValueReset && !d.h.InterfaceReset{{end}}
var mk {{ .MapKey }}
var mv {{ .Elem }}
if containerLen > 0 {
for j := 0; j < containerLen; j++ {
{{ if eq .MapKey "interface{}" }}var mk interface{}
{{ if eq .MapKey "interface{}" }}mk = nil
d.decode(&mk)
if bv, bok := mk.([]byte); bok {
mk = string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
}{{ else }}mk := {{ decmd .MapKey }}{{ end }}
mv := v[mk]
{{ if eq .Elem "interface{}" }}d.decode(&mv)
{{ else }}mv = {{ decmd .Elem }}{{ end }}
mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
if v != nil {
v[mk] = mv
}
}
} else if containerLen < 0 {
for j := 0; !dd.CheckBreak(); j++ {
{{ if eq .MapKey "interface{}" }}var mk interface{}
{{ if eq .MapKey "interface{}" }}mk = nil
d.decode(&mk)
if bv, bok := mk.([]byte); bok {
mk = string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
}{{ else }}mk := {{ decmd .MapKey }}{{ end }}
mv := v[mk]
{{ if eq .Elem "interface{}" }}d.decode(&mv)
{{ else }}mv = {{ decmd .Elem }}{{ end }}
mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
if v != nil {
v[mk] = mv
}

View File

@ -1,20 +1,28 @@
{{var "v"}} := *{{ .Varname }}
{{var "l"}} := r.ReadMapStart()
{{var "bh"}} := z.DecBasicHandle()
if {{var "v"}} == nil {
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
*{{ .Varname }} = {{var "v"}}
}
var {{var "mk"}} {{ .KTyp }}
var {{var "mv"}} {{ .Typ }}
var {{var "mg"}} bool
if {{var "bh"}}.MapValueReset {
{{if decElemKindPtr}}{{var "mg"}} = true
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
{{else if not decElemKindImmutable}}{{var "mg"}} = true
{{end}} }
if {{var "l"}} > 0 {
for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
var {{var "mk"}} {{ .KTyp }}
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
{{ if eq .KTyp "interface{}" }}// special case if a byte array.
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = string({{var "bv"}})
}
{{ end }}
{{var "mv"}} := {{var "v"}}[{{var "mk"}}]
}{{ end }}
if {{var "mg"}} {
{{var "mv"}} = {{var "v"}}[{{var "mk"}}]
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
@ -22,14 +30,13 @@ for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
}
} else if {{var "l"}} < 0 {
for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ {
var {{var "mk"}} {{ .KTyp }}
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
{{ if eq .KTyp "interface{}" }}// special case if a byte array.
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = string({{var "bv"}})
}
{{ end }}
{{var "mv"}} := {{var "v"}}[{{var "mk"}}]
}{{ end }}
if {{var "mg"}} {
{{var "mv"}} = {{var "v"}}[{{var "mk"}}]
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}

View File

@ -8,21 +8,29 @@ package codec
const genDecMapTmpl = `
{{var "v"}} := *{{ .Varname }}
{{var "l"}} := r.ReadMapStart()
{{var "bh"}} := z.DecBasicHandle()
if {{var "v"}} == nil {
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
*{{ .Varname }} = {{var "v"}}
}
var {{var "mk"}} {{ .KTyp }}
var {{var "mv"}} {{ .Typ }}
var {{var "mg"}} bool
if {{var "bh"}}.MapValueReset {
{{if decElemKindPtr}}{{var "mg"}} = true
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
{{else if not decElemKindImmutable}}{{var "mg"}} = true
{{end}} }
if {{var "l"}} > 0 {
for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
var {{var "mk"}} {{ .KTyp }}
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
{{ if eq .KTyp "interface{}" }}// special case if a byte array.
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = string({{var "bv"}})
}
{{ end }}
{{var "mv"}} := {{var "v"}}[{{var "mk"}}]
}{{ end }}
if {{var "mg"}} {
{{var "mv"}} = {{var "v"}}[{{var "mk"}}]
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
@ -30,14 +38,13 @@ for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ {
}
} else if {{var "l"}} < 0 {
for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ {
var {{var "mk"}} {{ .KTyp }}
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
{{ if eq .KTyp "interface{}" }}// special case if a byte array.
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = string({{var "bv"}})
}
{{ end }}
{{var "mv"}} := {{var "v"}}[{{var "mk"}}]
}{{ end }}
if {{var "mg"}} {
{{var "mv"}} = {{var "v"}}[{{var "mk"}}]
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}

View File

@ -169,7 +169,7 @@ func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeIn
ts: []reflect.Type{},
bp: genImportPath(typ[0]),
xs: uid,
ti: ti, //TODO: make it configurable
ti: ti,
}
if x.ti == nil {
x.ti = defTypeInfos
@ -928,6 +928,7 @@ func (x *genRunner) encListFallback(varname string, t reflect.Type) {
}
func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
// TODO: expand this to handle canonical.
i := x.varsfx()
x.line("r.EncodeMapStart(len(" + varname + "))")
x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
@ -1301,8 +1302,24 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type)
}
telem := t.Elem()
tkey := t.Key()
ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(tkey), x.genTypeName(telem), int(telem.Size() + tkey.Size())}
ts := tstruc{
genTempVarPfx, x.varsfx(), varname, x.genTypeName(tkey),
x.genTypeName(telem), int(telem.Size() + tkey.Size()),
}
funcs := make(template.FuncMap)
funcs["decElemZero"] = func() string {
return x.genZeroValueR(telem)
}
funcs["decElemKindImmutable"] = func() bool {
return genIsImmutable(telem)
}
funcs["decElemKindPtr"] = func() bool {
return telem.Kind() == reflect.Ptr
}
funcs["decElemKindIntf"] = func() bool {
return telem.Kind() == reflect.Interface
}
funcs["decLineVarK"] = func(varname string) string {
x.decVar(varname, tkey, false)
return ""
@ -1726,6 +1743,8 @@ func genInternalDecCommandAsString(s string) string {
return "uint32(dd.DecodeUint(32))"
case "uint64":
return "dd.DecodeUint(64)"
case "uintptr":
return "uintptr(dd.DecodeUint(uintBitsize))"
case "int":
return "int(dd.DecodeInt(intBitsize))"
case "int8":
@ -1746,9 +1765,24 @@ func genInternalDecCommandAsString(s string) string {
case "bool":
return "dd.DecodeBool()"
default:
panic(errors.New("unknown type for decode: " + s))
panic(errors.New("gen internal: unknown type for decode: " + s))
}
}
func genInternalSortType(s string, elem bool) string {
for _, v := range [...]string{"int", "uint", "float", "bool", "string"} {
if strings.HasPrefix(s, v) {
if elem {
if v == "int" || v == "uint" || v == "float" {
return v + "64"
} else {
return v
}
}
return v + "Slice"
}
}
panic("sorttype: unexpected type: " + s)
}
// var genInternalMu sync.Mutex
@ -1767,6 +1801,7 @@ func genInternalInit() {
"uint16",
"uint32",
"uint64",
"uintptr",
"int",
"int8",
"int16",
@ -1784,6 +1819,7 @@ func genInternalInit() {
"uint16",
"uint32",
"uint64",
"uintptr",
"int",
"int8",
"int16",
@ -1803,6 +1839,7 @@ func genInternalInit() {
"uint16": 2,
"uint32": 4,
"uint64": 8,
"uintptr": 1 * wordSizeBytes,
"int": 1 * wordSizeBytes,
"int8": 1,
"int16": 2,
@ -1837,16 +1874,18 @@ func genInternalInit() {
funcs["encmd"] = genInternalEncCommandAsString
funcs["decmd"] = genInternalDecCommandAsString
funcs["zerocmd"] = genInternalZeroValue
funcs["hasprefix"] = strings.HasPrefix
funcs["sorttype"] = genInternalSortType
genInternalV = gt
genInternalTmplFuncs = funcs
}
// GenInternalGoFile is used to generate source files from templates.
// genInternalGoFile is used to generate source files from templates.
// It is run by the program author alone.
// Unfortunately, it has to be exported so that it can be called from a command line tool.
// *** DO NOT USE ***
func GenInternalGoFile(r io.Reader, w io.Writer, safe bool) (err error) {
func genInternalGoFile(r io.Reader, w io.Writer, safe bool) (err error) {
genInternalOnce.Do(genInternalInit)
gt := genInternalV

View File

@ -101,6 +101,7 @@ package codec
// check for these error conditions.
import (
"bytes"
"encoding"
"encoding/binary"
"errors"
@ -975,3 +976,114 @@ func (_ checkOverflow) SignedInt(v uint64) (i int64, overflow bool) {
i = int64(v)
return
}
// ------------------ SORT -----------------
func isNaN(f float64) bool { return f != f }
// -----------------------
type intSlice []int64
type uintSlice []uint64
type floatSlice []float64
type boolSlice []bool
type stringSlice []string
type bytesSlice [][]byte
func (p intSlice) Len() int { return len(p) }
func (p intSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p intSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p uintSlice) Len() int { return len(p) }
func (p uintSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p uintSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p floatSlice) Len() int { return len(p) }
func (p floatSlice) Less(i, j int) bool {
return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j])
}
func (p floatSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p stringSlice) Len() int { return len(p) }
func (p stringSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p stringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p bytesSlice) Len() int { return len(p) }
func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 }
func (p bytesSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p boolSlice) Len() int { return len(p) }
func (p boolSlice) Less(i, j int) bool { return !p[i] && p[j] }
func (p boolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// ---------------------
type intRv struct {
v int64
r reflect.Value
}
type intRvSlice []intRv
type uintRv struct {
v uint64
r reflect.Value
}
type uintRvSlice []uintRv
type floatRv struct {
v float64
r reflect.Value
}
type floatRvSlice []floatRv
type boolRv struct {
v bool
r reflect.Value
}
type boolRvSlice []boolRv
type stringRv struct {
v string
r reflect.Value
}
type stringRvSlice []stringRv
type bytesRv struct {
v []byte
r reflect.Value
}
type bytesRvSlice []bytesRv
func (p intRvSlice) Len() int { return len(p) }
func (p intRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
func (p intRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p uintRvSlice) Len() int { return len(p) }
func (p uintRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
func (p uintRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p floatRvSlice) Len() int { return len(p) }
func (p floatRvSlice) Less(i, j int) bool {
return p[i].v < p[j].v || isNaN(p[i].v) && !isNaN(p[j].v)
}
func (p floatRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p stringRvSlice) Len() int { return len(p) }
func (p stringRvSlice) Less(i, j int) bool { return p[i].v < p[j].v }
func (p stringRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p bytesRvSlice) Len() int { return len(p) }
func (p bytesRvSlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
func (p bytesRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p boolRvSlice) Len() int { return len(p) }
func (p boolRvSlice) Less(i, j int) bool { return !p[i].v && p[j].v }
func (p boolRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// -----------------
type bytesI struct {
v []byte
i interface{}
}
type bytesISlice []bytesI
func (p bytesISlice) Len() int { return len(p) }
func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 }
func (p bytesISlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

View File

@ -411,7 +411,7 @@ func (e *jsonEncDriver) quoteStr(s string) {
//--------------------------------
type jsonNum struct {
bytes []byte // may have [+-.eE0-9]
// bytes []byte // may have [+-.eE0-9]
mantissa uint64 // where mantissa ends, and maybe dot begins.
exponent int16 // exponent value.
manOverflow bool
@ -421,7 +421,6 @@ type jsonNum struct {
}
func (x *jsonNum) reset() {
x.bytes = x.bytes[:0]
x.manOverflow = false
x.neg = false
x.dot = false
@ -454,29 +453,26 @@ func (x *jsonNum) uintExp() (n uint64, overflow bool) {
// return
}
func (x *jsonNum) floatVal() (f float64) {
// these constants are only used withn floatVal.
// They are brought out, so that floatVal can be inlined.
const (
jsonUint64MantissaBits = 52
jsonMaxExponent = int16(len(jsonFloat64Pow10)) - 1
)
func (x *jsonNum) floatVal() (f float64, parseUsingStrConv bool) {
// We do not want to lose precision.
// Consequently, we will delegate to strconv.ParseFloat if any of the following happen:
// - There are more digits than in math.MaxUint64: 18446744073709551615 (20 digits)
// We expect up to 99.... (19 digits)
// - The mantissa cannot fit into a 52 bits of uint64
// - The exponent is beyond our scope ie beyong 22.
const uint64MantissaBits = 52
const maxExponent = int16(len(jsonFloat64Pow10)) - 1
parseUsingStrConv = x.manOverflow ||
x.exponent > jsonMaxExponent ||
(x.exponent < 0 && -(x.exponent) > jsonMaxExponent) ||
x.mantissa>>jsonUint64MantissaBits != 0
parseUsingStrConv := x.manOverflow ||
x.exponent > maxExponent ||
(x.exponent < 0 && -(x.exponent) > maxExponent) ||
x.mantissa>>uint64MantissaBits != 0
if parseUsingStrConv {
var err error
if f, err = strconv.ParseFloat(stringView(x.bytes), 64); err != nil {
panic(fmt.Errorf("parse float: %s, %v", x.bytes, err))
return
}
if x.neg {
f = -f
}
return
}
@ -500,8 +496,9 @@ type jsonDecDriver struct {
r decReader // *bytesDecReader decReader
ct valueType // container type. one of unset, array or map.
bstr [8]byte // scratch used for string \UXXX parsing
b [64]byte // scratch
b2 [64]byte
b [64]byte // scratch, used for parsing strings or numbers
b2 [64]byte // scratch, used only for decodeBytes (after base64)
bs []byte // scratch. Initialized from b. Used for parsing strings or numbers.
wsSkipped bool // whitespace skipped
@ -662,8 +659,6 @@ func (d *jsonDecDriver) IsContainerType(vt valueType) bool {
}
func (d *jsonDecDriver) decNum(storeBytes bool) {
// storeBytes = true // TODO: remove.
// If it is has a . or an e|E, decode as a float; else decode as an int.
b := d.skipWhitespace(false)
if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) {
@ -674,10 +669,9 @@ func (d *jsonDecDriver) decNum(storeBytes bool) {
const cutoff = (1<<64-1)/uint64(10) + 1 // cutoff64(base)
const jsonNumUintMaxVal = 1<<uint64(64) - 1
// var n jsonNum // create stack-copy jsonNum, and set to pointer at end.
// n.bytes = d.n.bytes[:0]
n := &d.n
n.reset()
d.bs = d.bs[:0]
// The format of a number is as below:
// parsing: sign? digit* dot? digit* e? sign? digit*
@ -773,7 +767,7 @@ LOOP:
break LOOP
}
if storeBytes {
n.bytes = append(n.bytes, b)
d.bs = append(d.bs, b)
}
b, eof = d.r.readn1eof()
}
@ -834,13 +828,28 @@ func (d *jsonDecDriver) DecodeInt(bitsize uint8) (i int64) {
i = -i
}
if chkOvf.Int(i, bitsize) {
d.d.errorf("json: overflow %v bits: %s", bitsize, n.bytes)
d.d.errorf("json: overflow %v bits: %s", bitsize, d.bs)
return
}
// fmt.Printf("DecodeInt: %v\n", i)
return
}
// floatVal MUST only be called after a decNum, as d.bs now contains the bytes of the number
func (d *jsonDecDriver) floatVal() (f float64) {
f, useStrConv := d.n.floatVal()
if useStrConv {
var err error
if f, err = strconv.ParseFloat(stringView(d.bs), 64); err != nil {
panic(fmt.Errorf("parse float: %s, %v", d.bs, err))
}
if d.n.neg {
f = -f
}
}
return
}
func (d *jsonDecDriver) DecodeUint(bitsize uint8) (u uint64) {
if c := d.s.sc.sep(); c != 0 {
d.expectChar(c)
@ -868,7 +877,7 @@ func (d *jsonDecDriver) DecodeUint(bitsize uint8) (u uint64) {
}
}
if chkOvf.Uint(u, bitsize) {
d.d.errorf("json: overflow %v bits: %s", bitsize, n.bytes)
d.d.errorf("json: overflow %v bits: %s", bitsize, d.bs)
return
}
// fmt.Printf("DecodeUint: %v\n", u)
@ -880,10 +889,9 @@ func (d *jsonDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
d.expectChar(c)
}
d.decNum(true)
n := &d.n
f = n.floatVal()
f = d.floatVal()
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("json: overflow float32: %v, %s", f, n.bytes)
d.d.errorf("json: overflow float32: %v, %s", f, d.bs)
return
}
return
@ -916,12 +924,13 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [
if c := d.s.sc.sep(); c != 0 {
d.expectChar(c)
}
bs0 := d.appendStringAsBytes(d.b[:0])
d.appendStringAsBytes()
// if isstring, then just return the bytes, even if it is using the scratch buffer.
// the bytes will be converted to a string as needed.
if isstring {
return bs0
return d.bs
}
bs0 := d.bs
slen := base64.StdEncoding.DecodedLen(len(bs0))
if slen <= cap(bs) {
bsOut = bs[:slen]
@ -945,13 +954,23 @@ func (d *jsonDecDriver) DecodeString() (s string) {
if c := d.s.sc.sep(); c != 0 {
d.expectChar(c)
}
return string(d.appendStringAsBytes(d.b[:0]))
return d.decString()
}
func (d *jsonDecDriver) appendStringAsBytes(v []byte) []byte {
func (d *jsonDecDriver) decString() (s string) {
d.appendStringAsBytes()
if x := d.s.sc; x != nil && x.st == '}' && x.so { // map key
return d.d.string(d.bs)
}
return string(d.bs)
}
func (d *jsonDecDriver) appendStringAsBytes() {
d.expectChar('"')
v := d.bs[:0]
var c uint8
for {
c := d.r.readn1()
c = d.r.readn1()
if c == '"' {
break
} else if c == '\\' {
@ -979,7 +998,6 @@ func (d *jsonDecDriver) appendStringAsBytes(v []byte) []byte {
v = append(v, d.bstr[:w2]...)
default:
d.d.errorf("json: unsupported escaped value: %c", c)
return nil
}
} else {
v = append(v, c)
@ -988,7 +1006,7 @@ func (d *jsonDecDriver) appendStringAsBytes(v []byte) []byte {
if jsonTrackSkipWhitespace {
d.wsSkipped = false
}
return v
d.bs = v
}
func (d *jsonDecDriver) jsonU4(checkSlashU bool) rune {
@ -1040,7 +1058,7 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe
decodeFurther = true
case '"':
vt = valueTypeString
v = string(d.appendStringAsBytes(d.b[:0])) // same as d.DecodeString(), but skipping sep() call.
v = d.decString() // same as d.DecodeString(), but skipping sep() call.
default: // number
d.decNum(true)
n := &d.n
@ -1048,7 +1066,7 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe
switch {
case n.explicitExponent, n.dot, n.exponent < 0, n.manOverflow:
vt = valueTypeFloat
v = n.floatVal()
v = d.floatVal()
case n.exponent == 0:
u := n.mantissa
switch {
@ -1067,7 +1085,7 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe
switch {
case overflow:
vt = valueTypeFloat
v = n.floatVal()
v = d.floatVal()
case n.neg:
vt = valueTypeInt
v = -int64(u)
@ -1122,8 +1140,8 @@ func (h *JsonHandle) newEncDriver(e *Encoder) encDriver {
func (h *JsonHandle) newDecDriver(d *Decoder) decDriver {
// d := jsonDecDriver{r: r.(*bytesDecReader), h: h}
hd := jsonDecDriver{d: d, r: d.r, h: h}
hd.bs = hd.b[:0]
hd.se.i = h.RawBytesExt
hd.n.bytes = d.b[:]
return &hd
}

View File

@ -99,6 +99,14 @@ var fastpathAV fastpathA
EOF
cat > gen-from-tmpl.codec.generated.go <<EOF
package codec
import "io"
func GenInternalGoFile(r io.Reader, w io.Writer, safe bool) error {
return genInternalGoFile(r, w, safe)
}
EOF
cat > gen-from-tmpl.generated.go <<EOF
//+build ignore
@ -130,7 +138,7 @@ run("gen-helper.go.tmpl", "gen-helper.generated.go", false)
EOF
go run gen-from-tmpl.generated.go && \
rm -f gen-from-tmpl.generated.go
rm -f gen-from-tmpl.*generated.go
}
_codegenerators() {
@ -140,15 +148,26 @@ _codegenerators() {
"1" == $( _needgen "values_ffjson${zsfx}" ) ||
1 == 0 ]]
then
true && \
echo "codecgen - !unsafe ... " && \
codecgen -rt codecgen -t 'x,codecgen,!unsafe' -o values_codecgen${zsfx} -d 1978 $zfin && \
echo "codecgen - unsafe ... " && \
codecgen -u -rt codecgen -t 'x,codecgen,unsafe' -o values_codecgen_unsafe${zsfx} -d 1978 $zfin && \
echo "msgp ... " && \
msgp -tests=false -pkg=codec -o=values_msgp${zsfx} -file=$zfin && \
echo "ffjson ... " && \
ffjson -w values_ffjson${zsfx} $zfin && \
# codecgen creates some temporary files in the directory (main, pkg).
# Consequently, we should start msgp and ffjson first, and also put a small time latency before
# starting codecgen.
# Without this, ffjson chokes on one of the temporary files from codecgen.
echo "ffjson ... " && \
ffjson -w values_ffjson${zsfx} $zfin &
zzzIdFF=$!
echo "msgp ... " && \
msgp -tests=false -pkg=codec -o=values_msgp${zsfx} -file=$zfin &
zzzIdMsgp=$!
sleep 1 # give ffjson and msgp some buffer time. see note above.
echo "codecgen - !unsafe ... " && \
codecgen -rt codecgen -t 'x,codecgen,!unsafe' -o values_codecgen${zsfx} -d 19780 $zfin &
zzzIdC=$!
echo "codecgen - unsafe ... " && \
codecgen -u -rt codecgen -t 'x,codecgen,unsafe' -o values_codecgen_unsafe${zsfx} -d 19781 $zfin &
zzzIdCU=$!
wait $zzzIdC $zzzIdCU $zzzIdMsgp $zzzIdFF && \
# remove (M|Unm)arshalJSON implementations, so they don't conflict with encoding/json bench \
sed -i 's+ MarshalJSON(+ _MarshalJSON(+g' values_ffjson${zsfx} && \
sed -i 's+ UnmarshalJSON(+ _UnmarshalJSON(+g' values_ffjson${zsfx} && \

View File

@ -45,7 +45,7 @@ _run() {
}
# echo ">>>>>>> RUNNING VARIATIONS OF TESTS"
if [[ "x$@" = x ]]; then
if [[ "x$@" = "x" ]]; then
# r, x, g, gu
_run "-rtcins"
_run "-xtcins"

View File

@ -43,6 +43,7 @@ all:
verify:
hack/verify-gofmt.sh
hack/verify-boilerplate.sh
hack/verify-codecgen.sh
hack/verify-description.sh
hack/verify-generated-conversions.sh
hack/verify-generated-deep-copies.sh

View File

@ -40,7 +40,8 @@ if $SILENT ; then
echo "Running in the silent mode, run with -v if you want to see script logs."
fi
BASH_TARGETS="generated-conversions
BASH_TARGETS="codecgen
generated-conversions
generated-deep-copies
generated-docs
generated-swagger-docs

52
hack/update-codecgen.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
cd "${KUBE_ROOT}"
generated_files=$(
find . -not \( \
\( \
-wholename './output' \
-o -wholename './_output' \
-o -wholename './release' \
-o -wholename './target' \
-o -wholename '*/third_party/*' \
-o -wholename '*/Godeps/*' \
\) -prune \
\) -name '*.generated.go')
for generated_file in ${generated_files}; do
initial_dir=${PWD}
file=${generated_file//\.generated\.go/.go}
# codecgen work only if invoked from directory where the file
# is located.
pushd "$(dirname ${file})" > /dev/null
base_file=$(basename "${file}")
base_generated_file=$(basename "${generated_file}")
# We use '-d 1234' flag to have a deterministic output everytime.
# The constant was just randomly chosen.
codecgen -d 1234 -o "${base_generated_file}" "${base_file}"
# Add boilerplate at the begining of the generated file.
sed 's/YEAR/2015/' "${initial_dir}/hack/boilerplate/boilerplate.go.txt" > "${base_generated_file}.tmp"
cat "${base_generated_file}" >> "${base_generated_file}.tmp"
mv "${base_generated_file}.tmp" "${base_generated_file}"
popd > /dev/null
done

82
hack/verify-codecgen.sh Executable file
View File

@ -0,0 +1,82 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
kube::golang::setup_env
cd "${KUBE_ROOT}"
generated_files=$(
find . -not \( \
\( \
-wholename './output' \
-o -wholename './_output' \
-o -wholename './release' \
-o -wholename './target' \
-o -wholename '*/third_party/*' \
-o -wholename '*/Godeps/*' \
\) -prune \
\) -name '*.generated.go')
# create a nice clean place to put codecgen there
_tmpdir="$(mktemp -d -t codecgen.XXXXXX)"
function cleanup {
echo "Removing ${_tmpdir}"
rm -rf "${_tmpdir}"
}
trap cleanup EXIT
# build codecgen tool
# We make some tricks with GOPATH variable to make it work with Travis.
_gopath=${GOPATH}
export GOPATH="${_tmpdir}"
go get -u github.com/ugorji/go/codec/codecgen 2>/dev/null
go install github.com/ugorji/go/codec/codecgen 2>/dev/null
CODECGEN="${_tmpdir}/bin/codecgen"
export GOPATH=${_gopath}
for generated_file in ${generated_files}; do
initial_dir=${PWD}
file=${generated_file//\.generated\.go/.go}
# codecgen work only if invoked from directory where the file
# is located.
pushd "$(dirname ${file})" > /dev/null
base_file=$(basename "${file}")
base_generated_file=$(basename "${generated_file}")
# We use '-d 1234' flag to have a deterministic output everytime.
# The constant was just randomly chosen.
${CODECGEN} -d 1234 -o "${base_generated_file}.1tmp" "${base_file}"
# Add boilerplate at the begining of the generated file.
sed 's/YEAR/2015/' "${initial_dir}/hack/boilerplate/boilerplate.go.txt" > "${base_generated_file}.tmp"
cat "${base_generated_file}.1tmp" >> "${base_generated_file}.tmp"
rm "${base_generated_file}.1tmp"
ret=0
diff -Naupr -I 'Auto generated by' "${base_generated_file}" "${base_generated_file}.tmp" || ret=$?
if [[ $ret -eq 0 ]]; then
echo "${generated_file} up to date."
else
echo "${generated_file} is out of date. Please run hack/update-codecgen.sh"
exit 1
fi
rm "${base_generated_file}.tmp"
popd > /dev/null
done

43508
pkg/api/types.generated.go Normal file

File diff suppressed because it is too large Load Diff

43638
pkg/api/v1/types.generated.go Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,9 +17,9 @@ limitations under the License.
package conversion
import (
"encoding/json"
"errors"
"fmt"
"github.com/ugorji/go/codec"
)
func (s *Scheme) DecodeToVersionedObject(data []byte) (obj interface{}, version, kind string, err error) {
@ -38,7 +38,7 @@ func (s *Scheme) DecodeToVersionedObject(data []byte) (obj interface{}, version,
return nil, "", "", err
}
if err := json.Unmarshal(data, obj); err != nil {
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
return nil, "", "", err
}
return
@ -139,7 +139,7 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}
if err != nil {
return err
}
if err := json.Unmarshal(data, external); err != nil {
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(external); err != nil {
return err
}
flags, meta := s.generateConvertMeta(dataVersion, objVersion, external)

View File

@ -0,0 +1,513 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// ************************************************************
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED BY codecgen.
// ************************************************************
package testing
import (
"errors"
"fmt"
codec1978 "github.com/ugorji/go/codec"
pkg2_api "k8s.io/kubernetes/pkg/api"
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
pkg3_types "k8s.io/kubernetes/pkg/types"
"reflect"
"runtime"
time "time"
)
const (
codecSelferC_UTF81234 = 1
codecSelferC_RAW1234 = 0
codecSelferValueTypeArray1234 = 10
codecSelferValueTypeMap1234 = 9
)
var (
codecSelferBitsize1234 = uint8(reflect.TypeOf(uint(0)).Bits())
codecSelferOnlyMapOrArrayEncodeToStructErr1234 = errors.New(`only encoded map or array can be decoded into a struct`)
)
type codecSelfer1234 struct{}
func init() {
if codec1978.GenVersion != 4 {
_, file, _, _ := runtime.Caller(0)
err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v",
4, codec1978.GenVersion, file)
panic(err)
}
if false { // reference the types, but skip this branch at build/run time
var v0 pkg2_api.ObjectMeta
var v1 pkg1_unversioned.TypeMeta
var v2 pkg3_types.UID
var v3 time.Time
_, _, _, _ = v0, v1, v2, v3
}
}
func (x *TestStruct) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [7]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Kind != ""
yyq2[1] = x.APIVersion != ""
yyq2[2] = true
if yyr2 || yy2arr2 {
r.EncodeArrayStart(7)
} else {
var yynn2 int = 4
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
}
if yyr2 || yy2arr2 {
if yyq2[0] {
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[0] {
r.EncodeString(codecSelferC_UTF81234, string("kind"))
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
}
}
if yyr2 || yy2arr2 {
if yyq2[1] {
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[1] {
r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
}
}
if yyr2 || yy2arr2 {
if yyq2[2] {
yy10 := &x.ObjectMeta
yy10.CodecEncodeSelf(e)
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
r.EncodeString(codecSelferC_UTF81234, string("metadata"))
yy11 := &x.ObjectMeta
yy11.CodecEncodeSelf(e)
}
}
if yyr2 || yy2arr2 {
yym13 := z.EncBinary()
_ = yym13
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
}
} else {
r.EncodeString(codecSelferC_UTF81234, string("Key"))
yym14 := z.EncBinary()
_ = yym14
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Key))
}
}
if yyr2 || yy2arr2 {
if x.Map == nil {
r.EncodeNil()
} else {
yym16 := z.EncBinary()
_ = yym16
if false {
} else {
z.F.EncMapStringIntV(x.Map, false, e)
}
}
} else {
r.EncodeString(codecSelferC_UTF81234, string("Map"))
if x.Map == nil {
r.EncodeNil()
} else {
yym17 := z.EncBinary()
_ = yym17
if false {
} else {
z.F.EncMapStringIntV(x.Map, false, e)
}
}
}
if yyr2 || yy2arr2 {
if x.StringList == nil {
r.EncodeNil()
} else {
yym19 := z.EncBinary()
_ = yym19
if false {
} else {
z.F.EncSliceStringV(x.StringList, false, e)
}
}
} else {
r.EncodeString(codecSelferC_UTF81234, string("StringList"))
if x.StringList == nil {
r.EncodeNil()
} else {
yym20 := z.EncBinary()
_ = yym20
if false {
} else {
z.F.EncSliceStringV(x.StringList, false, e)
}
}
}
if yyr2 || yy2arr2 {
if x.IntList == nil {
r.EncodeNil()
} else {
yym22 := z.EncBinary()
_ = yym22
if false {
} else {
z.F.EncSliceIntV(x.IntList, false, e)
}
}
} else {
r.EncodeString(codecSelferC_UTF81234, string("IntList"))
if x.IntList == nil {
r.EncodeNil()
} else {
yym23 := z.EncBinary()
_ = yym23
if false {
} else {
z.F.EncSliceIntV(x.IntList, false, e)
}
}
}
if yysep2 {
r.EncodeEnd()
}
}
}
}
func (x *TestStruct) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym24 := z.DecBinary()
_ = yym24
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
if r.IsContainerType(codecSelferValueTypeMap1234) {
yyl25 := r.ReadMapStart()
if yyl25 == 0 {
r.ReadEnd()
} else {
x.codecDecodeSelfFromMap(yyl25, d)
}
} else if r.IsContainerType(codecSelferValueTypeArray1234) {
yyl25 := r.ReadArrayStart()
if yyl25 == 0 {
r.ReadEnd()
} else {
x.codecDecodeSelfFromArray(yyl25, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *TestStruct) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys26Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys26Slc
var yyhl26 bool = l >= 0
for yyj26 := 0; ; yyj26++ {
if yyhl26 {
if yyj26 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
yys26Slc = r.DecodeBytes(yys26Slc, true, true)
yys26 := string(yys26Slc)
switch yys26 {
case "kind":
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
x.Kind = string(r.DecodeString())
}
case "apiVersion":
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
x.APIVersion = string(r.DecodeString())
}
case "metadata":
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv29 := &x.ObjectMeta
yyv29.CodecDecodeSelf(d)
}
case "Key":
if r.TryDecodeAsNil() {
x.Key = ""
} else {
x.Key = string(r.DecodeString())
}
case "Map":
if r.TryDecodeAsNil() {
x.Map = nil
} else {
yyv31 := &x.Map
yym32 := z.DecBinary()
_ = yym32
if false {
} else {
z.F.DecMapStringIntX(yyv31, false, d)
}
}
case "StringList":
if r.TryDecodeAsNil() {
x.StringList = nil
} else {
yyv33 := &x.StringList
yym34 := z.DecBinary()
_ = yym34
if false {
} else {
z.F.DecSliceStringX(yyv33, false, d)
}
}
case "IntList":
if r.TryDecodeAsNil() {
x.IntList = nil
} else {
yyv35 := &x.IntList
yym36 := z.DecBinary()
_ = yym36
if false {
} else {
z.F.DecSliceIntX(yyv35, false, d)
}
}
default:
z.DecStructFieldNotFound(-1, yys26)
} // end switch yys26
} // end for yyj26
if !yyhl26 {
r.ReadEnd()
}
}
func (x *TestStruct) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj37 int
var yyb37 bool
var yyhl37 bool = l >= 0
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
x.Kind = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
x.APIVersion = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv40 := &x.ObjectMeta
yyv40.CodecDecodeSelf(d)
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.Key = ""
} else {
x.Key = string(r.DecodeString())
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.Map = nil
} else {
yyv42 := &x.Map
yym43 := z.DecBinary()
_ = yym43
if false {
} else {
z.F.DecMapStringIntX(yyv42, false, d)
}
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.StringList = nil
} else {
yyv44 := &x.StringList
yym45 := z.DecBinary()
_ = yym45
if false {
} else {
z.F.DecSliceStringX(yyv44, false, d)
}
}
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.IntList = nil
} else {
yyv46 := &x.IntList
yym47 := z.DecBinary()
_ = yym47
if false {
} else {
z.F.DecSliceIntX(yyv46, false, d)
}
}
for {
yyj37++
if yyhl37 {
yyb37 = yyj37 > l
} else {
yyb37 = r.CheckBreak()
}
if yyb37 {
break
}
z.DecStructFieldNotFound(yyj37-1, "")
}
r.ReadEnd()
}

View File

@ -0,0 +1,335 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// ************************************************************
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED BY codecgen.
// ************************************************************
package testing
import (
"errors"
"fmt"
codec1978 "github.com/ugorji/go/codec"
pkg2_api "k8s.io/kubernetes/pkg/api"
pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
pkg3_types "k8s.io/kubernetes/pkg/types"
"reflect"
"runtime"
time "time"
)
const (
codecSelferC_UTF81234 = 1
codecSelferC_RAW1234 = 0
codecSelferValueTypeArray1234 = 10
codecSelferValueTypeMap1234 = 9
)
var (
codecSelferBitsize1234 = uint8(reflect.TypeOf(uint(0)).Bits())
codecSelferOnlyMapOrArrayEncodeToStructErr1234 = errors.New(`only encoded map or array can be decoded into a struct`)
)
type codecSelfer1234 struct{}
func init() {
if codec1978.GenVersion != 4 {
_, file, _, _ := runtime.Caller(0)
err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v",
4, codec1978.GenVersion, file)
panic(err)
}
if false { // reference the types, but skip this branch at build/run time
var v0 pkg2_api.ObjectMeta
var v1 pkg1_unversioned.TypeMeta
var v2 pkg3_types.UID
var v3 time.Time
_, _, _, _ = v0, v1, v2, v3
}
}
func (x *TestResource) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Kind != ""
yyq2[1] = x.APIVersion != ""
if yyr2 || yy2arr2 {
r.EncodeArrayStart(4)
} else {
var yynn2 int = 2
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
}
if yyr2 || yy2arr2 {
if yyq2[0] {
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[0] {
r.EncodeString(codecSelferC_UTF81234, string("kind"))
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
}
}
if yyr2 || yy2arr2 {
if yyq2[1] {
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[1] {
r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
}
}
if yyr2 || yy2arr2 {
yy10 := &x.ObjectMeta
yy10.CodecEncodeSelf(e)
} else {
r.EncodeString(codecSelferC_UTF81234, string("metadata"))
yy11 := &x.ObjectMeta
yy11.CodecEncodeSelf(e)
}
if yyr2 || yy2arr2 {
yym13 := z.EncBinary()
_ = yym13
if false {
} else {
r.EncodeInt(int64(x.Value))
}
} else {
r.EncodeString(codecSelferC_UTF81234, string("value"))
yym14 := z.EncBinary()
_ = yym14
if false {
} else {
r.EncodeInt(int64(x.Value))
}
}
if yysep2 {
r.EncodeEnd()
}
}
}
}
func (x *TestResource) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym15 := z.DecBinary()
_ = yym15
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
if r.IsContainerType(codecSelferValueTypeMap1234) {
yyl16 := r.ReadMapStart()
if yyl16 == 0 {
r.ReadEnd()
} else {
x.codecDecodeSelfFromMap(yyl16, d)
}
} else if r.IsContainerType(codecSelferValueTypeArray1234) {
yyl16 := r.ReadArrayStart()
if yyl16 == 0 {
r.ReadEnd()
} else {
x.codecDecodeSelfFromArray(yyl16, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *TestResource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys17Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys17Slc
var yyhl17 bool = l >= 0
for yyj17 := 0; ; yyj17++ {
if yyhl17 {
if yyj17 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
yys17Slc = r.DecodeBytes(yys17Slc, true, true)
yys17 := string(yys17Slc)
switch yys17 {
case "kind":
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
x.Kind = string(r.DecodeString())
}
case "apiVersion":
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
x.APIVersion = string(r.DecodeString())
}
case "metadata":
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv20 := &x.ObjectMeta
yyv20.CodecDecodeSelf(d)
}
case "value":
if r.TryDecodeAsNil() {
x.Value = 0
} else {
x.Value = int(r.DecodeInt(codecSelferBitsize1234))
}
default:
z.DecStructFieldNotFound(-1, yys17)
} // end switch yys17
} // end for yyj17
if !yyhl17 {
r.ReadEnd()
}
}
func (x *TestResource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj22 int
var yyb22 bool
var yyhl22 bool = l >= 0
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
} else {
yyb22 = r.CheckBreak()
}
if yyb22 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
x.Kind = string(r.DecodeString())
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
} else {
yyb22 = r.CheckBreak()
}
if yyb22 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
x.APIVersion = string(r.DecodeString())
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
} else {
yyb22 = r.CheckBreak()
}
if yyb22 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.ObjectMeta = pkg2_api.ObjectMeta{}
} else {
yyv25 := &x.ObjectMeta
yyv25.CodecDecodeSelf(d)
}
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
} else {
yyb22 = r.CheckBreak()
}
if yyb22 {
r.ReadEnd()
return
}
if r.TryDecodeAsNil() {
x.Value = 0
} else {
x.Value = int(r.DecodeInt(codecSelferBitsize1234))
}
for {
yyj22++
if yyhl22 {
yyb22 = yyj22 > l
} else {
yyb22 = r.CheckBreak()
}
if yyb22 {
break
}
z.DecStructFieldNotFound(yyj22-1, "")
}
r.ReadEnd()
}