Skip to content

Commit 3831c23

Browse files
committed
chore: update ebml dependency
1 parent 0004561 commit 3831c23

5 files changed

Lines changed: 141 additions & 26 deletions

File tree

cmd/mkc/internal/list/list.go

Lines changed: 129 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package list
22

33
import (
44
"bytes"
5+
"context"
56
"errors"
67
"fmt"
78
"github.com/charmbracelet/huh"
@@ -60,7 +61,7 @@ func run(flags *flag.FlagSet) {
6061
r := io.MultiReader(f) // remove seeking capability
6162
s := matroska.NewScanner(r)
6263

63-
v := printVisitor{
64+
v := listCallbacker{
6465
w: os.Stdout,
6566
s: s,
6667

@@ -70,7 +71,7 @@ func run(flags *flag.FlagSet) {
7071
showSize: *flagSize || *flagVerbose,
7172
showDataSize: *flagDataSize || *flagVerbose,
7273
}
73-
s.Decoder().SetVisitor(v)
74+
s.Decoder().SetCallback(v)
7475

7576
if err := s.Init(); err != nil {
7677
fmt.Fprint(os.Stderr, err)
@@ -82,7 +83,7 @@ func run(flags *flag.FlagSet) {
8283
}
8384
}
8485

85-
type printVisitor struct {
86+
type listCallbacker struct {
8687
w io.Writer
8788
s *matroska.Scanner
8889

@@ -92,13 +93,40 @@ type printVisitor struct {
9293
showPosition bool
9394
showSize bool
9495
showDataSize bool
96+
97+
queueEnabled bool
98+
queue []func(v listCallbacker, ctx context.Context) listCallbacker
99+
}
100+
101+
func (v listCallbacker) Found(el ebml.Element, offset int64, headerSize int) ebml.Callbacker {
102+
callCtx := context.Background()
103+
104+
switch el.ID {
105+
case matroska.IDBlockGroup:
106+
v.queueEnabled = true
107+
}
108+
109+
f := func(v listCallbacker, ctx context.Context) listCallbacker {
110+
return v.found(el, offset, headerSize, ctx)
111+
}
112+
113+
if v.queueEnabled {
114+
v.queue = append(v.queue, f)
115+
} else {
116+
for _, ff := range v.queue {
117+
v = ff(v, callCtx)
118+
}
119+
v.queue = nil
120+
v = f(v, context.Background())
121+
}
122+
123+
return v
95124
}
96125

97-
func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val any) (w ebml.Visitor) {
126+
func (v listCallbacker) found(el ebml.Element, offset int64, headerSize int, ctx context.Context) listCallbacker {
98127
sch := el.Schema
99128

100129
v.printer.Sub(offset)
101-
102130
v.suffix.Reset()
103131

104132
if v.showPosition {
@@ -119,15 +147,83 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
119147
}
120148
}
121149

122-
var lastTrackNumber uint = 0
150+
switch el.ID {
151+
default:
152+
if sch.Type != ebml.TypeMaster {
153+
return v
154+
}
155+
v.printer.Printf("%s%s", sch.Name, v.suffix.String())
156+
}
157+
158+
if el.DataSize > -1 {
159+
absoluteEnd := offset + int64(headerSize) + el.DataSize
160+
v.printer.Add(absoluteEnd)
161+
} else {
162+
v.printer.Add(-1)
163+
}
164+
165+
return v
166+
}
167+
168+
func (v listCallbacker) Decoded(el ebml.Element, offset int64, headerSize int, val any) ebml.Callbacker {
169+
callCtx := context.Background()
170+
171+
switch el.ID {
172+
case matroska.IDBlockGroup:
173+
v.queueEnabled = false
174+
175+
callCtx = context.WithValue(callCtx, el.ID, val)
176+
}
177+
178+
f := func(v listCallbacker, ctx context.Context) listCallbacker {
179+
return v.decode(el, offset, headerSize, val, ctx)
180+
}
181+
182+
if v.queueEnabled {
183+
v.queue = append(v.queue, f)
184+
} else {
185+
for _, ff := range v.queue {
186+
v = ff(v, callCtx)
187+
}
188+
v.queue = nil
189+
v = f(v, callCtx)
190+
}
191+
192+
return v
193+
}
194+
195+
func (v listCallbacker) decode(el ebml.Element, offset int64, headerSize int, val any, ctx context.Context) listCallbacker {
196+
sch := el.Schema
197+
if sch.Type == ebml.TypeMaster {
198+
return v
199+
}
200+
201+
v.printer.Sub(offset)
202+
v.suffix.Reset()
203+
204+
if v.showPosition {
205+
fmt.Fprintf(&v.suffix, ", at %d", offset)
206+
}
207+
if v.showSize {
208+
if el.DataSize == -1 {
209+
fmt.Fprint(&v.suffix, ", size unknown")
210+
} else {
211+
fmt.Fprintf(&v.suffix, ", size %d", int64(headerSize)+el.DataSize)
212+
}
213+
}
214+
if v.showDataSize {
215+
if el.DataSize == -1 {
216+
fmt.Fprint(&v.suffix, ", data size unknown")
217+
} else {
218+
fmt.Fprintf(&v.suffix, ", data size %d", el.DataSize)
219+
}
220+
}
123221

124222
switch el.ID {
125223
default:
126224
switch sch.Type {
127225
default:
128226
v.printer.Print("unexpected element ", el.ID)
129-
case ebml.TypeMaster:
130-
v.printer.Printf("%s%s", sch.Name, v.suffix.String())
131227
case ebml.TypeBinary:
132228
v.printer.Printf("%s%s", sch.Name, v.suffix.String())
133229
case ebml.TypeString:
@@ -143,6 +239,10 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
143239
case ebml.TypeDate:
144240
v.printer.Printf("%s: %s%s", sch.Name, val, v.suffix.String())
145241
}
242+
243+
case matroska.IDBlockGroup:
244+
v.queueEnabled = true
245+
146246
case matroska.IDDuration:
147247
// https://www.ietf.org/archive/id/draft-ietf-cellar-matroska-21.html#name-segment-ticks
148248
timestampScale := v.s.Info().TimestampScale
@@ -164,6 +264,9 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
164264
case matroska.IDBlockDuration, matroska.IDReferenceBlock:
165265
// https://www.ietf.org/archive/id/draft-ietf-cellar-matroska-21.html#name-track-ticks
166266
timestampScale := v.s.Info().TimestampScale
267+
blockGroup := ctx.Value(matroska.IDBlockGroup).(matroska.BlockGroup)
268+
block, _ := matroska.ReadBlock(blockGroup.Block, timestampScale)
269+
167270
var i int64
168271
switch v := val.(type) {
169272
default:
@@ -176,7 +279,7 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
176279
// TODO: validate if this would work. I may need the whole BlockGroup.
177280
trackTimestampScale := 1.0
178281
for _, te := range v.s.Tracks().TrackEntry {
179-
if te.TrackNumber == lastTrackNumber {
282+
if te.TrackNumber == block.TrackNumber() {
180283
trackTimestampScale = te.TrackTimestampScale
181284
break
182285
}
@@ -186,10 +289,26 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
186289
case matroska.IDBlock:
187290
// https://www.ietf.org/archive/id/draft-ietf-cellar-matroska-21.html#name-block-structure
188291
timestampScale := v.s.Info().TimestampScale
292+
blockGroup := ctx.Value(matroska.IDBlockGroup).(matroska.BlockGroup)
293+
189294
b := val.([]byte)
190295
block, _ := matroska.ReadBlock(b, timestampScale)
191296
frames := block.Frames()
192-
blockDuration := time.Second // TODO: get proper value
297+
298+
blockDuration := time.Second
299+
if blockGroup.BlockDuration != nil {
300+
blockDuration = time.Duration(*blockGroup.BlockDuration)
301+
} else {
302+
for _, te := range v.s.Tracks().TrackEntry {
303+
if te.TrackNumber == block.TrackNumber() {
304+
if te.DefaultDuration != nil {
305+
blockDuration = time.Duration(*te.DefaultDuration)
306+
}
307+
break
308+
}
309+
}
310+
}
311+
193312
v.printer.Printf("%s: track number %d, %d frame(s), timestamp %v%s", sch.Name,
194313
block.TrackNumber(), len(frames), blockDuration*timestampScale, v.suffix.String())
195314
v.printer.Add(1)
@@ -202,8 +321,6 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
202321
frameOffset += int64(len(f))
203322
}
204323
v.printer.Sub(1)
205-
206-
lastTrackNumber = block.TrackNumber()
207324
case matroska.IDSimpleBlock:
208325
// https://www.ietf.org/archive/id/draft-ietf-cellar-matroska-21.html#name-simpleblock-structure
209326
timestampScale := v.s.Info().TimestampScale
@@ -224,15 +341,6 @@ func (v printVisitor) Visit(el ebml.Element, offset int64, headerSize int, val a
224341
v.printer.Sub(1)
225342
}
226343

227-
if sch.Type == ebml.TypeMaster {
228-
if el.DataSize > -1 {
229-
absoluteEnd := offset + int64(headerSize) + el.DataSize
230-
v.printer.Add(absoluteEnd)
231-
} else {
232-
v.printer.Add(-1)
233-
}
234-
}
235-
236344
return v
237345
}
238346

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ toolchain go1.24.1
77
require (
88
github.com/charmbracelet/huh v0.6.0
99
github.com/charmbracelet/huh/spinner v0.0.0-20250410174039-76d1f8226680
10-
github.com/coding-socks/ebml v0.0.0-20250423185329-7aabf7e89ae9
10+
github.com/coding-socks/ebml v0.0.0-20250423205039-3eaea91d5d71
1111
github.com/spf13/pflag v1.0.6
1212
golang.org/x/tools v0.32.0
1313
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ github.com/coding-socks/ebml v0.0.0-20250423152522-9ccc7122c118 h1:T63MS67JwXtfQ
4242
github.com/coding-socks/ebml v0.0.0-20250423152522-9ccc7122c118/go.mod h1:6RUr58mWiQHHZiL2UFb8JygHNS5E35wGJfEmoSsDyI0=
4343
github.com/coding-socks/ebml v0.0.0-20250423185329-7aabf7e89ae9 h1:xCzC2gZ2uC1Fbh1tT1de6DHtGO/YOsEXlgpXik0kELU=
4444
github.com/coding-socks/ebml v0.0.0-20250423185329-7aabf7e89ae9/go.mod h1:6RUr58mWiQHHZiL2UFb8JygHNS5E35wGJfEmoSsDyI0=
45+
github.com/coding-socks/ebml v0.0.0-20250423205039-3eaea91d5d71 h1:asw2kEIPHmbb9Y7RZanKoZ5v5fHnOv7G/WmR8wO4EkU=
46+
github.com/coding-socks/ebml v0.0.0-20250423205039-3eaea91d5d71/go.mod h1:6RUr58mWiQHHZiL2UFb8JygHNS5E35wGJfEmoSsDyI0=
4547
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
4648
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
4749
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=

matroska_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@ func Test_init(t *testing.T) {
2626
}
2727
}
2828

29-
type diagnosisVisitor struct{ t *testing.T }
29+
type diagnosisCallbacker struct{ t *testing.T }
3030

31-
func (v diagnosisVisitor) Visit(el ebml.Element, offset int64, headerSize int, val any) (w ebml.Visitor) {
31+
func (v diagnosisCallbacker) Found(el ebml.Element, offset int64, headerSize int) ebml.Callbacker {
32+
v.t.Logf("%s %s at %d, size %d+%d", el.Schema.Name, el.ID, offset, headerSize, el.DataSize)
33+
return v
34+
}
35+
36+
func (v diagnosisCallbacker) Decoded(el ebml.Element, offset int64, headerSize int, val any) ebml.Callbacker {
3237
v.t.Logf("%s %s at %d, size %d+%d", el.Schema.Name, el.ID, offset, headerSize, el.DataSize)
3338
return v
3439
}
@@ -304,7 +309,7 @@ func TestDecode(t *testing.T) {
304309
defer f.Close()
305310
d := ebml.NewDecoder(f)
306311
if *flagDiagnosis {
307-
d.SetVisitor(diagnosisVisitor{t: t})
312+
d.SetCallback(diagnosisCallbacker{t: t})
308313
}
309314
header, err := d.DecodeHeader()
310315
if err != nil {

scanner_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func TestScanner(t *testing.T) {
9292
defer f.Close()
9393
s := NewScanner(f)
9494
if *flagDiagnosis {
95-
s.Decoder().SetVisitor(diagnosisVisitor{t: t})
95+
s.Decoder().SetCallback(diagnosisCallbacker{t: t})
9696
}
9797
var cluster []Cluster
9898
for s.Next() {

0 commit comments

Comments
 (0)