(r Reader, v reflect.Value, flags flags)
| 366 | } |
| 367 | |
| 368 | func (dec *structDecoder) decode(r Reader, v reflect.Value, flags flags) error { |
| 369 | flags = flags.only(decodeFlags) |
| 370 | coalesceBoolFields := flags.have(coalesceBoolFields) |
| 371 | |
| 372 | lastField := reflect.Value{} |
| 373 | union := len(dec.union) > 0 |
| 374 | seen := make([]uint64, 1) |
| 375 | if len(dec.required) > len(seen) { |
| 376 | seen = make([]uint64, len(dec.required)) |
| 377 | } |
| 378 | |
| 379 | err := readStruct(r, func(r Reader, f Field) error { |
| 380 | i := int(f.ID) - int(dec.minID) |
| 381 | if i < 0 || i >= len(dec.fields) || dec.fields[i].decode == nil { |
| 382 | return skipField(r, f) |
| 383 | } |
| 384 | field := &dec.fields[i] |
| 385 | seen[i/64] |= 1 << (i % 64) |
| 386 | |
| 387 | // TODO: implement type conversions? |
| 388 | if f.Type != field.typ && (f.Type != TRUE || field.typ != BOOL) { |
| 389 | if flags.have(strict) { |
| 390 | return &TypeMismatch{item: "field value", Expect: field.typ, Found: f.Type} |
| 391 | } |
| 392 | return nil |
| 393 | } |
| 394 | |
| 395 | x := v |
| 396 | for _, i := range field.index { |
| 397 | if x.Kind() == reflect.Ptr { |
| 398 | x = x.Elem() |
| 399 | } |
| 400 | if x = x.Field(i); x.Kind() == reflect.Ptr { |
| 401 | if x.IsNil() { |
| 402 | x.Set(reflect.New(x.Type().Elem())) |
| 403 | } |
| 404 | } |
| 405 | } |
| 406 | |
| 407 | if union { |
| 408 | v.Set(dec.zero) |
| 409 | } |
| 410 | |
| 411 | lastField = x |
| 412 | |
| 413 | if coalesceBoolFields && (f.Type == TRUE || f.Type == FALSE) { |
| 414 | for x.Kind() == reflect.Ptr { |
| 415 | if x.IsNil() { |
| 416 | x.Set(reflect.New(x.Type().Elem())) |
| 417 | } |
| 418 | x = x.Elem() |
| 419 | } |
| 420 | x.SetBool(f.Type == TRUE) |
| 421 | return nil |
| 422 | } |
| 423 | |
| 424 | return field.decode(r, x, flags.with(field.flags)) |
| 425 | }) |
no test coverage detected