Browse Source

codec: map iterator says whether the key/value() method returns valid values

This allows us to know whether to call the Key/Value() method or not.
Ugorji Nwoke 6 years ago
parent
commit
b01f3206d8

+ 7 - 2
codec/encode.go

@@ -666,10 +666,13 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 	var rvk = mapAddressableRV(f.ti.key, ktypeKind)
 
 	it := mapRange(rv, rvk, rvv, true)
+	validKV := it.ValidKV()
 	var vx reflect.Value
 	for it.Next() {
 		e.mapElemKey()
-		if vx = it.Key(); !vx.IsValid() {
+		if validKV {
+			vx = it.Key()
+		} else {
 			vx = rvk
 		}
 		if keyTypeIsString {
@@ -682,7 +685,9 @@ func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
 			e.encodeValue(vx, keyFn)
 		}
 		e.mapElemValue()
-		if vx = it.Value(); !vx.IsValid() {
+		if validKV {
+			vx = it.Value()
+		} else {
 			vx = rvv
 		}
 		e.encodeValue(vx, valFn)

+ 4 - 0
codec/goversion_maprange_gte_go112.go

@@ -14,6 +14,10 @@ type mapIter struct {
 	values bool
 }
 
+func (t *mapIter) ValidKV() (r bool) {
+	return true
+}
+
 func (t *mapIter) Next() (r bool) {
 	return t.t.Next()
 }

+ 4 - 0
codec/goversion_maprange_lt_go112.go

@@ -15,6 +15,10 @@ type mapIter struct {
 	values bool
 }
 
+func (t *mapIter) ValidKV() (r bool) {
+	return true
+}
+
 func (t *mapIter) Next() (r bool) {
 	t.j++
 	return t.j < len(t.keys)

+ 4 - 0
codec/helper_unsafe.go

@@ -704,6 +704,10 @@ type unsafeMapIter struct {
 // 	New: func() interface{} { return new(unsafeMapIter) },
 // }
 
+func (t *unsafeMapIter) ValidKV() (r bool) {
+	return false
+}
+
 func (t *unsafeMapIter) Next() (r bool) {
 	if t == nil || t.done {
 		return