encodeValue will encode a value. Note that encodeValue will handle nil in the stream early, so that the subsequent calls i.e. kXXX methods, etc do not have to handle it themselves.
(rv reflect.Value, fn *codecFn)
| 1279 | // Note that encodeValue will handle nil in the stream early, so that the |
| 1280 | // subsequent calls i.e. kXXX methods, etc do not have to handle it themselves. |
| 1281 | func (e *Encoder) encodeValue(rv reflect.Value, fn *codecFn) { |
| 1282 | // if a valid fn is passed, it MUST BE for the dereferenced type of rv |
| 1283 | |
| 1284 | // MARKER: We check if value is nil here, so that the kXXX method do not have to. |
| 1285 | |
| 1286 | var sptr interface{} |
| 1287 | var rvp reflect.Value |
| 1288 | var rvpValid bool |
| 1289 | TOP: |
| 1290 | switch rv.Kind() { |
| 1291 | case reflect.Ptr: |
| 1292 | if rvIsNil(rv) { |
| 1293 | e.e.EncodeNil() |
| 1294 | return |
| 1295 | } |
| 1296 | rvpValid = true |
| 1297 | rvp = rv |
| 1298 | rv = rv.Elem() |
| 1299 | goto TOP |
| 1300 | case reflect.Interface: |
| 1301 | if rvIsNil(rv) { |
| 1302 | e.e.EncodeNil() |
| 1303 | return |
| 1304 | } |
| 1305 | rvpValid = false |
| 1306 | rvp = reflect.Value{} |
| 1307 | rv = rv.Elem() |
| 1308 | goto TOP |
| 1309 | case reflect.Struct: |
| 1310 | if rvpValid && e.h.CheckCircularRef { |
| 1311 | sptr = rv2i(rvp) |
| 1312 | for _, vv := range e.ci { |
| 1313 | if eq4i(sptr, vv) { // error if sptr already seen |
| 1314 | e.errorf("circular reference found: %p, %T", sptr, sptr) |
| 1315 | } |
| 1316 | } |
| 1317 | e.ci = append(e.ci, sptr) |
| 1318 | } |
| 1319 | case reflect.Slice, reflect.Map, reflect.Chan: |
| 1320 | if rvIsNil(rv) { |
| 1321 | e.e.EncodeNil() |
| 1322 | return |
| 1323 | } |
| 1324 | case reflect.Invalid, reflect.Func: |
| 1325 | e.e.EncodeNil() |
| 1326 | return |
| 1327 | } |
| 1328 | |
| 1329 | if fn == nil { |
| 1330 | fn = e.h.fn(rv.Type()) |
| 1331 | } |
| 1332 | |
| 1333 | if !fn.i.addrE { // typically, addrE = false, so check it first |
| 1334 | // keep rv same |
| 1335 | } else if rvpValid { |
| 1336 | rv = rvp |
| 1337 | } else { |
| 1338 | rv = e.addrRV(rv, fn.i.ti.rt, fn.i.ti.ptr) |
no test coverage detected