Skip to content

refactor: Have parsers handle "everything"#18

Merged
cyanChill merged 7 commits into
mainfrom
refactor/parsers
Jun 21, 2026
Merged

refactor: Have parsers handle "everything"#18
cyanChill merged 7 commits into
mainfrom
refactor/parsers

Conversation

@cyanChill

@cyanChill cyanChill commented Jun 21, 2026

Copy link
Copy Markdown
Member

Right now, we want our parsers to handle everything:

  1. Pass in the raw list of metadata.
  2. Extract the necessary values.
  3. Exit early once we're sure we've got what we needed.

If we want these to be more reusable, we would drop the initial arguments & the init block and expose parseFrom methods that may be overloaded so that we can support both List<Metadata> & Metadata.Entry.

This PR also fixes an issues where we sometimes had "junk" in front of the returned lyrics. The root cause was not handling the lyrics returned by ID3's binary frame correctly.

This is then followed by some more "junk" (in the form of "content" descriptor) of unknown size, which ends with 1 or 2 null bytes based on encoding (UTF16 uses 2 bytes for null while the others use 1 byte).

Summary by CodeRabbit

  • Bug Fixes
    • Fixed stray/garbled characters appearing before lyrics when retrieving tagged lyrics from certain audio files.
    • Improved lyrics extraction to better handle different tagging formats, including synchronized lyrics.
  • Chores
    • Updated the changelog under [Unreleased] with the latest lyrics and parser-related notes.

- It acts more like a function rather than a class.
- If we want things to be reusable, instead of accepting some initial parameters, we would expose a `parseFrom` function which might be overloaded to support `List<Metadata>` & `Metadata`.
- In the future, we may want to change up what we expose in `ReplayGainParser`, for example: `trackGain` (prev `gain`), `trackPeak`, `albumGain`, and `albumPeak`.
- This only occurs for ID3 binary frames.
- This was due to the null bytes that we didn't handle before.
@cyanChill cyanChill added Bug Something isn't working Housekeeping Code maintenance or refactor. labels Jun 21, 2026
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@cyanChill, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 11 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8943ca84-d3db-4657-ac44-b0be4e01252f

📥 Commits

Reviewing files that changed from the base of the PR and between decbd80 and 6793d0b.

📒 Files selected for processing (1)
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/LyricsParser.kt
📝 Walkthrough

Walkthrough

LyricsParser and ReplayGainParser are rewritten to accept a List<Metadata> and relocated from the utils package to the modules package. The new LyricsParser adds binary-frame junk-byte stripping with charset and BOM detection. MetadataRetrieverModule.getLyric and getR128Gain are simplified to single-expression delegations to the new parsers.

Changes

Parser rewrite and module integration

Layer / File(s) Summary
New LyricsParser in modules with binary-frame fix
android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/LyricsParser.kt
New LyricsParser accepts List<Metadata>, iterates entries, and dispatches to handlers for TextInformationFrame (filters SYLT/USLT), BinaryFrame (detects charset/BOM from ID3 encoding byte, strips frame-type-specific junk bytes and null-terminated content descriptor, decodes payload), and VorbisComment (matches key "LYRICS"). Stops early when synchronised lyrics are found. Exposes lyrics via public field.
ReplayGainParser migration to modules
android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/ReplayGainParser.kt
Package declaration updated from utils to modules; constructor changed from Metadata.Entry to List<Metadata>; initialization now iterates all metadata and their entries via parseMetadataEntry helper, stopping once gain is non-null. Region comments organize the code structure.
MetadataRetrieverModule simplification and CHANGELOG
android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/MetadataRetrieverModule.kt, CHANGELOG.md
getLyric and getR128Gain replace explicit accumulator loops with single-expression calls: LyricsParser(metadataList).lyrics and ReplayGainParser(metadataList).gain; import block updated. CHANGELOG records binary-frame junk removal and parser rewrites under Unreleased.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: Have parsers handle "everything"' is directly related to the main architectural change—refactoring parsers to handle complete metadata processing workflows by accepting raw metadata lists instead of relying on init blocks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/LyricsParser.kt`:
- Around line 60-67: The BOM detection logic in the encodingCharSet assignment
is reading bytes from the wrong location in byteArr. The USLT/SYLT header is
dropped later in the code, but the current BOM detection using indices [1] and
[2] is checking pre-header bytes instead of the actual lyric text bytes. Move
the encodingCharSet assignment and BOM detection logic to occur after the header
has been dropped from byteArr, so that the UTF-16 endianness check examines the
correct bytes from the actual lyric content rather than the frame header,
preventing incorrect endianness selection and garbled output.
- Around line 99-104: The handleVorbisComment method is incorrectly marking
Vorbis LYRICS comments as synchronized by passing true as the isSync parameter
to ParsedResult. Since Vorbis LYRICS tags are inherently unsynchronized, change
the boolean parameter from true to false in the ParsedResult constructor call so
that the parser continues scanning for actual synchronized lyrics frames like
SYLT instead of prematurely stopping based on this unsynchronized source.
- Around line 56-67: The code in the encodingCharSet assignment accesses byteArr
at indices 0, 1, and 2 without checking if the array has sufficient length,
which can throw ArrayIndexOutOfBoundsException for malformed or short ID3
frames. Add a bounds check before the val encodingByte assignment to ensure
byteArr has at least 3 elements, and handle the case where the array is too
short by returning early or using a default charset value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a76c4f3-cd71-4b2f-8d77-551bf4ac9dc8

📥 Commits

Reviewing files that changed from the base of the PR and between 256c9e5 and 71c4bc9.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/LyricsParser.kt
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/MetadataRetrieverModule.kt
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/modules/ReplayGainParser.kt
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/utils/LyricsParser.kt
💤 Files with no reviewable changes (1)
  • android/src/main/java/com/cyanchill/missingcore/metadataretriever/utils/LyricsParser.kt

- We were previously checking the bytes representing "language", which isn't encoded.
@cyanChill

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- This is due to potentially being at the end of the returned lyrics.
@cyanChill cyanChill merged commit 32921ad into main Jun 21, 2026
4 checks passed
@cyanChill cyanChill deleted the refactor/parsers branch June 21, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working Housekeeping Code maintenance or refactor.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant