Skip to content

Commit 3eaea91

Browse files
committed
feat: reimagine visitor pattern as callback pattern
1 parent 06321c0 commit 3eaea91

File tree

2 files changed

+22
-19
lines changed

2 files changed

+22
-19
lines changed

decode.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,6 @@ func (d *Decoder) Decode(el Element, v interface{}) error {
138138
return err
139139
}
140140

141-
// callVisitor calls the visitor if there is any and subtracts the header length from the offset.
142-
func (d *Decoder) callVisitor(el Element, offset int64, headerSize int, val any) {
143-
if d.visitor == nil {
144-
return
145-
}
146-
d.visitor = d.visitor.Visit(el, offset-int64(headerSize), headerSize, val)
147-
}
148-
149141
var (
150142
typeTime = reflect.TypeOf(time.Time{})
151143
typeDuration = reflect.TypeOf(time.Duration(0))
@@ -411,12 +403,16 @@ func (d *Decoder) decodeSingle(el Element, val reflect.Value) error {
411403
return err
412404
}
413405

406+
pos := d.r.InputOffset()
407+
414408
if sch.Type == TypeMaster {
415-
return d.decodeMaster(val, el)
409+
err := d.decodeMaster(val, el)
410+
if d.callback != nil {
411+
d.callback = d.callback.Decoded(el, pos-int64(d.n), d.n, val.Interface())
412+
}
413+
return err
416414
}
417415

418-
pos := d.r.InputOffset()
419-
420416
if int64(cap(d.window)) < el.DataSize {
421417
n := DefaultAllocationWindow
422418
for n < el.DataSize {
@@ -488,6 +484,8 @@ func (d *Decoder) decodeSingle(el Element, val reflect.Value) error {
488484
val.SetString(str)
489485
}
490486

491-
d.callVisitor(el, pos, d.n, val.Interface())
487+
if d.callback != nil {
488+
d.callback = d.callback.Decoded(el, pos-int64(d.n), d.n, val.Interface())
489+
}
492490
return nil
493491
}

ebml.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ type Decoder struct {
178178
window []byte
179179
typeInfos map[reflect.Type]*typeInfo
180180

181-
visitor Visitor
181+
callback Callbacker
182182
}
183183

184184
// NewDecoder reads and parses an EBML Document from r.
@@ -191,8 +191,10 @@ func NewDecoder(r io.Reader) *Decoder {
191191
}
192192
}
193193

194-
func (d *Decoder) SetVisitor(v Visitor) {
195-
d.visitor = v
194+
// SetCallback adds a Callbacker which is triggered when NextOf reads element id
195+
// and data size, and when a value is successfully decoded.
196+
func (d *Decoder) SetCallback(c Callbacker) {
197+
d.callback = c
196198
}
197199

198200
// next reads the following element id and data size.
@@ -219,8 +221,8 @@ func (d *Decoder) next() (el Element, n int, err error) {
219221
} else {
220222
el.Schema = sch
221223
}
222-
if sch.Type == TypeMaster {
223-
d.callVisitor(el, d.r.InputOffset(), n, nil)
224+
if d.callback != nil {
225+
d.callback = d.callback.Found(el, d.r.InputOffset()-int64(n), n)
224226
}
225227
return el, n, err
226228
}
@@ -307,6 +309,9 @@ func (d *Decoder) EndOfUnknownDataSize(parent Element, el Element) bool {
307309
return !strings.HasPrefix(elSch.Path, parentSch.Path) || len(elSch.Path) == len(parentSch.Path)
308310
}
309311

310-
type Visitor interface {
311-
Visit(el Element, offset int64, headerSize int, val any) (w Visitor)
312+
type Callbacker interface {
313+
// Found is called whenever a new element is found in the target io.Reader.
314+
Found(el Element, offset int64, headerSize int) Callbacker
315+
// Decoded is called whenever an element is decoded from the target io.Reader.
316+
Decoded(el Element, offset int64, headerSize int, val any) Callbacker
312317
}

0 commit comments

Comments
 (0)