-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathinfodumper.go
109 lines (101 loc) · 2.59 KB
/
infodumper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package mp4
import (
"fmt"
"io"
"strconv"
"strings"
)
const (
infoVersionNone = -1
infoVersionGroupingType = -2
infoVersionDescriptor = -3
)
type boxLike interface {
Type() string
Size() uint64
Info(w io.Writer, specificBoxLevels, indent, indentStep string) error
}
// infoDumper - dump box name and size. Allow for more with write.
type infoDumper struct {
w io.Writer
indent string
box boxLike
err error
}
// fixStartingCopyrightChar - replace starting one byte © with two-bytes UTF-8
func fixStartingCopyrightChar(boxType string) string {
// © is 0xa9 in latin1 (and in Apple boxes/atoms)
// In UTF-8 it is two bytes: 0xc2 0xa9
bType := []byte(boxType)
if bType[0] == 0xa9 {
bType = append([]byte{0xc2}, bType...)
}
return string(bType)
}
// newInfoDumper - make an infoDumper with indent
// write version if >= 0
// set Version to -1 if not present for box
// set Version to -2 for sample group entries
// set Version to -3 for descriptors
func newInfoDumper(w io.Writer, indent string, b boxLike, version int, flags uint32) *infoDumper {
bd := infoDumper{w, indent, b, nil}
utf8BoxType := fixStartingCopyrightChar(b.Type())
switch {
case version >= 0:
bd.write("[%s] size=%d version=%d flags=%06x", utf8BoxType, b.Size(), version, flags)
case version == infoVersionNone:
bd.write("[%s] size=%d", utf8BoxType, b.Size())
case version == infoVersionGroupingType:
bd.write("GroupingType %q size=%d", utf8BoxType, b.Size())
case version == infoVersionDescriptor:
bd.write("Descriptor %q size=2+%d", b.Type(), b.Size())
default:
bd.write("Unknown version %d", version)
}
return &bd
}
// write - write formated objecds if level <= bd.level
func (b *infoDumper) write(format string, p ...interface{}) {
if b.err != nil {
return
}
_, err := fmt.Fprintf(b.w, "%s", b.indent)
if err != nil {
b.err = err
return
}
_, b.err = fmt.Fprintf(b.w, format+"\n", p...)
}
// getInfoLevel - get info level for specific boxLike, or from all
func getInfoLevel(b boxLike, specificBoxLevels string) (level int) {
if len(specificBoxLevels) == 0 {
return level
}
boxesLevels := strings.Split(specificBoxLevels, ",")
boxType := b.Type()
if _, ok := b.(Descriptor); ok {
boxType = "esds"
}
var err error
for _, bl := range boxesLevels {
splitPos := strings.Index(bl, ":")
if splitPos < 1 {
continue
}
bt := bl[:splitPos]
nr := bl[splitPos+1:]
if bt == boxType {
level, err = strconv.Atoi(nr)
if err != nil {
level = 0
}
return level
} else if bt == "all" {
level, err = strconv.Atoi(nr)
if err != nil {
level = 0
}
}
}
return level
}