Skip to content

Commit

Permalink
Add package pkg/io and pkg/safecast
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasgeihs committed Oct 6, 2021
1 parent 7df16c4 commit d39918c
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
41 changes: 41 additions & 0 deletions pkg/io/io.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2021 PolyCrypt GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package io

import (
"fmt"
"io"

"github.com/perun-network/perun-cosmwasm-backend/pkg/safecast"
pio "perun.network/go-perun/pkg/io"
)

// WriteBytesUint16 writes the uint16-length-encoded byte slice to the stream.
func WriteBytesUint16(w io.Writer, a []byte) error {
l := safecast.Uint16FromInt(len(a))
return pio.Encode(w, l, a)
}

// ReadBytesUint16 reads an uint16-length-encoded byte slice from the stream.
func ReadBytesUint16(r io.Reader, a *[]byte) error {
var l uint16
err := pio.Decode(r, &l)
if err != nil {
return fmt.Errorf("reading length: %w", err)
}

*a = make([]byte, l)
return pio.Decode(r, a)
}
49 changes: 49 additions & 0 deletions pkg/io/io_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2021 PolyCrypt GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package io_test

import (
"bytes"
"math/rand"
"testing"

"github.com/perun-network/perun-cosmwasm-backend/pkg/io"
)

func TestReadWriteBytesUint16(t *testing.T) {
// Generate random byte slice with uint16 length.
l := rand.Intn(1 << 16)
b := make([]byte, l)
_, err := rand.Read(b)
if err != nil {
panic(err)
}

var buf bytes.Buffer
err = io.WriteBytesUint16(&buf, b)
if err != nil {
t.Fatalf("writing: %v", err)
}

_b := make([]byte, len(b))
err = io.ReadBytesUint16(&buf, &_b)
if err != nil {
t.Fatalf("reading: %v", err)
}

if !bytes.Equal(b, _b) {
t.Errorf("no equal: %v, %v", b, _b)
}
}
33 changes: 33 additions & 0 deletions pkg/safecast/safecast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2021 PolyCrypt GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package safecast

// Uint16FromInt converts an int into an uint16 and panics if the value overflows.
func Uint16FromInt(a int) uint16 {
b := uint16(a)
if a != int(b) {
panic("unsafe")
}
return b
}

// Int64FromUint64 converts an uint64 into an int64 and panics if the value overflows.
func Int64FromUint64(a uint64) int64 {
b := int64(a)
if b < 0 {
panic("unsafe")
}
return b
}
80 changes: 80 additions & 0 deletions pkg/safecast/safecast_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2021 PolyCrypt GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package safecast_test

import (
"math/rand"
"testing"

"github.com/perun-network/perun-cosmwasm-backend/pkg/safecast"
)

func TestUint16FromInt(t *testing.T) {
// Test valid input: Correct result, no panic.
func() {
defer func() {
if err := recover(); err != nil {
t.Errorf("casting valid value should not panic: %v", err)
}
}()

i := rand.Intn(1 << 16)
_i := safecast.Uint16FromInt(i)
if i != int(_i) {
t.Errorf("values should be equal: %v, %v", i, _i)
}
}()

// Test invalid input: Panic.
func() {
defer func() {
if err := recover(); err == nil {
t.Errorf("casting invalid value should panic")
}
}()

i := 1 << 16
_ = safecast.Uint16FromInt(i)
}()
}

func TestInt64FromUint64(t *testing.T) {
// Test valid input: Correct result, no panic.
func() {
defer func() {
if err := recover(); err != nil {
t.Errorf("casting valid value should not panic: %v", err)
}
}()

i := uint64(rand.Int63())
_i := safecast.Int64FromUint64(i)
if i != uint64(_i) {
t.Errorf("values should be equal: %v, %v", i, _i)
}
}()

// Test invalid input: Panic.
func() {
defer func() {
if err := recover(); err == nil {
t.Errorf("casting invalid value should panic")
}
}()

i := uint64(1<<63) + 1
_ = safecast.Int64FromUint64(i)
}()
}

0 comments on commit d39918c

Please sign in to comment.