parse method

Future<LcrLyrics> parse()

Parse the lrc file or format.

For high fault tolerance, if characters that do not meet expectations will be ignored or the relevant value will be set to the default value.

May throw LyricsParserNotReadyException when call parse before ready.

Implementation

Future<LcrLyrics> parse() async {
  if (!_isReady) {
    throw LyricsParserNotReadyException('Unready when parse. You need call ready before parse when read from lrc file');
  }
  final pairsFuture = rawString.characters
      .getLines(containsEmptyLine: false, trim: false)
      .map((line) {
        Iterator<String> it = line.iterator;
        final results = <LrcTagContentPair>[];

        var isInTag = false;
        var isInTagKey = false;
        final tagRaw = StringBuffer();
        final lyricRaw = StringBuffer();
        final tagKey = StringBuffer();
        final tagValue = StringBuffer();
        final content = StringBuffer();

        void release() {
          if (lyricRaw.isEmpty) {
            return;
          }
          results.add(_parseToPair(
            tagRaw: tagRaw.toString(),
            tagKey: tagKey.toString(),
            tagValue: tagValue.toString(),
            content: content.toString(),
            lyricRaw: lyricRaw.toString(),
          ));
          tagRaw.clear();
          lyricRaw.clear();
          tagKey.clear();
          tagValue.clear();
          content.clear();
        }

        while (it.moveNext()) {
          if (it.current == '[') {
            release();
            isInTag = true;
            isInTagKey = true;
            tagRaw.write(it.current);
            lyricRaw.write(it.current);
          } else if (it.current == ':') {
            isInTagKey = isInTag ? false : isInTagKey;
            tagRaw.write(it.current);
            lyricRaw.write(it.current);
          } else if (it.current == ']') {
            isInTag = false;
            tagRaw.write(it.current);
            lyricRaw.write(it.current);
          } else {
            if (isInTag && isInTagKey) {
              tagKey.write(it.current);
              tagRaw.write(it.current);
            } else if (isInTag) {
              tagValue.write(it.current);
              tagRaw.write(it.current);
            } else {
              content.write(it.current);
            }
            lyricRaw.write(it.current);
          }
        }

        release();

        return results;
      })
      .expand((element) => element)
      .toList();
  final pairs = await pairsFuture;
  return _parsePairs(pairs);
}