summaryrefslogtreecommitdiff
path: root/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil')
-rw-r--r--vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go
new file mode 100644
index 000000000..a0a0c94c6
--- /dev/null
+++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go
@@ -0,0 +1,66 @@
+// Package msgutil provides utility for JSON message with uint32le header
+package msgutil
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "io"
+
+ "github.com/pkg/errors"
+)
+
+const (
+ maxLength = 1 << 16
+)
+
+func MarshalToWriter(w io.Writer, x interface{}) (int, error) {
+ b, err := json.Marshal(x)
+ if err != nil {
+ return 0, err
+ }
+ if len(b) > maxLength {
+ return 0, errors.Errorf("bad message length: %d (max: %d)", len(b), maxLength)
+ }
+ h := make([]byte, 4)
+ binary.LittleEndian.PutUint32(h, uint32(len(b)))
+ return w.Write(append(h, b...))
+}
+
+func UnmarshalFromReader(r io.Reader, x interface{}) (int, error) {
+ hdr := make([]byte, 4)
+ n, err := r.Read(hdr)
+ if err != nil {
+ return n, err
+ }
+ if n != 4 {
+ return n, errors.Errorf("read %d bytes, expected 4 bytes", n)
+ }
+ bLen := binary.LittleEndian.Uint32(hdr)
+ if bLen > maxLength || bLen < 1 {
+ return n, errors.Errorf("bad message length: %d (max: %d)", bLen, maxLength)
+ }
+ b := make([]byte, bLen)
+ n, err = r.Read(b)
+ if err != nil {
+ return 4 + n, err
+ }
+ if n != int(bLen) {
+ return 4 + n, errors.Errorf("read %d bytes, expected %d bytes", n, bLen)
+ }
+ return 4 + n, json.Unmarshal(b, x)
+}
+
+func Marshal(x interface{}) ([]byte, error) {
+ var b bytes.Buffer
+ _, err := MarshalToWriter(&b, x)
+ return b.Bytes(), err
+}
+
+func Unmarshal(b []byte, x interface{}) error {
+ n, err := UnmarshalFromReader(bytes.NewReader(b), x)
+ if n != len(b) {
+ return errors.Errorf("read %d bytes, expected %d bytes", n, len(b))
+ }
+ return err
+}