Skip to content

Commit 0a2df12

Browse files
committed
rewrote arguments
1 parent e55a38f commit 0a2df12

13 files changed

+755
-648
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
@go test -coverprofile cover.out
3+
4+
.PHONY: test

argument.go

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package osc
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"fmt"
7+
"io"
8+
)
9+
10+
// Argument represents an OSC argument.
11+
// An OSC argument can have many different types, which is why
12+
// we choose to represent them with an interface.
13+
type Argument interface {
14+
io.WriterTo
15+
16+
ReadInt32() (int32, error)
17+
ReadFloat32() (float32, error)
18+
ReadBool() (bool, error)
19+
ReadString() (string, error)
20+
ReadBlob() ([]byte, error)
21+
Typetag() byte
22+
}
23+
24+
// Int represents a 32-bit integer.
25+
type Int int32
26+
27+
// ReadInt32 reads a 32-bit integer from the arg.
28+
func (i Int) ReadInt32() (int32, error) { return int32(i), nil }
29+
30+
// ReadFloat32 reads a 32-bit float from the arg.
31+
func (i Int) ReadFloat32() (float32, error) { return 0, ErrInvalidTypeTag }
32+
33+
// ReadBool bool reads a boolean from the arg.
34+
func (i Int) ReadBool() (bool, error) { return false, ErrInvalidTypeTag }
35+
36+
// ReadString string reads a string from the arg.
37+
func (i Int) ReadString() (string, error) { return "", ErrInvalidTypeTag }
38+
39+
// ReadBlob reads a slice of bytes from the arg.
40+
func (i Int) ReadBlob() ([]byte, error) { return nil, ErrInvalidTypeTag }
41+
42+
// Typetag returns the argument's type tag.
43+
func (i Int) Typetag() byte { return TypetagInt }
44+
45+
// WriteTo writes the arg to an io.Writer.
46+
func (i Int) WriteTo(w io.Writer) (int64, error) {
47+
written, err := fmt.Fprintf(w, "%d", i)
48+
return int64(written), err
49+
}
50+
51+
// Float represents a 32-bit float.
52+
type Float float32
53+
54+
// ReadInt32 reads a 32-bit integer from the arg.
55+
func (f Float) ReadInt32() (int32, error) { return 0, ErrInvalidTypeTag }
56+
57+
// ReadFloat32 reads a 32-bit float from the arg.
58+
func (f Float) ReadFloat32() (float32, error) { return float32(f), nil }
59+
60+
// ReadBool bool reads a boolean from the arg.
61+
func (f Float) ReadBool() (bool, error) { return false, ErrInvalidTypeTag }
62+
63+
// ReadString string reads a string from the arg.
64+
func (f Float) ReadString() (string, error) { return "", ErrInvalidTypeTag }
65+
66+
// ReadBlob reads a slice of bytes from the arg.
67+
func (f Float) ReadBlob() ([]byte, error) { return nil, ErrInvalidTypeTag }
68+
69+
// Typetag returns the argument's type tag.
70+
func (f Float) Typetag() byte { return TypetagFloat }
71+
72+
// WriteTo writes the arg to an io.Writer.
73+
func (f Float) WriteTo(w io.Writer) (int64, error) {
74+
written, err := fmt.Fprintf(w, "%f", f)
75+
return int64(written), err
76+
}
77+
78+
// Bool represents a boolean value.
79+
type Bool bool
80+
81+
// ReadInt32 reads a 32-bit integer from the arg.
82+
func (b Bool) ReadInt32() (int32, error) { return 0, ErrInvalidTypeTag }
83+
84+
// ReadFloat32 reads a 32-bit float from the arg.
85+
func (b Bool) ReadFloat32() (float32, error) { return 0, ErrInvalidTypeTag }
86+
87+
// ReadBool bool reads a boolean from the arg.
88+
func (b Bool) ReadBool() (bool, error) { return bool(b), nil }
89+
90+
// ReadString string reads a string from the arg.
91+
func (b Bool) ReadString() (string, error) { return "", ErrInvalidTypeTag }
92+
93+
// ReadBlob reads a slice of bytes from the arg.
94+
func (b Bool) ReadBlob() ([]byte, error) { return nil, ErrInvalidTypeTag }
95+
96+
// Typetag returns the argument's type tag.
97+
func (b Bool) Typetag() byte {
98+
if bool(b) {
99+
return TypetagTrue
100+
}
101+
return TypetagFalse
102+
}
103+
104+
// WriteTo writes the arg to an io.Writer.
105+
func (b Bool) WriteTo(w io.Writer) (int64, error) {
106+
written, err := fmt.Fprintf(w, "%t", b)
107+
return int64(written), err
108+
}
109+
110+
// String is a string.
111+
type String string
112+
113+
// ReadInt32 reads a 32-bit integer from the arg.
114+
func (s String) ReadInt32() (int32, error) { return 0, ErrInvalidTypeTag }
115+
116+
// ReadFloat32 reads a 32-bit float from the arg.
117+
func (s String) ReadFloat32() (float32, error) { return 0, ErrInvalidTypeTag }
118+
119+
// ReadBool bool reads a boolean from the arg.
120+
func (s String) ReadBool() (bool, error) { return false, ErrInvalidTypeTag }
121+
122+
// ReadString string reads a string from the arg.
123+
func (s String) ReadString() (string, error) { return string(s), nil }
124+
125+
// ReadBlob reads a slice of bytes from the arg.
126+
func (s String) ReadBlob() ([]byte, error) { return nil, ErrInvalidTypeTag }
127+
128+
// Typetag returns the argument's type tag.
129+
func (s String) Typetag() byte { return TypetagString }
130+
131+
// WriteTo writes the arg to an io.Writer.
132+
func (s String) WriteTo(w io.Writer) (int64, error) {
133+
written, err := fmt.Fprintf(w, "%s", s)
134+
return int64(written), err
135+
}
136+
137+
// Blob is a slice of bytes.
138+
type Blob []byte
139+
140+
// ReadInt32 reads a 32-bit integer from the arg.
141+
func (b Blob) ReadInt32() (int32, error) { return 0, ErrInvalidTypeTag }
142+
143+
// ReadFloat32 reads a 32-bit float from the arg.
144+
func (b Blob) ReadFloat32() (float32, error) { return 0, ErrInvalidTypeTag }
145+
146+
// ReadBool bool reads a boolean from the arg.
147+
func (b Blob) ReadBool() (bool, error) { return false, ErrInvalidTypeTag }
148+
149+
// ReadString string reads a string from the arg.
150+
func (b Blob) ReadString() (string, error) { return "", ErrInvalidTypeTag }
151+
152+
// ReadBlob reads a slice of bytes from the arg.
153+
func (b Blob) ReadBlob() ([]byte, error) { return []byte(b), nil }
154+
155+
// Typetag returns the argument's type tag.
156+
func (b Blob) Typetag() byte { return TypetagBlob }
157+
158+
// WriteTo writes the arg to an io.Writer.
159+
func (b Blob) WriteTo(w io.Writer) (int64, error) {
160+
written, err := w.Write([]byte(b))
161+
return int64(written), err
162+
}
163+
164+
// ParseArgument parses an OSC message argument given a type tag and some data.
165+
func ParseArgument(tt byte, data []byte) (Argument, int64, error) {
166+
switch tt {
167+
case TypetagInt:
168+
var val int32
169+
if err := binary.Read(bytes.NewReader(data), byteOrder, &val); err != nil {
170+
return nil, 0, err
171+
}
172+
return Int(val), 4, nil
173+
case TypetagFloat:
174+
var val float32
175+
if err := binary.Read(bytes.NewReader(data), byteOrder, &val); err != nil {
176+
return nil, 0, err
177+
}
178+
return Float(val), 4, nil
179+
case TypetagTrue:
180+
return Bool(true), 0, nil
181+
case TypetagFalse:
182+
return Bool(false), 0, nil
183+
case TypetagString:
184+
s, idx := ReadString(data)
185+
return String(s), idx, nil
186+
case TypetagBlob:
187+
var length int32
188+
if err := binary.Read(bytes.NewReader(data), byteOrder, &length); err != nil {
189+
return nil, 0, err
190+
}
191+
b, bl := ReadBlob(length, data)
192+
return Blob(b), bl, nil
193+
default:
194+
return nil, 0, fmt.Errorf("unrecognized type tag: %c", tt)
195+
}
196+
}

