summaryrefslogtreecommitdiff
path: root/vendor/github.com/abema/go-mp4/string.go
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2022-12-17 05:38:56 +0100
committerLibravatar GitHub <noreply@github.com>2022-12-17 04:38:56 +0000
commit2bbc64be4317166d3abb7aa177d4913f166a53e8 (patch)
tree88c3d613eb986b18894f311afa4291987a0e26c4 /vendor/github.com/abema/go-mp4/string.go
parent[chore] fix some little config whoopsies (#1272) (diff)
downloadgotosocial-2bbc64be4317166d3abb7aa177d4913f166a53e8.tar.xz
[feature] Enable basic video support (mp4 only) (#1274)
* [feature] basic video support * fix missing semicolon * replace text shadow with stacked icons Co-authored-by: f0x <f0x@cthu.lu>
Diffstat (limited to 'vendor/github.com/abema/go-mp4/string.go')
-rw-r--r--vendor/github.com/abema/go-mp4/string.go261
1 files changed, 261 insertions, 0 deletions
diff --git a/vendor/github.com/abema/go-mp4/string.go b/vendor/github.com/abema/go-mp4/string.go
new file mode 100644
index 000000000..56afff1bb
--- /dev/null
+++ b/vendor/github.com/abema/go-mp4/string.go
@@ -0,0 +1,261 @@
+package mp4
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+
+ "github.com/abema/go-mp4/util"
+)
+
+type stringifier struct {
+ buf *bytes.Buffer
+ src IImmutableBox
+ indent string
+ ctx Context
+}
+
+func Stringify(src IImmutableBox, ctx Context) (string, error) {
+ return StringifyWithIndent(src, "", ctx)
+}
+
+func StringifyWithIndent(src IImmutableBox, indent string, ctx Context) (string, error) {
+ boxDef := src.GetType().getBoxDef(ctx)
+ if boxDef == nil {
+ return "", ErrBoxInfoNotFound
+ }
+
+ v := reflect.ValueOf(src).Elem()
+
+ m := &stringifier{
+ buf: bytes.NewBuffer(nil),
+ src: src,
+ indent: indent,
+ ctx: ctx,
+ }
+
+ err := m.stringifyStruct(v, boxDef.fields, 0, true)
+ if err != nil {
+ return "", err
+ }
+
+ return m.buf.String(), nil
+}
+
+func (m *stringifier) stringify(v reflect.Value, fi *fieldInstance, depth int) error {
+ switch v.Type().Kind() {
+ case reflect.Ptr:
+ return m.stringifyPtr(v, fi, depth)
+ case reflect.Struct:
+ return m.stringifyStruct(v, fi.children, depth, fi.is(fieldExtend))
+ case reflect.Array:
+ return m.stringifyArray(v, fi, depth)
+ case reflect.Slice:
+ return m.stringifySlice(v, fi, depth)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return m.stringifyInt(v, fi, depth)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return m.stringifyUint(v, fi, depth)
+ case reflect.Bool:
+ return m.stringifyBool(v, depth)
+ case reflect.String:
+ return m.stringifyString(v, depth)
+ default:
+ return fmt.Errorf("unsupported type: %s", v.Type().Kind())
+ }
+}
+
+func (m *stringifier) stringifyPtr(v reflect.Value, fi *fieldInstance, depth int) error {
+ return m.stringify(v.Elem(), fi, depth)
+}
+
+func (m *stringifier) stringifyStruct(v reflect.Value, fs []*field, depth int, extended bool) error {
+ if !extended {
+ m.buf.WriteString("{")
+ if m.indent != "" {
+ m.buf.WriteString("\n")
+ }
+ depth++
+ }
+
+ for _, f := range fs {
+ fi := resolveFieldInstance(f, m.src, v, m.ctx)
+
+ if !isTargetField(m.src, fi, m.ctx) {
+ continue
+ }
+
+ if f.cnst != "" || f.is(fieldHidden) {
+ continue
+ }
+
+ if !f.is(fieldExtend) {
+ if m.indent != "" {
+ writeIndent(m.buf, m.indent, depth+1)
+ } else if m.buf.Len() != 0 && m.buf.Bytes()[m.buf.Len()-1] != '{' {
+ m.buf.WriteString(" ")
+ }
+ m.buf.WriteString(f.name)
+ m.buf.WriteString("=")
+ }
+
+ str, ok := fi.cfo.StringifyField(f.name, m.indent, depth+1, m.ctx)
+ if ok {
+ m.buf.WriteString(str)
+ if !f.is(fieldExtend) && m.indent != "" {
+ m.buf.WriteString("\n")
+ }
+ continue
+ }
+
+ if f.name == "Version" {
+ m.buf.WriteString(strconv.Itoa(int(m.src.GetVersion())))
+ } else if f.name == "Flags" {
+ fmt.Fprintf(m.buf, "0x%06x", m.src.GetFlags())
+ } else {
+ err := m.stringify(v.FieldByName(f.name), fi, depth)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !f.is(fieldExtend) && m.indent != "" {
+ m.buf.WriteString("\n")
+ }
+ }
+
+ if !extended {
+ if m.indent != "" {
+ writeIndent(m.buf, m.indent, depth)
+ }
+ m.buf.WriteString("}")
+ }
+
+ return nil
+}
+
+func (m *stringifier) stringifyArray(v reflect.Value, fi *fieldInstance, depth int) error {
+ begin, sep, end := "[", ", ", "]"
+ if fi.is(fieldString) || fi.is(fieldISO639_2) {
+ begin, sep, end = "\"", "", "\""
+ } else if fi.is(fieldUUID) {
+ begin, sep, end = "", "", ""
+ }
+
+ m.buf.WriteString(begin)
+
+ m2 := *m
+ if fi.is(fieldString) {
+ m2.buf = bytes.NewBuffer(nil)
+ }
+ size := v.Type().Size()
+ for i := 0; i < int(size)/int(v.Type().Elem().Size()); i++ {
+ if i != 0 {
+ m2.buf.WriteString(sep)
+ }
+
+ if err := m2.stringify(v.Index(i), fi, depth+1); err != nil {
+ return err
+ }
+
+ if fi.is(fieldUUID) && (i == 3 || i == 5 || i == 7 || i == 9) {
+ m.buf.WriteString("-")
+ }
+ }
+ if fi.is(fieldString) {
+ m.buf.WriteString(util.EscapeUnprintables(m2.buf.String()))
+ }
+
+ m.buf.WriteString(end)
+
+ return nil
+}
+
+func (m *stringifier) stringifySlice(v reflect.Value, fi *fieldInstance, depth int) error {
+ begin, sep, end := "[", ", ", "]"
+ if fi.is(fieldString) || fi.is(fieldISO639_2) {
+ begin, sep, end = "\"", "", "\""
+ }
+
+ m.buf.WriteString(begin)
+
+ m2 := *m
+ if fi.is(fieldString) {
+ m2.buf = bytes.NewBuffer(nil)
+ }
+ for i := 0; i < v.Len(); i++ {
+ if fi.length != LengthUnlimited && uint(i) >= fi.length {
+ break
+ }
+
+ if i != 0 {
+ m2.buf.WriteString(sep)
+ }
+
+ if err := m2.stringify(v.Index(i), fi, depth+1); err != nil {
+ return err
+ }
+ }
+ if fi.is(fieldString) {
+ m.buf.WriteString(util.EscapeUnprintables(m2.buf.String()))
+ }
+
+ m.buf.WriteString(end)
+
+ return nil
+}
+
+func (m *stringifier) stringifyInt(v reflect.Value, fi *fieldInstance, depth int) error {
+ if fi.is(fieldHex) {
+ val := v.Int()
+ if val >= 0 {
+ m.buf.WriteString("0x")
+ m.buf.WriteString(strconv.FormatInt(val, 16))
+ } else {
+ m.buf.WriteString("-0x")
+ m.buf.WriteString(strconv.FormatInt(-val, 16))
+ }
+ } else {
+ m.buf.WriteString(strconv.FormatInt(v.Int(), 10))
+ }
+ return nil
+}
+
+func (m *stringifier) stringifyUint(v reflect.Value, fi *fieldInstance, depth int) error {
+ if fi.is(fieldISO639_2) {
+ m.buf.WriteString(string([]byte{byte(v.Uint() + 0x60)}))
+ } else if fi.is(fieldUUID) {
+ fmt.Fprintf(m.buf, "%02x", v.Uint())
+ } else if fi.is(fieldString) {
+ m.buf.WriteString(string([]byte{byte(v.Uint())}))
+ } else if fi.is(fieldHex) || (!fi.is(fieldDec) && v.Type().Kind() == reflect.Uint8) || v.Type().Kind() == reflect.Uintptr {
+ m.buf.WriteString("0x")
+ m.buf.WriteString(strconv.FormatUint(v.Uint(), 16))
+ } else {
+ m.buf.WriteString(strconv.FormatUint(v.Uint(), 10))
+ }
+
+ return nil
+}
+
+func (m *stringifier) stringifyBool(v reflect.Value, depth int) error {
+ m.buf.WriteString(strconv.FormatBool(v.Bool()))
+
+ return nil
+}
+
+func (m *stringifier) stringifyString(v reflect.Value, depth int) error {
+ m.buf.WriteString("\"")
+ m.buf.WriteString(util.EscapeUnprintables(v.String()))
+ m.buf.WriteString("\"")
+
+ return nil
+}
+
+func writeIndent(w io.Writer, indent string, depth int) {
+ for i := 0; i < depth; i++ {
+ io.WriteString(w, indent)
+ }
+}