SSTFormat.v1/v2.スコア クラスの '行を読み込む()' を private 化。バージョンによって前処理の内容に左右されるのはよろしくないため。
/// <param name="path">
/// SSTF ファイルのパス。
/// </param>
+ /// <returns>
+ /// 取得された SSTF バージョン。
+ /// SSTF ファイルにバージョンの記載がない場合には、1.0.0.0 が返される。
+ /// </returns>
+ /// <remarks>
+ /// SSTFVersion の指定は、先頭行でのみ可能。
+ /// 例: "SSTFVersion 1.0.0.0"
+ /// </remarks>
public static Version CreateVersionFromFile( string path )
{
if( false == File.Exists( path ) )
using( var reader = new StreamReader( path, Encoding.UTF8 ) )
{
- // 先頭行を読み込む。
- string line = reader.ReadLine();
+ string バージョン文字列 = "1.0.0.0"; // 既定のバージョン
+ string トークン = "SSTFVersion";
- }
+ // 最初の行に指定がなかったら、既定のバージョンとする。
+ string 先頭行 = reader.ReadLine();
- return null;
+ if( 先頭行.StartsWith( トークン ) )
+ バージョン文字列 = 先頭行.Substring( トークン.Length ).Trim();
+
+ return new Version( バージョン文字列 );
+ }
}
/// <summary>
}
/// <summary>
- /// Stream から1行読み込み、コメントや改行等の前処理を行ってから返す。
- /// </summary>
- /// <param name="reader">
- /// 行の読み込み元。読み込んだ分、ポジションは進められる。
- /// </param>
- /// <returns>
- /// 読み込んで、コメントや改行等の前処理を適用したあとの行を返す。
- /// reader が EOF だった場合には null を返す。
- /// </returns>
- public static string 行を読み込む( StreamReader reader )
- {
- if( reader.EndOfStream )
- return null;
-
- // 1行読み込む。
- string 行 = reader.ReadLine();
-
- // (1) 改行とTABを空白文字に変換し、先頭末尾の空白を削除する。
- 行 = 行.Replace( Environment.NewLine, " " );
- 行 = 行.Replace( '\t', ' ' );
- 行 = 行.Trim();
-
- // (2) 行中の '#' 以降はコメントとして除外する。
- int 区切り位置 = 行.IndexOf( '#' );
- if( 0 <= 区切り位置 )
- {
- 行 = 行.Substring( 0, 区切り位置 );
- 行 = 行.Trim();
- }
-
- return 行;
- }
-
- /// <summary>
/// 指定された曲データファイルを読み込む。
/// 失敗すれば何らかの例外を発出する。
/// </summary>
{
// 1行ずつ読み込む。
行番号++;
- string 行 = 行を読み込む( sr );
+ string 行 = this._行を読み込む( sr );
if( 行.Nullまたは空である() )
continue;
#region " 小節番号を取得・設定。"
//-----------------
- string 小節番号文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
+ string 小節番号文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
if( 小節番号文字列.Nullまたは空である() )
{
//-----------------
パラメータ = パラメータ.Substring( 1 ).Trim();
- string 小節長倍率文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
+ string 小節長倍率文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
if( 小節長倍率文字列.Nullまたは空である() )
{
Log.ERROR( $"Part(小節番号)コマンドに小節長倍率の記述がありません。この属性をスキップします。[{行番号}行目]" );
#region " チップ位置を取得する。"
//-----------------
int チップ位置 = 0;
- string 位置番号文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string 位置番号文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
// 文法チェック。
#region " 音量 "
//-----------------
chipTokens[ i ] = chipTokens[ i ].Substring( 1 ).Trim();
- string 音量文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string 音量文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
int チップ音量 = 0;
chipTokens[ i ] = chipTokens[ i ].Substring( 1 ).Trim();
- string BPM文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string BPM文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
if( BPM文字列.Nullまたは空である() )
// 1行ずつ読み込む。
行番号++;
- string 行 = 行を読み込む( sr );
+ string 行 = this._行を読み込む( sr );
if( 行.Nullまたは空である() )
continue;
/// 取出文字列の先頭にある数字(小数点も有効)の連続した部分を取り出して、戻り値として返す。
/// また、取出文字列から取り出した数字文字列部分を除去した文字列を再度格納する。
/// </summary>
- protected string 指定された文字列の先頭から数字文字列を取り出す( ref string 取出文字列 )
+ private string _指定された文字列の先頭から数字文字列を取り出す( ref string 取出文字列 )
{
int 桁数 = 0;
while( ( 桁数 < 取出文字列.Length ) && ( char.IsDigit( 取出文字列[ 桁数 ] ) || 取出文字列[ 桁数 ] == '.' ) )
return 数字文字列;
}
+
+ /// <summary>
+ /// Stream から1行読み込み、コメントや改行等の前処理を行ってから返す。
+ /// </summary>
+ /// <param name="reader">
+ /// 行の読み込み元。読み込んだ分、ポジションは進められる。
+ /// </param>
+ /// <returns>
+ /// 読み込んで、コメントや改行等の前処理を適用したあとの行を返す。
+ /// reader が EOF だった場合には null を返す。
+ /// </returns>
+ private string _行を読み込む( StreamReader reader )
+ {
+ if( reader.EndOfStream )
+ return null;
+
+ // 1行読み込む。
+ string 行 = reader.ReadLine();
+
+ // (1) 改行とTABを空白文字に変換し、先頭末尾の空白を削除する。
+ 行 = 行.Replace( Environment.NewLine, " " );
+ 行 = 行.Replace( '\t', ' ' );
+ 行 = 行.Trim();
+
+ // (2) 行中の '#' 以降はコメントとして除外する。
+ int 区切り位置 = 行.IndexOf( '#' );
+ if( 0 <= 区切り位置 )
+ {
+ 行 = 行.Substring( 0, 区切り位置 );
+ 行 = 行.Trim();
+ }
+
+ return 行;
+ }
}
}
}
/// <summary>
- /// Stream から1行読み込み、コメントや改行等の前処理を行ってから返す。
- /// </summary>
- /// <param name="reader">
- /// 行の読み込み元。読み込んだ分、ポジションは進められる。
- /// </param>
- /// <returns>
- /// 読み込んで、コメントや改行等の前処理を適用したあとの行を返す。
- /// reader が EOF だった場合には null を返す。
- /// </returns>
- public static string 行を読み込む( StreamReader reader )
- {
- if( reader.EndOfStream )
- return null;
-
- // 1行読み込む。
- string 行 = reader.ReadLine();
-
- // (1) 改行とTABを空白文字に変換し、先頭末尾の空白を削除する。
- 行 = 行.Replace( Environment.NewLine, " " );
- 行 = 行.Replace( '\t', ' ' );
- 行 = 行.Trim();
-
- // (2) 行中の '#' 以降はコメントとして除外する。
- int 区切り位置 = 行.IndexOf( '#' );
- if( 0 <= 区切り位置 )
- {
- 行 = 行.Substring( 0, 区切り位置 );
- 行 = 行.Trim();
- }
-
- return 行;
- }
-
- /// <summary>
/// 指定された曲データファイルを読み込む。
/// 失敗すれば何らかの例外を発出する。
/// </summary>
{
// 1行ずつ読み込む。
行番号++;
- string 行 = 行を読み込む( sr );
+ string 行 = this._行を読み込む( sr );
if( 行.Nullまたは空である() )
continue;
#region " 小節番号を取得・設定。"
//-----------------
- string 小節番号文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
+ string 小節番号文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
if( 小節番号文字列.Nullまたは空である() )
{
//-----------------
パラメータ = パラメータ.Substring( 1 ).Trim();
- string 小節長倍率文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
+ string 小節長倍率文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref パラメータ );
if( 小節長倍率文字列.Nullまたは空である() )
{
Log.ERROR( $"Part(小節番号)コマンドに小節長倍率の記述がありません。この属性をスキップします。[{行番号}行目]" );
#region " チップ位置を取得する。"
//-----------------
int チップ位置 = 0;
- string 位置番号文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string 位置番号文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
// 文法チェック。
#region " 音量 "
//-----------------
chipTokens[ i ] = chipTokens[ i ].Substring( 1 ).Trim();
- string 音量文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string 音量文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
int チップ音量 = 0;
chipTokens[ i ] = chipTokens[ i ].Substring( 1 ).Trim();
- string BPM文字列 = this.指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
+ string BPM文字列 = this._指定された文字列の先頭から数字文字列を取り出す( ref chipTokens[ i ] );
chipTokens[ i ].Trim();
if( BPM文字列.Nullまたは空である() )
// 1行ずつ読み込む。
行番号++;
- string 行 = 行を読み込む( sr );
+ string 行 = this._行を読み込む( sr );
if( 行.Nullまたは空である() )
continue;
/// 取出文字列の先頭にある数字(小数点も有効)の連続した部分を取り出して、戻り値として返す。
/// また、取出文字列から取り出した数字文字列部分を除去した文字列を再度格納する。
/// </summary>
- protected string 指定された文字列の先頭から数字文字列を取り出す( ref string 取出文字列 )
+ private string _指定された文字列の先頭から数字文字列を取り出す( ref string 取出文字列 )
{
int 桁数 = 0;
while( ( 桁数 < 取出文字列.Length ) && ( char.IsDigit( 取出文字列[ 桁数 ] ) || 取出文字列[ 桁数 ] == '.' ) )
return 数字文字列;
}
+
+ /// <summary>
+ /// Stream から1行読み込み、コメントや改行等の前処理を行ってから返す。
+ /// </summary>
+ /// <param name="reader">
+ /// 行の読み込み元。読み込んだ分、ポジションは進められる。
+ /// </param>
+ /// <returns>
+ /// 読み込んで、コメントや改行等の前処理を適用したあとの行を返す。
+ /// reader が EOF だった場合には null を返す。
+ /// </returns>
+ private string _行を読み込む( StreamReader reader )
+ {
+ if( reader.EndOfStream )
+ return null;
+
+ // 1行読み込む。
+ string 行 = reader.ReadLine();
+
+ // (1) 改行とTABを空白文字に変換し、先頭末尾の空白を削除する。
+ 行 = 行.Replace( Environment.NewLine, " " );
+ 行 = 行.Replace( '\t', ' ' );
+ 行 = 行.Trim();
+
+ // (2) 行中の '#' 以降はコメントとして除外する。
+ int 区切り位置 = 行.IndexOf( '#' );
+ if( 0 <= 区切り位置 )
+ {
+ 行 = 行.Substring( 0, 区切り位置 );
+ 行 = 行.Trim();
+ }
+
+ return 行;
+ }
}
}
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="v1\スコアTests.cs" />
- <Compile Include="v2\スコアTests.cs" />
+ <Compile Include="VersionTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SSTFormat\SSTFormat.csproj">
--- /dev/null
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using SSTFormat;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace SSTFormat.Tests
+{
+ [TestClass()]
+ public class VersionTests
+ {
+ private void ファイルに新規出力する( string tempName, string 出力文字列 )
+ {
+ using( var sw = new StreamWriter( tempName, false, Encoding.UTF8 ) )
+ {
+ sw.WriteLine( 出力文字列 );
+ }
+ }
+
+ [TestMethod()]
+ public void CreateVersionFromFileTest()
+ {
+ string tempName = Path.GetTempFileName();
+ try
+ {
+ // 正常系。
+
+ #region " 正常な記述。"
+ this.ファイルに新規出力する( tempName, @"SSTFVersion 1.2.3.4" );
+ Assert.IsTrue( new Version( 1, 2, 3, 4 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+ #region " 省略時は 1.0.0.0 になる。"
+ this.ファイルに新規出力する( tempName, @"# コメントやよー" );
+ Assert.IsTrue( new Version( 1, 0, 0, 0 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+ #region " トークンとバージョン番号の間に空白がなくても大丈夫。"
+ this.ファイルに新規出力する( tempName, @"SSTFVersion5.6.7.8" );
+ Assert.IsTrue( new Version( 5, 6, 7, 8 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+ #region " Revision は省略可能。"
+ this.ファイルに新規出力する( tempName, @"SSTFVersion 9.10.11" );
+ Assert.IsTrue( new Version( 9, 10, 11 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+ #region " Build と Revision は省略可能。"
+ this.ファイルに新規出力する( tempName, @"SSTFVersion 12.13" );
+ Assert.IsTrue( new Version( 12, 13 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+
+ // 準正常系。
+
+ #region " Major と Minor は省略不可。"
+ this.ファイルに新規出力する( tempName, @"SSTFVersion 12" );
+ try
+ {
+ var ver = Version.CreateVersionFromFile( tempName );
+ }
+ catch( System.ArgumentException )
+ {
+ // 成功。
+ }
+ this.ファイルに新規出力する( tempName, @"SSTFVersion " );
+ try
+ {
+ var ver = Version.CreateVersionFromFile( tempName );
+ }
+ catch( System.ArgumentException )
+ {
+ // 成功。
+ }
+ #endregion
+ #region " 2行目以降に指定しても無視されて、1.0.0.0 になる。"
+ this.ファイルに新規出力する( tempName, @"# 1行目やよー\nSSTFVersion 1.2.3.4\n# 3行目やよー" );
+ Assert.IsTrue( new Version( 1, 0, 0, 0 ) == Version.CreateVersionFromFile( tempName ) );
+ #endregion
+ }
+ finally
+ {
+ File.Delete( tempName );
+ }
+ }
+ }
+}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using SSTFormat.v1;
[TestClass()]
public class スコアTests
{
- private void ファイルに新規出力する( string ファイル名, string 文字列 )
- {
- using( var sw = new StreamWriter( new FileStream( ファイル名, FileMode.Create ) ) )
- {
- sw.WriteLine( 文字列 );
- }
- }
-
[TestMethod()]
public void コマンドのパラメータ文字列部分を返すTest()
{
#endregion
}
-
- [TestMethod()]
- public void 行を読み込むTest()
- {
- string tempPath = Path.GetTempFileName();
- try
- {
- // 正常系。
-
- #region " 行の先頭に '#' がある場合、空文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"# これはコメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行の途中に '#' がある場合、その直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これは#コメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これは", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行の末尾に '#' がある場合、その直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これはコメントです。#" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これはコメントです。", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行に複数の '#' がある場合、最初の '#' の直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これ#はコメント#です。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これ", スコア.行を読み込む( reader ) );
- }
- this.ファイルに新規出力する( tempPath, @"#これ#はコメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- this.ファイルに新規出力する( tempPath, @"#これはコメントです。#" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- #endregion
- }
- finally
- {
- File.Delete( tempPath );
- }
- }
}
}
\ No newline at end of file
+++ /dev/null
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using SSTFormat.v2;
-
-namespace SSTFormat.v2.Tests
-{
- [TestClass()]
- public class スコアTests
- {
- private void ファイルに新規出力する( string ファイル名, string 文字列 )
- {
- using( var sw = new StreamWriter( new FileStream( ファイル名, FileMode.Create ) ) )
- {
- sw.WriteLine( 文字列 );
- }
- }
-
- [TestMethod()]
- public void 行を読み込むTest()
- {
- string tempPath = Path.GetTempFileName();
- try
- {
- // 正常系。
-
- #region " 行の先頭に '#' がある場合、空文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"# これはコメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行の途中に '#' がある場合、その直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これは#コメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これは", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行の末尾に '#' がある場合、その直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これはコメントです。#" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これはコメントです。", スコア.行を読み込む( reader ) );
- }
- #endregion
- #region " 行に複数の '#' がある場合、最初の '#' の直前までの文字列が得られる。"
- this.ファイルに新規出力する( tempPath, @"これ#はコメント#です。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"これ", スコア.行を読み込む( reader ) );
- }
- this.ファイルに新規出力する( tempPath, @"#これ#はコメントです。" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- this.ファイルに新規出力する( tempPath, @"#これはコメントです。#" );
- using( var reader = new StreamReader( tempPath ) )
- {
- Assert.AreEqual( @"", スコア.行を読み込む( reader ) );
- }
- #endregion
- }
- finally
- {
- File.Delete( tempPath );
- }
- }
- }
-}