argument_test.go

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package osc
2+
3+
import (
4+
"bytes"
5+
"io/ioutil"
6+
"testing"
7+
)
8+
9+
func TestInt(t *testing.T) {
10+
arg := Int(0)
11+
i, err := arg.ReadInt32()
12+
if err != nil {
13+
t.Fatal(err)
14+
}
15+
if expected, got := int32(0), i; expected != got {
16+
t.Fatalf("expected %d, got %d", expected, got)
17+
}
18+
if _, err := arg.ReadFloat32(); err != ErrInvalidTypeTag {
19+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
20+
}
21+
if _, err := arg.ReadBool(); err != ErrInvalidTypeTag {
22+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
23+
}
24+
if _, err := arg.ReadString(); err != ErrInvalidTypeTag {
25+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
26+
}
27+
if _, err := arg.ReadBlob(); err != ErrInvalidTypeTag {
28+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
29+
}
30+
if expected, got := TypetagInt, arg.Typetag(); expected != got {
31+
t.Fatalf("expected %c, got %c", expected, got)
32+
}
33+
if _, err := arg.WriteTo(ioutil.Discard); err != nil {
34+
t.Fatal(err)
35+
}
36+
}
37+
38+
func TestFloat(t *testing.T) {
39+
arg := Float(0)
40+
f, err := arg.ReadFloat32()
41+
if err != nil {
42+
t.Fatal(err)
43+
}
44+
if expected, got := float32(0), f; expected != got {
45+
t.Fatalf("expected %f, got %f", expected, got)
46+
}
47+
if _, err := arg.ReadInt32(); err != ErrInvalidTypeTag {
48+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
49+
}
50+
if _, err := arg.ReadBool(); err != ErrInvalidTypeTag {
51+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
52+
}
53+
if _, err := arg.ReadString(); err != ErrInvalidTypeTag {
54+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
55+
}
56+
if _, err := arg.ReadBlob(); err != ErrInvalidTypeTag {
57+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
58+
}
59+
if expected, got := TypetagFloat, arg.Typetag(); expected != got {
60+
t.Fatalf("expected %c, got %c", expected, got)
61+
}
62+
if _, err := arg.WriteTo(ioutil.Discard); err != nil {
63+
t.Fatal(err)
64+
}
65+
}
66+
67+
func TestBool(t *testing.T) {
68+
arg := Bool(false)
69+
b, err := arg.ReadBool()
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
if expected, got := false, b; expected != got {
74+
t.Fatalf("expected %f, got %f", expected, got)
75+
}
76+
if _, err := arg.ReadInt32(); err != ErrInvalidTypeTag {
77+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
78+
}
79+
if _, err := arg.ReadFloat32(); err != ErrInvalidTypeTag {
80+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
81+
}
82+
if _, err := arg.ReadString(); err != ErrInvalidTypeTag {
83+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
84+
}
85+
if _, err := arg.ReadBlob(); err != ErrInvalidTypeTag {
86+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
87+
}
88+
if expected, got := TypetagFalse, arg.Typetag(); expected != got {
89+
t.Fatalf("expected %c, got %c", expected, got)
90+
}
91+
92+
argTrue := Bool(true)
93+
if expected, got := TypetagTrue, argTrue.Typetag(); expected != got {
94+
t.Fatalf("expected %c, got %c", expected, got)
95+
}
96+
97+
if _, err := arg.WriteTo(ioutil.Discard); err != nil {
98+
t.Fatal(err)
99+
}
100+
}
101+
102+
func TestString(t *testing.T) {
103+
arg := String("foo")
104+
s, err := arg.ReadString()
105+
if err != nil {
106+
t.Fatal(err)
107+
}
108+
if expected, got := "foo", s; expected != got {
109+
t.Fatalf("expected %f, got %f", expected, got)
110+
}
111+
if _, err := arg.ReadInt32(); err != ErrInvalidTypeTag {
112+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
113+
}
114+
if _, err := arg.ReadFloat32(); err != ErrInvalidTypeTag {
115+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
116+
}
117+
if _, err := arg.ReadBool(); err != ErrInvalidTypeTag {
118+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
119+
}
120+
if _, err := arg.ReadBlob(); err != ErrInvalidTypeTag {
121+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
122+
}
123+
if expected, got := TypetagString, arg.Typetag(); expected != got {
124+
t.Fatalf("expected %c, got %c", expected, got)
125+
}
126+
if _, err := arg.WriteTo(ioutil.Discard); err != nil {
127+
t.Fatal(err)
128+
}
129+
}
130+
131+
func TestBlob(t *testing.T) {
132+
arg := Blob([]byte{'f', 'o', 'o'})
133+
b, err := arg.ReadBlob()
134+
if err != nil {
135+
t.Fatal(err)
136+
}
137+
if expected, got := []byte{'f', 'o', 'o'}, b; !bytes.Equal(expected, got) {
138+
t.Fatalf("expected %f, got %f", expected, got)
139+
}
140+
if _, err := arg.ReadInt32(); err != ErrInvalidTypeTag {
141+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
142+
}
143+
if _, err := arg.ReadFloat32(); err != ErrInvalidTypeTag {
144+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
145+
}
146+
if _, err := arg.ReadBool(); err != ErrInvalidTypeTag {
147+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
148+
}
149+
if _, err := arg.ReadString(); err != ErrInvalidTypeTag {
150+
t.Fatalf("expected ErrInvalidTypeTag, got %+v", err)
151+
}
152+
if expected, got := TypetagBlob, arg.Typetag(); expected != got {
153+
t.Fatalf("expected %c, got %c", expected, got)
154+
}
155+
if _, err := arg.WriteTo(ioutil.Discard); err != nil {
156+
t.Fatal(err)
157+
}
158+
}
159+
160+
func TestParseArgument(t *testing.T) {
161+
}

bundle.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,13 @@ ReadPackets:
154154
for err := binary.Read(r, byteOrder, &size); err == nil; err = binary.Read(r, byteOrder, &size) {
155155
i += 4
156156
switch data[i] {
157-
case messageChar:
157+
case MessageChar:
158158
pkt, err := parseMessage(data[i:], sender)
159159
if err != nil {
160160
return nil, err
161161
}
162162
b.Packets = append(b.Packets, pkt)
163-
case bundleChar:
163+
case BundleTag[0]:
164164
pkt, err := parseBundle(data[i:], sender)
165165
if err != nil {
166166
return nil, err

0 commit comments

Comments
 (0)