From 588e3e73acbb6859ec76533f7711544e87676f6c Mon Sep 17 00:00:00 2001 From: AppleNeko2001 Date: Sun, 12 Jul 2020 15:35:03 +0900 Subject: [PATCH] Upload projects --- Opportunity.LrcParser.UnitTest/LineTests.cs | 8 +- .../Opportunity.LrcParser.UnitTest.csproj | 2 +- .../TimestampTests.cs | 8 +- Opportunity.LrcParser/Line.cs | 10 +- Opportunity.LrcParser/MetaDataType.cs | 22 +++- .../Opportunity.LrcParser.csproj | 22 ++-- Opportunity.LrcParser/Parser.cs | 2 +- Opportunity.LrcParser/TimeSpanExtension.cs | 108 ++++++++++++++++++ Opportunity.LrcParser/Timestamp.cs | 17 ++- README.md | 22 ++-- 10 files changed, 174 insertions(+), 47 deletions(-) create mode 100644 Opportunity.LrcParser/TimeSpanExtension.cs diff --git a/Opportunity.LrcParser.UnitTest/LineTests.cs b/Opportunity.LrcParser.UnitTest/LineTests.cs index 22cc103..a81da0a 100644 --- a/Opportunity.LrcParser.UnitTest/LineTests.cs +++ b/Opportunity.LrcParser.UnitTest/LineTests.cs @@ -16,10 +16,10 @@ public class LineTests [DataTestMethod] public void Create(string content, string expected) { - var ts = new DateTime(DateTime.Now.Ticks); + var ts = new TimeSpan(0); var line = new Line(ts, content); Assert.AreEqual(expected, line.Content); - Assert.AreEqual(ts.TimeOfDay.Ticks, line.Timestamp.Ticks); + Assert.AreEqual(ts.Ticks, line.Timestamp.Ticks); } [DataRow("", "", "", "", "")] @@ -35,11 +35,11 @@ public void Create(string content, string expected) [DataTestMethod] public void CreateWithSpeaker(string speaker, string expectedSpeaker, string lyrics, string expectedLyrics, string expected) { - var ts = new DateTime(DateTime.Now.Ticks); + var ts = new TimeSpan(DateTime.Now.Ticks); var line = new LineWithSpeaker(ts, speaker, lyrics); Assert.AreEqual(expectedSpeaker, line.Speaker); Assert.AreEqual(expectedLyrics, line.Lyrics); - Assert.AreEqual(ts.TimeOfDay.Ticks, line.Timestamp.Ticks); + Assert.AreEqual(ts.Ticks, line.Timestamp.Ticks); Assert.AreEqual(new Line(ts, expected).ToString(), line.ToString()); } } diff --git a/Opportunity.LrcParser.UnitTest/Opportunity.LrcParser.UnitTest.csproj b/Opportunity.LrcParser.UnitTest/Opportunity.LrcParser.UnitTest.csproj index 8fc69ca..29542f1 100644 --- a/Opportunity.LrcParser.UnitTest/Opportunity.LrcParser.UnitTest.csproj +++ b/Opportunity.LrcParser.UnitTest/Opportunity.LrcParser.UnitTest.csproj @@ -1,7 +1,7 @@ - netcoreapp2.0 + netcoreapp3.0 false diff --git a/Opportunity.LrcParser.UnitTest/TimestampTests.cs b/Opportunity.LrcParser.UnitTest/TimestampTests.cs index f7e5ae9..fc20027 100644 --- a/Opportunity.LrcParser.UnitTest/TimestampTests.cs +++ b/Opportunity.LrcParser.UnitTest/TimestampTests.cs @@ -10,10 +10,10 @@ public class TimestampTests [TestMethod] public void Create() { - Assert.AreEqual(new DateTime(1, 1, 1, 0, 0, 1, 100), Timestamp.Create(1, 100)); - Assert.AreEqual(new DateTime(1, 1, 1, 0, 0, 1, 100), Timestamp.Create(1100)); - Assert.AreEqual(new DateTime(1, 1, 1, 0, 1, 2, 100), Timestamp.Create(62, 100)); - Assert.AreEqual(new DateTime(1, 1, 1, 0, 1, 1, 100), Timestamp.Create(1, 1, 100)); + Assert.AreEqual(new TimeSpan(0, 0, 0, 1, 100), Timestamp.Create(1, 100)); + Assert.AreEqual(new TimeSpan(0, 0, 0, 1, 100), Timestamp.Create(1100)); + Assert.AreEqual(new TimeSpan(0, 0, 1, 2, 100), Timestamp.Create(62, 100)); + Assert.AreEqual(new TimeSpan(0, 0, 1, 1, 100), Timestamp.Create(1, 1, 100)); } } } diff --git a/Opportunity.LrcParser/Line.cs b/Opportunity.LrcParser/Line.cs index 007e1d2..9690394 100644 --- a/Opportunity.LrcParser/Line.cs +++ b/Opportunity.LrcParser/Line.cs @@ -21,22 +21,22 @@ public Line() { } /// /// Timestamp of this line. /// Lyrics of this line. - public Line(DateTime timestamp, string content) + public Line(TimeSpan timestamp, string content) { Timestamp = timestamp; this.content = (content ?? "").Trim(); } [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] - internal DateTime InternalTimestamp; + internal TimeSpan InternalTimestamp; /// /// Timestamp of this line of lyrics. /// /// of value is not . - public DateTime Timestamp + public TimeSpan Timestamp { get => this.InternalTimestamp; - set => this.InternalTimestamp = value.ToTimestamp(); + set => this.InternalTimestamp = value; } [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] @@ -94,7 +94,7 @@ public LineWithSpeaker() { } /// Timestamp of this line. /// Speaker of this line. /// Lyrics of this line. - public LineWithSpeaker(DateTime timestamp, string speaker, string lyrics) + public LineWithSpeaker(TimeSpan timestamp, string speaker, string lyrics) : base(timestamp, null) { this.Speaker = speaker; diff --git a/Opportunity.LrcParser/MetaDataType.cs b/Opportunity.LrcParser/MetaDataType.cs index 2b8425c..17e754e 100644 --- a/Opportunity.LrcParser/MetaDataType.cs +++ b/Opportunity.LrcParser/MetaDataType.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Globalization; namespace Opportunity.LrcParser { @@ -204,6 +205,17 @@ protected internal override string Stringify(object mataDataContent) } } + private static TimeSpan ParseOffsetString(string s) + { + var fmt = new NumberFormatInfo(); + fmt.NegativeSign = "−"; + s = s.Replace(',', '.'); + var number = double.Parse(s, fmt); + var tick = (long)(number * 10000); + var result = new TimeSpan(tick); + return result; + } + #region Pre-defined /// /// Pre-defined . @@ -216,15 +228,17 @@ protected internal override string Stringify(object mataDataContent) ["ti"] = new NoValidateMetaDataType("ti"), ["au"] = new NoValidateMetaDataType("au"), ["by"] = new NoValidateMetaDataType("by"), - ["offset"] = new DelegateMetaDataType("offset", v => TimeSpan.FromTicks((long)(double.Parse(v, System.Globalization.NumberStyles.Any) * 10000)), ts => ts.TotalMilliseconds.ToString("+0.#;-0.#"), default), + ["offset"] = new DelegateMetaDataType("offset", + v => ParseOffsetString(v),//TimeSpan.FromTicks((long)(double.Parse(v, System.Globalization.NumberStyles.Any) * 10000)), + ts => ts.TotalMilliseconds.ToString("+0.#;-0.#"), default), ["re"] = new NoValidateMetaDataType("re"), ["ve"] = new NoValidateMetaDataType("ve"), - ["length"] = new DelegateMetaDataType("length", v => + ["length"] = new DelegateMetaDataType("length", v => { - if (DateTimeExtension.TryParseLrcString(v, 0, v.Length, out var r)) + if (TimeSpanExtension.TryParseLrcString(v, 0, v.Length, out var r)) return r; throw new ArgumentException("Invalid length string."); - }, d => d.ToTimestamp().ToLrcStringShort(), default), + }, d => d.ToLrcStringShort(), default), }); /// diff --git a/Opportunity.LrcParser/Opportunity.LrcParser.csproj b/Opportunity.LrcParser/Opportunity.LrcParser.csproj index 7105663..809e377 100644 --- a/Opportunity.LrcParser/Opportunity.LrcParser.csproj +++ b/Opportunity.LrcParser/Opportunity.LrcParser.csproj @@ -1,20 +1,24 @@ - + - netstandard1.0 + netstandard2.0 Library - Opportunity - An library for lrc files. + Opportunity (Project owner), mod by appleneko2001 + An lyric file parser (.lrc parser) for C# project. +Mod by appleneko2001 true - https://github.com/OpportunityLiu/LrcParser - https://github.com/OpportunityLiu/LrcParser + https://github.com/appleneko2001/LrcParser + https://github.com/appleneko2001/LrcParser https://github.com/OpportunityLiu/LrcParser/blob/master/LICENSE 1.0.4 - * Fix bug + * Use TimeSpan instead of DateTime on Timestamp property +* Targeted to .Net Standard 2.0 lrc; lyrics; parser; git + Opportunity.LrcParser (TimeSpan mod) + Opportunity (Project owner), mod by appleneko2001 @@ -29,4 +33,8 @@ true + + + + diff --git a/Opportunity.LrcParser/Parser.cs b/Opportunity.LrcParser/Parser.cs index 7e8611f..6685c0d 100644 --- a/Opportunity.LrcParser/Parser.cs +++ b/Opportunity.LrcParser/Parser.cs @@ -113,7 +113,7 @@ private void analyzeLine(int next) var oldPos = this.currentPosition; if (!readTag(next, out var tagStart, out var tagEnd)) break; - if (DateTimeExtension.TryParseLrcString(this.Data, tagStart, tagEnd, out var time)) + if (TimeSpanExtension.TryParseLrcString(this.Data, tagStart, tagEnd, out var time)) { this.Lines.Add(new TLine { InternalTimestamp = time }); isIdTagLine = false; diff --git a/Opportunity.LrcParser/TimeSpanExtension.cs b/Opportunity.LrcParser/TimeSpanExtension.cs new file mode 100644 index 0000000..7c6b600 --- /dev/null +++ b/Opportunity.LrcParser/TimeSpanExtension.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Opportunity.LrcParser +{ + internal static class TimeSpanExtension + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string ToString(this TimeSpan dateTime, string mFormat, string smSep, string sFormat) + { + var t = dateTime.Ticks; + var m = t / TICKS_PER_MINUTE; + t -= m * TICKS_PER_MINUTE; + var s = (double)t / TICKS_PER_SECOND; + return m.ToString(mFormat) + smSep + s.ToString(sFormat); + } + + public static string ToLrcString(this TimeSpan timeSpan) + => timeSpan.ToString("D2", ":", "00.00"); + + public static string ToLrcStringRaw(this TimeSpan timeSpan) + => timeSpan.ToString("D2", ":", "00.00######"); + + public static string ToLrcStringShort(this TimeSpan timeSpan) + => timeSpan.ToString("D2", ":", "00"); + + public static bool TryParseLrcString(string value, int start, int end, out TimeSpan result) + { + var m = 0; + var s = 0; + var t = 0; + + var i = start; + for (; i < end; i++) + { + var v = value[i] - '0'; + if (v >= 0 && v <= 9) + m = m * 10 + v; + else if (value[i] == ':') + { + i++; + break; + } + else if (char.IsWhiteSpace(value, i)) + { + continue; + } + else + { + goto ERROR; + } + } + + for (; i < end; i++) + { + var v = value[i] - '0'; + if (v >= 0 && v <= 9) + s = s * 10 + v; + else if (value[i] == '.') + { + i++; + break; + } + else if (char.IsWhiteSpace(value, i)) + { + continue; + } + else + { + goto ERROR; + } + } + + var weight = (int)(TICKS_PER_SECOND / 10); + for (; i < end; i++) + { + var v = value[i] - '0'; + if (v >= 0 && v <= 9) + { + t += weight * v; + weight /= 10; + } + else if (char.IsWhiteSpace(value, i)) + { + continue; + } + else + { + goto ERROR; + } + } + ; + result = new TimeSpan(t + TICKS_PER_SECOND * s + TICKS_PER_MINUTE * m); + return true; + + ERROR: + result = default; + return false; + } + + public const long TICKS_PER_MINUTE = TICKS_PER_SECOND * 60; + public const long TICKS_PER_SECOND = TICKS_PER_MILLISECOND * 1000; + public const long TICKS_PER_MILLISECOND = 10_000; + + } +} diff --git a/Opportunity.LrcParser/Timestamp.cs b/Opportunity.LrcParser/Timestamp.cs index e43a991..aeef675 100644 --- a/Opportunity.LrcParser/Timestamp.cs +++ b/Opportunity.LrcParser/Timestamp.cs @@ -1,5 +1,5 @@ using System; -using static Opportunity.LrcParser.DateTimeExtension; +using static Opportunity.LrcParser.TimeSpanExtension; namespace Opportunity.LrcParser { @@ -16,7 +16,7 @@ public static class Timestamp /// Millisecond, 0 ~ 999. /// of timestamp. /// Argument out of range. - public static DateTime Create(int minute, int second, int millisecond) + public static TimeSpan Create(int minute, int second, int millisecond) { if (minute < 0) throw new ArgumentOutOfRangeException(nameof(minute)); @@ -24,9 +24,7 @@ public static DateTime Create(int minute, int second, int millisecond) throw new ArgumentOutOfRangeException(nameof(second)); if (unchecked((uint)millisecond >= 1000U)) throw new ArgumentOutOfRangeException(nameof(millisecond)); - return new DateTime(minute * TICKS_PER_MINUTE - + second * TICKS_PER_SECOND - + millisecond * TICKS_PER_MILLISECOND); + return new TimeSpan(0,0,minute, second, millisecond); } /// @@ -36,14 +34,13 @@ public static DateTime Create(int minute, int second, int millisecond) /// Millisecond, 0 ~ 999. /// of timestamp. /// Argument out of range. - public static DateTime Create(int second, int millisecond) + public static TimeSpan Create(int second, int millisecond) { if (second < 0) throw new ArgumentOutOfRangeException(nameof(second)); if (unchecked((uint)millisecond >= 1000U)) throw new ArgumentOutOfRangeException(nameof(millisecond)); - return new DateTime(second * TICKS_PER_SECOND - + millisecond * TICKS_PER_MILLISECOND); + return new TimeSpan(0, 0, 0, second, millisecond); } /// @@ -52,11 +49,11 @@ public static DateTime Create(int second, int millisecond) /// Millisecond, > 0. /// of timestamp. /// Argument out of range. - public static DateTime Create(int millisecond) + public static TimeSpan Create(int millisecond) { if (millisecond < 0) throw new ArgumentOutOfRangeException(nameof(millisecond)); - return new DateTime(millisecond * TICKS_PER_MILLISECOND); + return new TimeSpan(0,0,0,0,millisecond); } } } diff --git a/README.md b/README.md index 0a708ac..ef817c8 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# LrcParser -[![Build status](https://ci.appveyor.com/api/projects/status/7ne8mex2di844260?svg=true)](https://ci.appveyor.com/project/OpportunityLiu/lrcparser) -[![NuGet](https://img.shields.io/nuget/v/Opportunity.LrcParser.svg)](https://www.nuget.org/packages/Opportunity.LrcParser/) -An library for lrc files. +### LrcParser mod by appleneko2001 +An lyric file parser (.lrc parser) for C# project. +This is modded version with slightly changes framework of working. +for original ver. ====>> https://github.com/OpportunityLiu/LrcParser -## Quick Start +##### Changes: +* Use TimeSpan type instead of DateTime on timestamp property +* UnitTest slightly changed to support this library -### Parse An `LRC` File +##### Requirements: +This modded library uses .Net Standard 2.0, so your project should targeting .Net Framework to 4.6.1 at least +for more information about minimum requirement of standard: https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support -To parse `lrc` files, use `Lyrics.Parse(string)` method, overloads can be used for variants of `lrc` formats. - -### Stringify A `Lyrics` Instance - -To create `lrc` file with a `Lyrics` instance, call its `ToString()` method, you can also use `ToString(LyricsFormat)` overload to specify format settings. +Or if you really want to use more older framework version, you can try to rebuild this library and targeting to .Net Standard 1.1 (or create new library project and copy-paste all codes. UnitTest are optional component). \ No newline at end of file