Skip to content

Commit

Permalink
Upload projects
Browse files Browse the repository at this point in the history
  • Loading branch information
appleneko2001 committed Jul 12, 2020
1 parent a10a842 commit 588e3e7
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 47 deletions.
8 changes: 4 additions & 4 deletions Opportunity.LrcParser.UnitTest/LineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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("", "", "", "", "")]
Expand All @@ -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());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
8 changes: 4 additions & 4 deletions Opportunity.LrcParser.UnitTest/TimestampTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
}
10 changes: 5 additions & 5 deletions Opportunity.LrcParser/Line.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ public Line() { }
/// </summary>
/// <param name="timestamp">Timestamp of this line.</param>
/// <param name="content">Lyrics of this line.</param>
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;
/// <summary>
/// Timestamp of this line of lyrics.
/// </summary>
/// <exception cref="ArgumentException"><see cref="DateTime.Kind"/> of value is not <see cref="DateTimeKind.Unspecified"/>.</exception>
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)]
Expand Down Expand Up @@ -94,7 +94,7 @@ public LineWithSpeaker() { }
/// <param name="timestamp">Timestamp of this line.</param>
/// <param name="speaker">Speaker of this line.</param>
/// <param name="lyrics">Lyrics of this line.</param>
public LineWithSpeaker(DateTime timestamp, string speaker, string lyrics)
public LineWithSpeaker(TimeSpan timestamp, string speaker, string lyrics)
: base(timestamp, null)
{
this.Speaker = speaker;
Expand Down
22 changes: 18 additions & 4 deletions Opportunity.LrcParser/MetaDataType.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;

namespace Opportunity.LrcParser
{
Expand Down Expand Up @@ -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
/// <summary>
/// Pre-defined <see cref="MetaDataType"/>.
Expand All @@ -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<TimeSpan>("offset", v => TimeSpan.FromTicks((long)(double.Parse(v, System.Globalization.NumberStyles.Any) * 10000)), ts => ts.TotalMilliseconds.ToString("+0.#;-0.#"), default),
["offset"] = new DelegateMetaDataType<TimeSpan>("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<DateTime>("length", v =>
["length"] = new DelegateMetaDataType<TimeSpan>("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),
});

/// <summary>
Expand Down
22 changes: 15 additions & 7 deletions Opportunity.LrcParser/Opportunity.LrcParser.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
<Authors>Opportunity</Authors>
<Description>An library for lrc files.</Description>
<Authors>Opportunity (Project owner), mod by appleneko2001</Authors>
<Description>An lyric file parser (.lrc parser) for C# project.
Mod by appleneko2001</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageProjectUrl>https://github.com/OpportunityLiu/LrcParser</PackageProjectUrl>
<RepositoryUrl>https://github.com/OpportunityLiu/LrcParser</RepositoryUrl>
<PackageProjectUrl>https://github.com/appleneko2001/LrcParser</PackageProjectUrl>
<RepositoryUrl>https://github.com/appleneko2001/LrcParser</RepositoryUrl>
<PackageLicenseUrl>https://github.com/OpportunityLiu/LrcParser/blob/master/LICENSE</PackageLicenseUrl>
<Version>1.0.4</Version>
<PackageReleaseNotes>* Fix bug</PackageReleaseNotes>
<PackageReleaseNotes>* Use TimeSpan instead of DateTime on Timestamp property
* Targeted to .Net Standard 2.0</PackageReleaseNotes>
<PackageTags>lrc; lyrics; parser;</PackageTags>
<RepositoryType>git</RepositoryType>
<PackageId>Opportunity.LrcParser (TimeSpan mod)</PackageId>
<Company>Opportunity (Project owner), mod by appleneko2001</Company>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand All @@ -29,4 +33,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<Compile Remove="DateTimeExtension.cs" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Opportunity.LrcParser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
108 changes: 108 additions & 0 deletions Opportunity.LrcParser/TimeSpanExtension.cs
Original file line number Diff line number Diff line change
@@ -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;

}
}
17 changes: 7 additions & 10 deletions Opportunity.LrcParser/Timestamp.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using static Opportunity.LrcParser.DateTimeExtension;
using static Opportunity.LrcParser.TimeSpanExtension;

namespace Opportunity.LrcParser
{
Expand All @@ -16,17 +16,15 @@ public static class Timestamp
/// <param name="millisecond">Millisecond, 0 ~ 999.</param>
/// <returns><see cref="DateTime"/> of timestamp.</returns>
/// <exception cref="ArgumentOutOfRangeException">Argument out of range.</exception>
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));
if (unchecked((uint)second >= 60U))
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);
}

/// <summary>
Expand All @@ -36,14 +34,13 @@ public static DateTime Create(int minute, int second, int millisecond)
/// <param name="millisecond">Millisecond, 0 ~ 999.</param>
/// <returns><see cref="DateTime"/> of timestamp.</returns>
/// <exception cref="ArgumentOutOfRangeException">Argument out of range.</exception>
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);
}

/// <summary>
Expand All @@ -52,11 +49,11 @@ public static DateTime Create(int second, int millisecond)
/// <param name="millisecond">Millisecond, > 0.</param>
/// <returns><see cref="DateTime"/> of timestamp.</returns>
/// <exception cref="ArgumentOutOfRangeException">Argument out of range.</exception>
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);
}
}
}
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -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<TLine>` 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).

0 comments on commit 588e3e7

Please sign in to comment.