diff options
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.go | 112 |
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 @@ | |||
1 | package stdlib | ||
2 | |||
3 | import ( | ||
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. | ||
15 | var 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. | ||
22 | func 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. | ||
32 | var 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. | ||
48 | var 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 | |||
106 | func BytesLen(buf cty.Value) (cty.Value, error) { | ||
107 | return BytesLenFunc.Call([]cty.Value{buf}) | ||
108 | } | ||
109 | |||
110 | func BytesSlice(buf cty.Value, offset cty.Value, length cty.Value) (cty.Value, error) { | ||
111 | return BytesSliceFunc.Call([]cty.Value{buf, offset, length}) | ||
112 | } | ||