diff options
author | 2022-12-17 05:38:56 +0100 | |
---|---|---|
committer | 2022-12-17 04:38:56 +0000 | |
commit | 2bbc64be4317166d3abb7aa177d4913f166a53e8 (patch) | |
tree | 88c3d613eb986b18894f311afa4291987a0e26c4 /vendor/github.com/abema/go-mp4/string.go | |
parent | [chore] fix some little config whoopsies (#1272) (diff) | |
download | gotosocial-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.go | 261 |
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) + } +} |