| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package util |
| |
| import ( |
| "fmt" |
| |
| "v.io/v23/vdl" |
| "v.io/v23/vom" |
| ) |
| |
| type structSplitTarget struct { |
| tt *vdl.Type |
| fields []*vom.RawBytes |
| vdl.Target |
| } |
| |
| func (targ *structSplitTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) { |
| targ.tt = tt |
| targ.fields = make([]*vom.RawBytes, tt.NumField()) |
| return &structSplitFieldsTarget{targ}, nil |
| } |
| |
| func (targ *structSplitTarget) FinishFields(x vdl.FieldsTarget) error { |
| return nil |
| } |
| |
| func (targ *structSplitTarget) Fields() []*vom.RawBytes { |
| return targ.fields |
| } |
| |
| type structSplitFieldsTarget struct { |
| targ *structSplitTarget |
| } |
| |
| func (ft *structSplitFieldsTarget) StartField(name string) (key, field vdl.Target, _ error) { |
| _, index := ft.targ.tt.FieldByName(name) |
| rb := new(vom.RawBytes) |
| ft.targ.fields[index] = rb |
| return nil, rb.MakeVDLTarget(), nil |
| } |
| |
| func (ft *structSplitFieldsTarget) FinishField(key, field vdl.Target) error { |
| return nil |
| } |
| |
| func StructSplitTarget() *structSplitTarget { |
| return &structSplitTarget{} |
| } |
| |
| func JoinRawBytesAsStruct(targ vdl.Target, structType *vdl.Type, fields []*vom.RawBytes) error { |
| st, err := targ.StartFields(structType) |
| if err != nil { |
| return err |
| } |
| if structType.NumField() != len(fields) { |
| return fmt.Errorf("received %d fields, but %v has %d fields", len(fields), structType, structType.NumField()) |
| } |
| for i := 0; i < structType.NumField(); i++ { |
| f := structType.Field(i) |
| k, t, err := st.StartField(f.Name) |
| if err != nil { |
| return err |
| } |
| if err := fields[i].FillVDLTarget(t); err != nil { |
| return err |
| } |
| if err := st.FinishField(k, t); err != nil { |
| return err |
| } |
| } |
| return targ.FinishFields(st) |
| } |