7 "github.com/zclconf/go-cty/cty"
8 "github.com/zclconf/go-cty/cty/function"
9 "github.com/zclconf/go-cty/cty/gocty"
12 // Bytes is a capsule type that can be used with the binary functions to
13 // support applications that need to support raw buffers in addition to
15 var Bytes = cty.Capsule("bytes", reflect.TypeOf([]byte(nil)))
17 // BytesVal creates a new Bytes value from the given buffer, which must be
18 // non-nil or this function will panic.
20 // Once a byte slice has been wrapped in a Bytes capsule, its underlying array
21 // must be considered immutable.
22 func BytesVal(buf []byte) cty.Value {
24 panic("can't make Bytes value from nil slice")
27 return cty.CapsuleVal(Bytes, &buf)
30 // BytesLen is a Function that returns the length of the buffer encapsulated
32 var BytesLenFunc = function.New(&function.Spec{
33 Params: []function.Parameter{
37 AllowDynamicType: true,
40 Type: function.StaticReturnType(cty.Number),
41 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
42 bufPtr := args[0].EncapsulatedValue().(*[]byte)
43 return cty.NumberIntVal(int64(len(*bufPtr))), nil
47 // BytesSlice is a Function that returns a slice of the given Bytes value.
48 var BytesSliceFunc = function.New(&function.Spec{
49 Params: []function.Parameter{
53 AllowDynamicType: true,
58 AllowDynamicType: true,
63 AllowDynamicType: true,
66 Type: function.StaticReturnType(Bytes),
67 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
68 bufPtr := args[0].EncapsulatedValue().(*[]byte)
70 var offset, length int
73 err = gocty.FromCtyValue(args[1], &offset)
75 return cty.NilVal, err
77 err = gocty.FromCtyValue(args[2], &length)
79 return cty.NilVal, err
82 if offset < 0 || length < 0 {
83 return cty.NilVal, fmt.Errorf("offset and length must be non-negative")
86 if offset > len(*bufPtr) {
87 return cty.NilVal, fmt.Errorf(
88 "offset %d is greater than total buffer length %d",
93 end := offset + length
95 if end > len(*bufPtr) {
96 return cty.NilVal, fmt.Errorf(
97 "offset %d + length %d is greater than total buffer length %d",
98 offset, length, len(*bufPtr),
102 return BytesVal((*bufPtr)[offset:end]), nil
106 func BytesLen(buf cty.Value) (cty.Value, error) {
107 return BytesLenFunc.Call([]cty.Value{buf})
110 func BytesSlice(buf cty.Value, offset cty.Value, length cty.Value) (cty.Value, error) {
111 return BytesSliceFunc.Call([]cty.Value{buf, offset, length})