github.com/urso/go-structform@v0.0.2/gotype/unfold_arr.yml (about) 1 import: 2 - unfold_templates.yml 3 4 main: | 5 package gotype 6 7 import "github.com/urso/go-structform" 8 9 {{/* defined 'lifted' pointer slice unfolders into reflection based unfolders */}} 10 var ( 11 unfolderReflArrIfc = liftGoUnfolder(newUnfolderArrIfc()) 12 {{ range data.primitiveTypes }} 13 {{ $t := capitalize . }} 14 unfolderReflArr{{ $t }} = liftGoUnfolder(newUnfolderArr{{ $t }}()) 15 {{ end }} 16 ) 17 18 {{/* define pointer based unfolder types */}} 19 {{ invoke "makeTypeWithName" "name" "Ifc" "type" "interface{}" }} 20 {{ template "makeType" "bool" }} 21 {{ template "makeType" "string" }} 22 {{ range .numTypes }} 23 {{ template "makeType" . }} 24 {{ end }} 25 26 {{/* create visitor callbacks */}} 27 {{ invoke "onIfcFns" "name" "unfolderArrIfc" "fn" "append" }} 28 {{ invoke "onBoolFns" "name" "unfolderArrBool" "fn" "append" }} 29 {{ invoke "onStringFns" "name" "unfolderArrString" "fn" "append" }} 30 {{ range .numTypes }} 31 {{ $type := . }} 32 {{ $name := capitalize $type | printf "unfolderArr%v" }} 33 {{ invoke "onNumberFns" "name" $name "type" $type "fn" "append" }} 34 {{ end }} 35 36 {{ template "arrIfc" }} 37 38 39 # makeTypeWithName(name, type) 40 templates.makeTypeWithName: | 41 {{ $type := .type }} 42 {{ $name := capitalize .name | printf "unfolderArr%v" }} 43 {{ $startName := capitalize .name | printf "unfoldArrStart%v" }} 44 45 {{ invoke "makeUnfoldType" "name" $name }} 46 {{ invoke "makeUnfoldType" "name" $startName "base" "unfolderErrArrayStart" }} 47 48 func (u *{{ $name }} ) initState(ctx *unfoldCtx, ptr unsafe.Pointer) { 49 ctx.unfolder.push(u) 50 ctx.unfolder.push(new{{ $startName | capitalize}}()) 51 ctx.idx.push(0) 52 ctx.ptr.push(ptr) 53 } 54 55 func (u * {{ $name }} ) cleanup(ctx *unfoldCtx) { 56 ctx.unfolder.pop() 57 ctx.idx.pop() 58 ctx.ptr.pop() 59 } 60 61 func (u * {{ $startName }}) cleanup(ctx *unfoldCtx) { 62 ctx.unfolder.pop() 63 } 64 65 func (u *{{ $startName }} ) ptr(ctx *unfoldCtx) *[]{{ $type }} { 66 return (*[]{{ $type }})(ctx.ptr.current) 67 } 68 69 func (u *{{ $name }} ) ptr(ctx *unfoldCtx) *[]{{ $type }} { 70 return (*[]{{ $type }})(ctx.ptr.current) 71 } 72 73 func (u *{{ $startName }}) OnArrayStart(ctx *unfoldCtx, l int, baseType structform.BaseType) error { 74 to := u.ptr(ctx) 75 if l < 0 { 76 l = 0 77 } 78 79 if *to == nil && l > 0 { 80 *to = make([]{{ $type }}, l) 81 } else if l < len(*to) { 82 *to = (*to)[:l] 83 } 84 85 u.cleanup(ctx) 86 return nil 87 } 88 89 func (u *{{ $name }} ) OnArrayFinished(ctx *unfoldCtx) error { 90 u.cleanup(ctx) 91 return nil 92 } 93 94 func (u *{{ $name }} ) append(ctx *unfoldCtx, v {{ $type }}) error { 95 idx := &ctx.idx 96 to := u.ptr(ctx) 97 if len(*to) <= idx.current { 98 *to = append(*to, v) 99 } else { 100 (*to)[idx.current] = v 101 } 102 103 idx.current++ 104 return nil 105 } 106 107 templates.arrIfc: | 108 109 func unfoldIfcStartSubArray(ctx *unfoldCtx, l int, baseType structform.BaseType) error { 110 _, ptr, unfolder := makeArrayPtr(ctx, l, baseType) 111 ctx.ptr.push(ptr) // store pointer for use in 'Finish' 112 ctx.baseType.push(baseType) 113 unfolder.initState(ctx, ptr) 114 return ctx.unfolder.current.OnArrayStart(ctx, l, baseType) 115 } 116 117 func unfoldIfcFinishSubArray(ctx *unfoldCtx) (interface{}, error) { 118 child := ctx.ptr.pop() 119 bt := ctx.baseType.pop() 120 switch bt { 121 {{ range $bt, $gt := data.mapTypes }} 122 case structform.{{ $bt }}: 123 ctx.buf.release() 124 return *(*[]{{ $gt }})(child), nil 125 {{ end }} 126 default: 127 return nil, errTODO() 128 } 129 } 130 131 func makeArrayPtr(ctx *unfoldCtx, l int, bt structform.BaseType) (interface{}, unsafe.Pointer, ptrUnfolder) { 132 switch bt { 133 {{ range $bt, $gt := data.mapTypes }} 134 case structform.{{ $bt }}: 135 sz := unsafe.Sizeof([]{{ $gt }}{}) 136 ptr := ctx.buf.alloc(int(sz)) 137 to := (*[]{{ $gt }})(ptr) 138 139 if l > 0 { 140 *to = make([]{{ $gt }}, l) 141 } 142 143 {{ if or (eq $bt "AnyType") (eq $bt "ZeroType") }} 144 unfolder := newUnfolderArrIfc() 145 {{ else }} 146 unfolder := newUnfolderArr{{ $gt | capitalize }}() 147 {{ end }} 148 return to, ptr, unfolder 149 150 {{ end }} 151 default: 152 panic("invalid type code") 153 return nil, nil, nil 154 } 155 }