diff --git a/.gitignore b/.gitignore index c795b05..0664ec5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -build \ No newline at end of file +build +coverage* \ No newline at end of file diff --git a/bundle.go b/bundle.go index 68eb56b..022d8e7 100644 --- a/bundle.go +++ b/bundle.go @@ -4,21 +4,32 @@ import ( "errors" ) -func (b *OSCBundle) ToBytes() []byte { +func (b *OSCBundle) ToBytes() ([]byte, error) { bytes := stringToOSCBytes("#bundle") - bytes = append(bytes, timeTagToOSCBytes(b.TimeTag)...) + timeTagBytes, err := timeTagToOSCBytes(b.TimeTag) + if err != nil { + return nil, err + } + bytes = append(bytes, timeTagBytes...) for _, packet := range b.Contents { - packetBytes := packet.ToBytes() - packetLength := len(packet.ToBytes()) + packetBytes, err := packet.ToBytes() + if err != nil { + return nil, err + } + packetLength := len(packetBytes) - bytes = append(bytes, int32ToOSCBytes(int32(packetLength))...) + packetLengthBytes, err := int32ToOSCBytes(int32(packetLength)) + if err != nil { + return nil, err + } + bytes = append(bytes, packetLengthBytes...) bytes = append(bytes, packetBytes...) } - return bytes + return bytes, nil } func BundleFromBytes(bytes []byte) (*OSCBundle, []byte, error) { diff --git a/bundle_test.go b/bundle_test.go index 8a808eb..66e31ce 100644 --- a/bundle_test.go +++ b/bundle_test.go @@ -9,9 +9,9 @@ import ( func TestOSCBundleEncoding(t *testing.T) { testCases := []struct { - description string - bundle *OSCBundle - expected []byte + name string + bundle *OSCBundle + expected []byte }{ { "simple contents single message", @@ -32,13 +32,19 @@ func TestOSCBundleEncoding(t *testing.T) { for _, testCase := range testCases { - actual := testCase.bundle.ToBytes() + t.Run(testCase.name, func(t *testing.T) { + + got, err := testCase.bundle.ToBytes() + + if err != nil { + t.Fatalf("failed to encode properly: %s", err.Error()) + } + + if !reflect.DeepEqual(got, testCase.expected) { + t.Fatalf("failed to encode properly got '%v', expected '%v'", got, testCase.expected) + } + }) - if !reflect.DeepEqual(actual, testCase.expected) { - t.Errorf("Test '%s' failed to encode properly", testCase.description) - fmt.Printf("expected: %v\n", testCase.expected) - fmt.Printf("actual: %v\n", actual) - } } } diff --git a/cmd/makeosc/makeosc.go b/cmd/makeosc/makeosc.go index 5772cea..76c26a1 100644 --- a/cmd/makeosc/makeosc.go +++ b/cmd/makeosc/makeosc.go @@ -175,7 +175,10 @@ func make(address string, args []string, types []string, slip bool) { oscMessage.Args = append(oscMessage.Args, argToTypedArg(arg, oscType)) } - oscMessageBuffer := oscMessage.ToBytes() + oscMessageBuffer, err := oscMessage.ToBytes() + if err != nil { + panic(err) + } if slip { oscMessageBuffer = slipEncode(oscMessageBuffer) diff --git a/cmd/sendosc/sendosc.go b/cmd/sendosc/sendosc.go index 6e45d2f..88e4643 100644 --- a/cmd/sendosc/sendosc.go +++ b/cmd/sendosc/sendosc.go @@ -208,7 +208,10 @@ func send(host string, port int32, address string, args []string, types []string } - oscMessageBuffer := oscMessage.ToBytes() + oscMessageBuffer, err := oscMessage.ToBytes() + if err != nil { + panic(err) + } if slip { oscMessageBuffer = slipEncode(oscMessageBuffer) diff --git a/message.go b/message.go index bd0051f..f37e0e3 100644 --- a/message.go +++ b/message.go @@ -5,7 +5,7 @@ import ( "strings" ) -func (m *OSCMessage) ToBytes() []byte { +func (m *OSCMessage) ToBytes() ([]byte, error) { //TODO(jwetzell): add error handling oscBuffer := []byte{} @@ -20,9 +20,13 @@ func (m *OSCMessage) ToBytes() []byte { } oscBuffer = append(oscBuffer, stringToOSCBytes(sb.String())...) - oscBuffer = append(oscBuffer, argsToBuffer(m.Args)...) + argsBuffer, err := argsToBuffer(m.Args) + if err != nil { + return nil, err + } + oscBuffer = append(oscBuffer, argsBuffer...) - return oscBuffer + return oscBuffer, nil } func MessageFromBytes(bytes []byte) (*OSCMessage, error) { diff --git a/message_test.go b/message_test.go index 0a5fb44..e163f0e 100644 --- a/message_test.go +++ b/message_test.go @@ -128,10 +128,14 @@ func TestGoodOSCMessageEncoding(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - actual := testCase.message.ToBytes() + got, err := testCase.message.ToBytes() - if !reflect.DeepEqual(actual, testCase.expected) { - t.Fatalf("failed to encode properly got '%v', expected '%v'", actual, testCase.expected) + if err != nil { + t.Fatalf("failed to encode properly: %s", err.Error()) + } + + if !reflect.DeepEqual(got, testCase.expected) { + t.Fatalf("failed to encode properly got '%v', expected '%v'", got, testCase.expected) } }) } diff --git a/osc.go b/osc.go index 3b80921..e0be749 100644 --- a/osc.go +++ b/osc.go @@ -26,47 +26,51 @@ func stringToOSCBytes(rawString string) []byte { return []byte(sb.String()) } -func int32ToOSCBytes(number int32) []byte { +func int32ToOSCBytes(number int32) ([]byte, error) { var buf bytes.Buffer err := binary.Write(&buf, binary.BigEndian, number) if err != nil { - panic(err) + return nil, err } - return buf.Bytes() + return buf.Bytes(), nil } -func int64ToOSCBytes(number int64) []byte { +func int64ToOSCBytes(number int64) ([]byte, error) { var buf bytes.Buffer err := binary.Write(&buf, binary.BigEndian, number) if err != nil { - panic(err) + return nil, err } - return buf.Bytes() + return buf.Bytes(), nil } -func float32ToOSCBytes(number float32) []byte { +func float32ToOSCBytes(number float32) ([]byte, error) { var buf bytes.Buffer err := binary.Write(&buf, binary.BigEndian, number) if err != nil { - panic(err) + return nil, err } - return buf.Bytes() + return buf.Bytes(), nil } -func float64ToOSCBytes(number float64) []byte { +func float64ToOSCBytes(number float64) ([]byte, error) { var buf bytes.Buffer err := binary.Write(&buf, binary.BigEndian, number) if err != nil { - panic(err) + return nil, err } - return buf.Bytes() + return buf.Bytes(), nil } -func byteArrayToOSCBytes(bytes []byte) []byte { +func byteArrayToOSCBytes(bytes []byte) ([]byte, error) { oscBytes := []byte{} bytesSize := len(bytes) - oscBytes = append(oscBytes, int32ToOSCBytes(int32(bytesSize))...) + bytesSizeBytes, err := int32ToOSCBytes(int32(bytesSize)) + if err != nil { + return nil, err + } + oscBytes = append(oscBytes, bytesSizeBytes...) oscBytes = append(oscBytes, bytes...) padLength := 4 - (bytesSize % 4) @@ -76,17 +80,24 @@ func byteArrayToOSCBytes(bytes []byte) []byte { } } - return oscBytes + return oscBytes, nil } -func timeTagToOSCBytes(timeTag OSCTimeTag) []byte { - timeTagBytes := int32ToOSCBytes(timeTag.seconds) - timeTagBytes = append(timeTagBytes, int32ToOSCBytes(timeTag.fractionalSeconds)...) +func timeTagToOSCBytes(timeTag OSCTimeTag) ([]byte, error) { + timeTagBytes, err := int32ToOSCBytes(timeTag.seconds) + if err != nil { + return nil, err + } + fractionalSecondsBytes, err := int32ToOSCBytes(timeTag.fractionalSeconds) + if err != nil { + return nil, err + } + timeTagBytes = append(timeTagBytes, fractionalSecondsBytes...) - return timeTagBytes + return timeTagBytes, nil } -func argsToBuffer(args []OSCArg) []byte { +func argsToBuffer(args []OSCArg) ([]byte, error) { //TODO(jwetzell): add error handling var argBuffers = []byte{} @@ -100,29 +111,61 @@ func argsToBuffer(args []OSCArg) []byte { } case "i": if value, ok := arg.Value.(int); ok { - argBuffers = append(argBuffers, int32ToOSCBytes(int32(value))...) + valueBytes, err := int32ToOSCBytes(int32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int32); ok { - argBuffers = append(argBuffers, int32ToOSCBytes(value)...) + valueBytes, err := int32ToOSCBytes(int32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else { fmt.Println("OSC arg had integer type but non-integer value.") } case "f": if value, ok := arg.Value.(float32); ok { - argBuffers = append(argBuffers, float32ToOSCBytes(float32(value))...) + valueBytes, err := float32ToOSCBytes(value) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(float64); ok { - argBuffers = append(argBuffers, float32ToOSCBytes(float32(value))...) + valueBytes, err := float32ToOSCBytes(float32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int); ok { - argBuffers = append(argBuffers, float32ToOSCBytes(float32(value))...) + valueBytes, err := float32ToOSCBytes(float32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int32); ok { - argBuffers = append(argBuffers, float32ToOSCBytes(float32(value))...) + valueBytes, err := float32ToOSCBytes(float32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int64); ok { - argBuffers = append(argBuffers, float32ToOSCBytes(float32(value))...) + valueBytes, err := float32ToOSCBytes(float32(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else { fmt.Println("OSC arg had float type but non-float value.") } case "b": if value, ok := arg.Value.([]byte); ok { - argBuffers = append(argBuffers, byteArrayToOSCBytes(value)...) + valueBytes, err := byteArrayToOSCBytes(value) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else { fmt.Println("OSC arg had blob type but non-blob value.") } @@ -142,25 +185,57 @@ func argsToBuffer(args []OSCArg) []byte { } case "h": if value, ok := arg.Value.(int); ok { - argBuffers = append(argBuffers, int64ToOSCBytes(int64(value))...) + valueBytes, err := int64ToOSCBytes(int64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int32); ok { - argBuffers = append(argBuffers, int64ToOSCBytes(int64(value))...) + valueBytes, err := int64ToOSCBytes(int64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int64); ok { - argBuffers = append(argBuffers, int64ToOSCBytes(value)...) + valueBytes, err := int64ToOSCBytes(value) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else { fmt.Println("OSC arg had integer type but non-integer value.") } case "d": if value, ok := arg.Value.(float32); ok { - argBuffers = append(argBuffers, float64ToOSCBytes(float64(value))...) + valueBytes, err := float64ToOSCBytes(float64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(float64); ok { - argBuffers = append(argBuffers, float64ToOSCBytes(float64(value))...) + valueBytes, err := float64ToOSCBytes(value) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int); ok { - argBuffers = append(argBuffers, float64ToOSCBytes(float64(value))...) + valueBytes, err := float64ToOSCBytes(float64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int32); ok { - argBuffers = append(argBuffers, float64ToOSCBytes(float64(value))...) + valueBytes, err := float64ToOSCBytes(float64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else if value, ok := arg.Value.(int64); ok { - argBuffers = append(argBuffers, float64ToOSCBytes(float64(value))...) + valueBytes, err := float64ToOSCBytes(float64(value)) + if err != nil { + return nil, err + } + argBuffers = append(argBuffers, valueBytes...) } else { fmt.Println("OSC arg had float type but non-float value.") } @@ -168,7 +243,7 @@ func argsToBuffer(args []OSCArg) []byte { fmt.Printf("unhandled osc type: %s.\n", oscType) } } - return argBuffers + return argBuffers, nil } func readOSCString(bytes []byte) (string, []byte, error) { diff --git a/types.go b/types.go index 482fe7d..c6f47fa 100644 --- a/types.go +++ b/types.go @@ -1,7 +1,7 @@ package osc type OSCPacket interface { - ToBytes() []byte + ToBytes() ([]byte, error) } type OSCBundle struct {