mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-14 13:27:09 +02:00
perf(lyrics): drop []byte/string round-trips in parsers
Apply code-review feedback to remove avoidable allocations in the lyrics parsers. isTTMLDocument now takes []byte directly, so parseTTMLWithDefaultLang no longer copies its buffer into a string before the TTML probe. parseSRTBlock splits its block with strings.Split instead of converting to []byte and back per line. ParseLyrics hoists strings.ToLower(suffix) out of the format loop. No behavior change; the dropped len(scanner)==0 SRT guard was dead (strings.Split never returns an empty slice, and the existing len(lines)==0 check still covers empty input). Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
002ccbf0e4
commit
76ce0b8553
3 changed files with 10 additions and 14 deletions
|
|
@ -30,13 +30,14 @@ var lyricFormats = []struct {
|
|||
// a structured parser that does not match falls back to the LRC/plain-text floor.
|
||||
func ParseLyrics(suffix, lang string, contents []byte) (LyricList, error) {
|
||||
contents = stripBOM(contents)
|
||||
sniff := suffix == "" || strings.EqualFold(suffix, "auto")
|
||||
suffix = strings.ToLower(suffix)
|
||||
sniff := suffix == "" || suffix == "auto"
|
||||
|
||||
// Sniffing tries every format in order; a known suffix selects just its own.
|
||||
// Unmatched suffixes leave no candidates, so parseFirstMatch falls to plain.
|
||||
candidates := make([]lyricParser, 0, len(lyricFormats))
|
||||
for _, f := range lyricFormats {
|
||||
if sniff || slices.Contains(f.suffixes, strings.ToLower(suffix)) {
|
||||
if sniff || slices.Contains(f.suffixes, suffix) {
|
||||
candidates = append(candidates, f.parse)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -61,14 +60,10 @@ func splitSRTBlocks(raw string) []string {
|
|||
}
|
||||
|
||||
func parseSRTBlock(block string) (Line, bool, error) {
|
||||
scanner := bytes.Split([]byte(block), []byte("\n"))
|
||||
if len(scanner) == 0 {
|
||||
return Line{}, false, nil
|
||||
}
|
||||
|
||||
lines := make([]string, 0, len(scanner))
|
||||
for _, line := range scanner {
|
||||
lines = append(lines, strings.TrimSpace(string(line)))
|
||||
rawLines := strings.Split(block, "\n")
|
||||
lines := make([]string, 0, len(rawLines))
|
||||
for _, line := range rawLines {
|
||||
lines = append(lines, strings.TrimSpace(line))
|
||||
}
|
||||
|
||||
if len(lines) == 0 {
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ type ttmlParser struct {
|
|||
metadataSeq int
|
||||
}
|
||||
|
||||
func isTTMLDocument(text string) bool {
|
||||
decoder := xml.NewDecoder(strings.NewReader(strings.TrimSpace(text)))
|
||||
func isTTMLDocument(contents []byte) bool {
|
||||
decoder := xml.NewDecoder(bytes.NewReader(bytes.TrimSpace(contents)))
|
||||
for {
|
||||
token, err := decoder.Token()
|
||||
if err != nil {
|
||||
|
|
@ -120,7 +120,7 @@ func parseTTMLWithDefaultLang(defaultLang string, contents []byte) (LyricList, e
|
|||
|
||||
// Skip non-TTML content so sniffing doesn't run the XML decoder on plain text.
|
||||
// Checked after the encoding fixup so UTF-16-declared documents are recognized.
|
||||
if !isTTMLDocument(string(contents)) {
|
||||
if !isTTMLDocument(contents) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue