Skip to content

Commit 46f6da0

Browse files
committedMar 7, 2024
Add UnmarshalString
Before ''' 2512 B/op 83 allocs/op ''' After ''' 2016 B/op 47 allocs/op '''
1 parent adf8269 commit 46f6da0

File tree

6 files changed

+26
-21
lines changed

6 files changed

+26
-21
lines changed
 

‎base_lexer.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ func (e syntaxError) Error() string {
2525
}
2626

2727
type baseLexer struct {
28-
value []byte
28+
value string
2929
pos int
3030
}
3131

3232
func (l baseLexer) syntaxError() error {
33-
return syntaxError{s: string(l.value), i: l.pos - 1}
33+
return syntaxError{s: l.value, i: l.pos - 1}
3434
}
3535

3636
func (l *baseLexer) unreadByte() error {
@@ -157,7 +157,7 @@ func (l *baseLexer) readField() (string, error) {
157157
break
158158
}
159159
}
160-
return string(l.value[start:stop]), nil
160+
return l.value[start:stop], nil
161161
}
162162

163163
// Returns symbols until line end
@@ -173,7 +173,7 @@ func (l *baseLexer) readLine() (string, error) {
173173
trim++
174174
}
175175
if ch == '\n' {
176-
return string(l.value[start : l.pos-trim]), nil
176+
return l.value[start : l.pos-trim], nil
177177
}
178178
}
179179
}

