aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go
new file mode 100644
index 0000000..a132e0c
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/bytes.go
@@ -0,0 +1,112 @@
1package stdlib
2
3import (
4 "fmt"
5 "reflect"
6
7 "github.com/zclconf/go-cty/cty"
8 "github.com/zclconf/go-cty/cty/function"
9 "github.com/zclconf/go-cty/cty/gocty"
10)
11
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
14// UTF-8 strings.
15var Bytes = cty.Capsule("bytes", reflect.TypeOf([]byte(nil)))
16
17// BytesVal creates a new Bytes value from the given buffer, which must be
18// non-nil or this function will panic.
19//
20// Once a byte slice has been wrapped in a Bytes capsule, its underlying array
21// must be considered immutable.
22func BytesVal(buf []byte) cty.Value {
23 if buf == nil {
24 panic("can't make Bytes value from nil slice")
25 }
26
27 return cty.CapsuleVal(Bytes, &buf)
28}
29
30// BytesLen is a Function that returns the length of the buffer encapsulated
31// in a Bytes value.
32var BytesLenFunc = function.New(&function.Spec{
33 Params: []function.Parameter{
34 {
35 Name: "buf",
36 Type: Bytes,
37 AllowDynamicType: true,
38 },
39 },
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
44 },
45})
46
47// BytesSlice is a Function that returns a slice of the given Bytes value.
48var BytesSliceFunc = function.New(&function.Spec{
49 Params: []function.Parameter{
50 {
51 Name: "buf",
52 Type: Bytes,
53 AllowDynamicType: true,
54 },
55 {
56 Name: "offset",
57 Type: cty.Number,
58 AllowDynamicType: true,
59 },
60 {
61 Name: "length",
62 Type: cty.Number,
63 AllowDynamicType: true,
64 },
65 },
66 Type: function.StaticReturnType(Bytes),
67 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
68 bufPtr := args[0].EncapsulatedValue().(*[]byte)
69
70 var offset, length int
71
72 var err error
73 err = gocty.FromCtyValue(args[1], &offset)
74 if err != nil {
75 return cty.NilVal, err
76 }
77 err = gocty.FromCtyValue(args[2], &length)
78 if err != nil {
79 return cty.NilVal, err
80 }
81
82 if offset < 0 || length < 0 {
83 return cty.NilVal, fmt.Errorf("offset and length must be non-negative")
84 }
85
86 if offset > len(*bufPtr) {
87 return cty.NilVal, fmt.Errorf(
88 "offset %d is greater than total buffer length %d",
89 offset, len(*bufPtr),
90 )
91 }
92
93 end := offset + length
94
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),
99 )
100 }
101
102 return BytesVal((*bufPtr)[offset:end]), nil
103 },
104})
105
106func BytesLen(buf cty.Value) (cty.Value, error) {
107 return BytesLenFunc.Call([]cty.Value{buf})
108}
109
110func BytesSlice(buf cty.Value, offset cty.Value, length cty.Value) (cty.Value, error) {
111 return BytesSliceFunc.Call([]cty.Value{buf, offset, length})
112}