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    }