From b2b34217111b014adb22fa992d96f52aefea654d Mon Sep 17 00:00:00 2001 From: Brad Moylan Date: Thu, 10 Jan 2019 09:30:45 -0800 Subject: [PATCH] Add binary package for base64 encoding (#137) --- binary/binary.go | 45 ++++++++++++++++++++++++++++++++++ binary/binary_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 binary/binary.go create mode 100644 binary/binary_test.go diff --git a/binary/binary.go b/binary/binary.go new file mode 100644 index 00000000..7877f97b --- /dev/null +++ b/binary/binary.go @@ -0,0 +1,45 @@ +// Copyright (c) 2018 Palantir Technologies. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package binary + +import ( + "encoding/base64" +) + +var b64 = base64.StdEncoding + +// Binary wraps binary data and provides encoding helpers using base64.StdEncoding. +// Use this type for binary fields serialized/deserialized as base64 text. +// Type is specified as string rather than []byte so that it can be used as a map key. +// Use Bytes() to access the raw bytes. +// Values of this type are only valid when the backing string is Base64-encoded using standard encoding. +type Binary string + +func New(data []byte) Binary { + return Binary(b64.EncodeToString(data)) +} + +func (b Binary) Bytes() ([]byte, error) { + return b64.DecodeString(string(b)) +} + +func (b Binary) MarshalText() (text []byte, err error) { + // Verify that data is base64-encoded + if _, err := b.Bytes(); err != nil { + return nil, err + } + + return []byte(b), nil +} + +func (b *Binary) UnmarshalText(data []byte) error { + // Verify that data is base64-encoded + if _, err := Binary(data).Bytes(); err != nil { + return err + } + + *b = Binary(data) + return nil +} diff --git a/binary/binary_test.go b/binary/binary_test.go new file mode 100644 index 00000000..875edaa9 --- /dev/null +++ b/binary/binary_test.go @@ -0,0 +1,57 @@ +// Copyright (c) 2018 Palantir Technologies. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package binary_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/palantir/pkg/binary" +) + +func TestBinary_Marshal(t *testing.T) { + for _, test := range []struct { + Name string + Input []byte + Output []byte + }{ + { + Name: "hello world", + Input: []byte(`hello world`), + Output: []byte(`"aGVsbG8gd29ybGQ="`), + }, + } { + t.Run(test.Name, func(t *testing.T) { + out, err := json.Marshal(binary.New(test.Input)) + assert.NoError(t, err) + assert.Equal(t, string(test.Output), string(out)) + }) + } +} + +func TestBinary_Unmarshal(t *testing.T) { + for _, test := range []struct { + Name string + Input []byte + Output []byte + }{ + { + Name: "hello world", + Input: []byte(`"aGVsbG8gd29ybGQ="`), + Output: []byte(`hello world`), + }, + } { + t.Run(test.Name, func(t *testing.T) { + var bin binary.Binary + err := json.Unmarshal(test.Input, &bin) + assert.NoError(t, err) + bytes, err := bin.Bytes() + assert.NoError(t, err) + assert.Equal(t, string(test.Output), string(bytes)) + }) + } +}