‎base_lexer_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestLexer(t *testing.T) {
1616
"with linebreak": "aaa \n",
1717
"with linebreak 2": "aaa \r\n",
1818
} {
19-
l := &baseLexer{value: []byte(value)}
19+
l := &baseLexer{value: value}
2020
field, err := l.readField()
2121
if err != nil {
2222
t.Fatal(err)
@@ -28,7 +28,7 @@ func TestLexer(t *testing.T) {
2828
})
2929

3030
t.Run("syntax error", func(t *testing.T) {
31-
l := &baseLexer{value: []byte("12NaN")}
31+
l := &baseLexer{value: "12NaN"}
3232
_, err := l.readUint64Field()
3333
if err != nil {
3434
fmt.Println("error message:", err.Error())
@@ -38,7 +38,7 @@ func TestLexer(t *testing.T) {
3838
})
3939

4040
t.Run("many fields", func(t *testing.T) {
41-
l := &baseLexer{value: []byte("aaa 123\nf1 f2\nlast")}
41+
l := &baseLexer{value: "aaa 123\nf1 f2\nlast"}
4242

4343
t.Run("first line", func(t *testing.T) {
4444
field, err := l.readField()

‎fuzz_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ package sdp
66
import "testing"
77

88
func FuzzUnmarshal(f *testing.F) {
9-
f.Add([]byte{})
10-
f.Add([]byte(CanonicalUnmarshalSDP))
11-
f.Fuzz(func(t *testing.T, data []byte) {
9+
f.Add("")
10+
f.Add(CanonicalUnmarshalSDP)
11+
f.Fuzz(func(t *testing.T, data string) {
1212
// Check that unmarshalling any byte slice does not panic.
1313
var sd SessionDescription
14-
if err := sd.Unmarshal(data); err != nil {
14+
if err := sd.UnmarshalString(data); err != nil {
1515
return
1616
}
1717
// Check that we can marshal anything we unmarshalled.

‎marshal_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func TestMarshalCanonical(t *testing.T) {
177177
func BenchmarkMarshal(b *testing.B) {
178178
b.ReportAllocs()
179179
var sd SessionDescription
180-
err := sd.Unmarshal([]byte(CanonicalUnmarshalSDP))
180+
err := sd.UnmarshalString(CanonicalUnmarshalSDP)
181181
if err != nil {
182182
b.Fatal(err)
183183
}

‎unmarshal.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var (
1818
errSDPInvalidPortValue = errors.New("sdp: invalid port value")
1919
)
2020

21-
// Unmarshal is the primary function that deserializes the session description
21+
// UnmarshalString is the primary function that deserializes the session description
2222
// message and stores it inside of a structured SessionDescription object.
2323
//
2424
// The States Transition Table describes the computation flow between functions
@@ -99,7 +99,7 @@ var (
9999
// | s15 | | 14 | | | 15 | | | | 12 | | | | | | | | |
100100
// | s16 | | 14 | | | | 15 | | | 12 | | | | | | | | |
101101
// +--------+----+-------+----+-----+----+-----+---+----+----+---+---+-----+---+---+----+---+----+
102-
func (s *SessionDescription) Unmarshal(value []byte) error {
102+
func (s *SessionDescription) UnmarshalString(value string) error {
103103
l := new(lexer)
104104
l.desc = s
105105
l.value = value
@@ -113,6 +113,12 @@ func (s *SessionDescription) Unmarshal(value []byte) error {
113113
return nil
114114
}
115115

116+
// Unmarshal converts the value into a []byte and then calls UnmarshalString.
117+
// Callers should use the more performant UnmarshalString
118+
func (s *SessionDescription) Unmarshal(value []byte) error {
119+
return s.UnmarshalString(string(value))
120+
}
121+
116122
func s1(l *lexer) (stateFn, error) {
117123
return l.handleType(func(key byte) stateFn {
118124
if key == 'v' {

‎unmarshal_test.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ func TestRoundTrip(t *testing.T) {
303303
t.Run(test.Name, func(t *testing.T) {
304304
sd := &SessionDescription{}
305305

306-
err := sd.Unmarshal([]byte(test.SDP))
306+
err := sd.UnmarshalString(test.SDP)
307307
if got, want := err, error(nil); !errors.Is(got, want) {
308308
t.Fatalf("Unmarshal:\nerr=%v\nwant=%v", got, want)
309309
}
@@ -327,7 +327,7 @@ func TestRoundTrip(t *testing.T) {
327327

328328
func TestUnmarshalRepeatTimes(t *testing.T) {
329329
sd := &SessionDescription{}
330-
if err := sd.Unmarshal([]byte(RepeatTimesSDP)); err != nil {
330+
if err := sd.UnmarshalString(RepeatTimesSDP); err != nil {
331331
t.Errorf("error: %v", err)
332332
}
333333

@@ -339,15 +339,15 @@ func TestUnmarshalRepeatTimes(t *testing.T) {
339339
t.Errorf("error:\n\nEXPECTED:\n%v\nACTUAL:\n%v", RepeatTimesSDPExpected, string(actual))
340340
}
341341

342-
err = sd.Unmarshal([]byte(TimingSDP + "r=\r\n"))
342+
err = sd.UnmarshalString(TimingSDP + "r=\r\n")
343343
if got, want := err, errSDPInvalidValue; !errors.Is(got, want) {
344344
t.Fatalf("Marshal(): err=%v, want %v", got, want)
345345
}
346346
}
347347

348348
func TestUnmarshalTimeZones(t *testing.T) {
349349
sd := &SessionDescription{}
350-
if err := sd.Unmarshal([]byte(TimeZonesSDP)); err != nil {
350+
if err := sd.UnmarshalString(TimeZonesSDP); err != nil {
351351
t.Errorf("error: %v", err)
352352
}
353353

@@ -363,7 +363,7 @@ func TestUnmarshalTimeZones(t *testing.T) {
363363
func TestUnmarshalNonNilAddress(t *testing.T) {
364364
in := "v=0\r\no=0 0 0 IN IP4 0\r\ns=0\r\nc=IN IP4\r\nt=0 0\r\n"
365365
var sd SessionDescription
366-
err := sd.Unmarshal([]byte(in))
366+
err := sd.UnmarshalString(in)
367367
if err != nil {
368368
t.Fatalf("failed to unmarshal %q", in)
369369
}
@@ -378,10 +378,9 @@ func TestUnmarshalNonNilAddress(t *testing.T) {
378378

379379
func BenchmarkUnmarshal(b *testing.B) {
380380
b.ReportAllocs()
381-
raw := []byte(CanonicalUnmarshalSDP)
382381
for i := 0; i < b.N; i++ {
383382
var sd SessionDescription
384-
err := sd.Unmarshal(raw)
383+
err := sd.UnmarshalString(CanonicalUnmarshalSDP)
385384
if err != nil {
386385
b.Fatal(err)
387386
}

0 commit comments

Comments
 (0)
Please sign in to comment.