v must be a slice or array. We want it to be of length wantLen. Prepare it as necessary (details described in the code below), and return its resulting length. If an array is too short, return an error. This behavior differs from encoding/json, which just populates a short array with whatever it can
(v reflect.Value, wantLen int)
| 559 | // encoding/json, which just populates a short array with whatever it can and drops |
| 560 | // the rest. That can lose data. |
| 561 | func prepareLength(v reflect.Value, wantLen int) error { |
| 562 | vLen := v.Len() |
| 563 | if v.Kind() == reflect.Slice { |
| 564 | // Construct a slice of the right size, avoiding allocation if possible. |
| 565 | switch { |
| 566 | case vLen < wantLen: // v too short |
| 567 | if v.Cap() >= wantLen { // extend its length if there's room |
| 568 | v.SetLen(wantLen) |
| 569 | } else { // else make a new one |
| 570 | v.Set(reflect.MakeSlice(v.Type(), wantLen, wantLen)) |
| 571 | } |
| 572 | case vLen > wantLen: // v too long; truncate it |
| 573 | v.SetLen(wantLen) |
| 574 | } |
| 575 | } else { // array |
| 576 | switch { |
| 577 | case vLen < wantLen: // v too short |
| 578 | return gcerr.Newf(gcerr.InvalidArgument, nil, "array length %d is too short for incoming list of length %d", |
| 579 | vLen, wantLen) |
| 580 | case vLen > wantLen: // v too long; set extra elements to zero |
| 581 | z := reflect.Zero(v.Type().Elem()) |
| 582 | for i := wantLen; i < vLen; i++ { |
| 583 | v.Index(i).Set(z) |
| 584 | } |
| 585 | } |
| 586 | } |
| 587 | return nil |
| 588 | } |
| 589 | |
| 590 | // Since a map value is not settable via reflection, this function always creates a |
| 591 | // new element for each corresponding map key. Existing values of v are overwritten. |
no test coverage detected