using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
+using System.Runtime.Serialization.Json;
+using System.Text;
+using System.Threading;
using System.Xml;
using SharpDX;
}
/// <summary>
- /// DataContract オブジェクトをシリアル化してXMLファイルに保存する。
+ /// DataContract オブジェクトをシリアル化してファイルに保存する。
/// 失敗すれば例外を発出。
/// </summary>
- public static void 保存する( object 保存するオブジェクト, string XMLファイルパス )
+ public static void 保存する( object 保存するオブジェクト, string ファイルパス, bool UseSimpleDictionaryFormat = true )
{
- var serializer = new DataContractSerializer( 保存するオブジェクト.GetType() );
-
- var settings = new XmlWriterSettings() {
- Encoding = new System.Text.UTF8Encoding( false ), // UTF-8, BOMなし
- NewLineChars = Environment.NewLine, // 改行コード
- NewLineHandling = NewLineHandling.Replace, // 改行コードを統一(上書き)
- Indent = true, // 改行&インデントを使う(falseにすると改行もされなくなる)
- };
-
- using( var writer = XmlWriter.Create( XMLファイルパス, settings ) )
+ using( var stream = File.Open( ファイルパス, FileMode.Create ) )
{
- serializer.WriteObject( writer, 保存するオブジェクト );
+ var culture = Thread.CurrentThread.CurrentCulture;
+ try
+ {
+ Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+
+ using( var writer = JsonReaderWriterFactory.CreateJsonWriter( stream, Encoding.UTF8, true, true ) )
+ {
+ var serializer = new DataContractJsonSerializer( 保存するオブジェクト.GetType(), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = UseSimpleDictionaryFormat } );
+ serializer.WriteObject( writer, 保存するオブジェクト );
+ writer.Flush();
+ }
+ }
+ finally
+ {
+ Thread.CurrentThread.CurrentCulture = culture;
+ }
}
}
/// <summary>
- /// XMLファイルを逆シリアル化して、DataContract オブジェクトを生成する。
+ /// ファイルを逆シリアル化して、DataContract オブジェクトを生成する。
/// 失敗すれば例外を発出。
/// </summary>
/// <remarks>
/// DataContract 属性を持つ型の逆シリアル時には、コンストラクタは呼び出されないので注意。
/// 各メンバは 0 または null になるが、それがイヤなら OnDeserializing コールバックを用意して、逆シリアル化の前に初期化すること。
/// </remarks>
- public static T 復元する<T>( string XMLファイルパス ) where T : class, new()
+ public static T 復元する<T>( string ファイルパス, bool UseSimpleDictionaryFormat = true ) where T : class, new()
{
T dataContract;
- var serializer = new DataContractSerializer( typeof( T ) );
-
- using( var reader = XmlReader.Create( XMLファイルパス ) )
+ using( var stream = File.OpenRead( ファイルパス ) )
{
- dataContract = ( T ) serializer.ReadObject( reader );
+ var culture = Thread.CurrentThread.CurrentCulture;
+ try
+ {
+ var serialier = new DataContractJsonSerializer( typeof( T ), new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = UseSimpleDictionaryFormat } );
+ dataContract = (T) serialier.ReadObject( stream );
+ }
+ finally
+ {
+ Thread.CurrentThread.CurrentCulture = culture;
+ }
}
return dataContract;
}
/// <summary>
- /// XMLファイルを逆シリアル化して、DataContract オブジェクトを生成する。
+ /// ファイルを逆シリアル化して、DataContract オブジェクトを生成する。
/// </summary>
/// <remarks>
- /// 復元に失敗すれば、新規にインスタンスを生成し、XML ファイルに保存してから返す。
+ /// 復元に失敗すれば、新規にインスタンスを生成し、ファイルに保存してから返す。
/// DataContract 属性を持つ型の逆シリアル時には、コンストラクタは呼び出されないので注意。
/// 各メンバは 0 または null になるが、それがイヤなら OnDeserializing コールバックを用意して、逆シリアル化の前に初期化すること。
/// </remarks>
- public static T 復元または新規作成する<T>( string XMLファイルパス ) where T : class, new()
+ public static T 復元または新規作成する<T>( string ファイルパス, bool UseSimpleDictionaryFormat = true ) where T : class, new()
{
T obj;
- if( File.Exists( XMLファイルパス ) )
+ if( File.Exists( ファイルパス ) )
{
try
{
- obj = Utilities.復元する<T>( XMLファイルパス );
- Log.Info( $"XMLファイルから{typeof( T ).Name}を復元しました。[{XMLファイルパス}]" );
+ obj = Utilities.復元する<T>( ファイルパス, UseSimpleDictionaryFormat );
+ Log.Info( $"ファイルから{typeof( T ).Name}を復元しました。[{ファイルパス}]" );
}
catch( Exception e )
{
- Log.WARNING( $"XMLファイルからの復元に失敗しました。初期状態で生成します。[{e.Message}][{XMLファイルパス}]" );
+ Log.WARNING( $"ファイルからの復元に失敗しました。初期状態で生成します。[{e.Message}][{ファイルパス}]" );
obj = new T();
}
}
else
{
- Log.WARNING( $"{typeof(T).Name}ファイルが存在しません。新規作成します。[{XMLファイルパス}]" );
+ Log.WARNING( $"{typeof(T).Name}ファイルが存在しません。新規作成します。[{ファイルパス}]" );
obj = new T();
- Utilities.保存する( obj, XMLファイルパス );
+ Utilities.保存する( obj, ファイルパス, UseSimpleDictionaryFormat );
}
return obj;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
-using System.Xml;
using SharpDX.DirectInput;
using FDK;
}
/// <summary>
- /// XMLファイルに保存する。
+ /// ファイルに保存する。
/// </summary>
public void 保存する()
{
using( Log.Block( Utilities.現在のメソッド名 ) )
{
- var xmlPath = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _KeyBindingsXmlファイルパス );
- Utilities.保存する( this, xmlPath );
+ var path = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _KeyBindingsファイルパス );
+ Utilities.保存する( this, path, false ); // キーが struct なので、SimplayDictionary を使うとおかしくなる。
}
}
/// <summary>
- /// XMLファイルから復元する。
+ /// ファイルから復元する。
/// </summary>
public static キーバインディング 復元する()
{
using( Log.Block( Utilities.現在のメソッド名 ) )
{
- var xmlPath = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _KeyBindingsXmlファイルパス );
- return Utilities.復元または新規作成する<キーバインディング>( xmlPath );
+ var path = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _KeyBindingsファイルパス );
+ return Utilities.復元または新規作成する<キーバインディング>( path, false ); // キーが struct なので、SimplayDictionary を使うとおかしくなる。
}
}
/// <summary>
- /// キーバインディングを保存する XML ファイルのパス。
+ /// キーバインディングを保存するファイルのパス。
/// </summary>
- private static readonly string _KeyBindingsXmlファイルパス = @"$(AppData)\KeyBindings.xml";
+ private static readonly string _KeyBindingsファイルパス = @"$(AppData)\KeyBindings.json";
/// <summary>
/// コンストラクタ時または逆シリアル化時のメンバの既定値を設定する。
foreach( var kvp in this._キーバインディング.MIDItoドラム )
{
var デバイスID = kvp.Key.deviceId;
- var デバイス名 = this._キーバインディング.MIDIデバイス番号toデバイス名[ デバイスID ];
- デバイスID = デバイスリスト.IndexOf( デバイス名 ); // 必ず存在する。
+ if( this._キーバインディング.MIDIデバイス番号toデバイス名.ContainsKey( デバイスID ) )
+ {
+ var デバイス名 = this._キーバインディング.MIDIデバイス番号toデバイス名[ デバイスID ];
+ デバイスID = デバイスリスト.IndexOf( デバイス名 ); // 必ず存在する。
+ }
+
中間バッファ.Add( new キーバインディング.IdKey( デバイスID, kvp.Key.key ), kvp.Value ); // デバイスID以外は変更なし。
}
}
/// <summary>
- /// ç\8f¾å\9c¨ã\81®<see cref="_ã\82ã\83¼ã\83\90ã\82¤ã\83³ã\83\87ã\82£ã\83³ã\82°"/>ã\81®å\86\85容ã\82\92ã\80\81XMLã\83\95ã\82¡ã\82¤ã\83«ã\81«ä¿\9då\98ã\81\99ã\82\8bã\80\82
+ /// 現在の<see cref="_キーバインディング"/>の内容をファイルに保存する。
/// </summary>
public void キーバインディングを保存する()
{
}
/// <summary>
- /// XMLファイルに保存する。
+ /// ファイルに保存する。
/// </summary>
/// <param name="ユーザフォルダパス">ユーザフォルダのパス。ユーザ名の部分は、ファイル名やパスで使える文字に調整済みであること。</param>
public void 保存する( string ユーザフォルダパス )
if( false == Directory.Exists( ユーザフォルダパス ) )
Directory.CreateDirectory( ユーザフォルダパス ); // 失敗したら例外発生。
- var xmlPath = Path.Combine( ユーザフォルダパス, _OptionXmlファイル名 );
- Utilities.保存する( this, xmlPath );
+ var path = Path.Combine( ユーザフォルダパス, _Optionファイル名 );
+ Utilities.保存する( this, path );
}
}
/// <summary>
- /// XMLファイルから復元する。
+ /// ファイルから復元する。
/// </summary>
/// <param name="ユーザフォルダパス">ユーザフォルダのパス。ユーザ名の部分は、ファイル名やパスで使える文字に調整済みであること。</param>
public static オプション設定 復元する( string ユーザフォルダパス )
{
using( Log.Block( Utilities.現在のメソッド名 ) )
{
- var xmlPath = Path.Combine( ユーザフォルダパス, _OptionXmlファイル名 );
- var options = Utilities.復元または新規作成する<オプション設定>( xmlPath );
+ var path = Path.Combine( ユーザフォルダパス, _Optionファイル名 );
+ var options = Utilities.復元または新規作成する<オプション設定>( path );
options.ドラムとチップと入力の対応表 = new ドラムとチップと入力の対応表( options.表示レーンの左右 );
/// <summary>
- /// オプション設定を保存する XML ファイルのパス。
+ /// オプション設定を保存するファイルのパス。
/// </summary>
- private static readonly string _OptionXmlファイル名 = @"Options.xml"; // パスなし
+ private static readonly string _Optionファイル名 = @"Options.json"; // パスなし
private Dictionary<ヒットランク種別, double> _最大ヒット距離secの既定値 = null;
}
/// <summary>
- /// XMLファイルに保存する。
+ /// ファイルに保存する。
/// </summary>
public void 保存する()
{
using( Log.Block( Utilities.現在のメソッド名 ) )
{
- var xmlPath = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _ConfigurationXmlファイルパス );
- Utilities.保存する( this, xmlPath );
+ var path = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _Configurationファイルパス );
+ Utilities.保存する( this, path );
}
}
/// <summary>
- /// XMLファイルから復元する。
+ /// ファイルから復元する。
/// </summary>
public static システム設定 復元する()
{
using( Log.Block( Utilities.現在のメソッド名 ) )
{
- var xmlPath = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _ConfigurationXmlファイルパス );
- var config = Utilities.復元または新規作成する<システム設定>( xmlPath );
+ var path = SST.IO.Folder.絶対パスに含まれるフォルダ変数を展開して返す( _Configurationファイルパス );
+ var config = Utilities.復元または新規作成する<システム設定>( path );
// ファイルに反映されていないメンバはいつまでも反映されないので、ここで一度、明示的に保存することにする。
config.保存する();
/// <summary>
- /// システム設定を保存する XML ファイルのパス。
+ /// システム設定を保存するファイルのパス。
/// </summary>
- private static readonly string _ConfigurationXmlファイルパス = @"$(AppData)\Configurations.xml";
+ private static readonly string _Configurationファイルパス = @"$(AppData)\Configurations.json";
/// <summary>
/// コンストラクタ時、または逆シリアル化時のメンバの既定値を設定する。
}
/// <summary>
- /// XMLファイルに保存する。
+ /// ファイルに保存する。
/// </summary>
public void 保存する()
{
Directory.CreateDirectory( ユーザフォルダパス ); // 失敗したら例外発生。
// プロパティを保存。
- Utilities.保存する( this.プロパティ, Path.Combine( ユーザフォルダパス, _PropertiesXmlファイル名 ) );
+ Utilities.保存する( this.プロパティ, Path.Combine( ユーザフォルダパス, _Propertiesファイル名 ) );
// オプション設定を保存。
this.オプション設定.保存する( ユーザフォルダパス );
}
/// <summary>
- /// XMLファイルから復元する。
+ /// ファイルから復元する。
/// 曲リストは復元しない。
/// </summary>
/// <param name="ユーザフォルダパス">ユーザフォルダのパス。ユーザ名の部分は、ファイル名やパスで使える文字に調整済みであること。</param>
using( Log.Block( Utilities.現在のメソッド名 ) )
{
var user = new ユーザ( "" );
- user.プロパティ = Utilities.復元する<ユーザプロパティ>( Path.Combine( ユーザフォルダパス, _PropertiesXmlファイル名 ) );
+ user.プロパティ = Utilities.復元する<ユーザプロパティ>( Path.Combine( ユーザフォルダパス, _Propertiesファイル名 ) );
user.オプション設定 = オプション設定.復元する( ユーザフォルダパス );
return user;
}
/// <summary>
- /// ユーザを保存する XML ファイルのパス。
+ /// ユーザを保存するファイルのパス。
/// </summary>
- private static readonly string _PropertiesXmlファイル名 = @"Properties.xml"; // ユーザルートからの相対パス
+ internal static readonly string _Propertiesファイル名 = @"Properties.json"; // ユーザルートからの相対パス
}
}
}
catch( Exception e )
{
- Log.ERROR( $"ユーザ「{user.プロパティ.名前}」のXMLファイルへの保存に失敗しました。スキップします。[{e.Message}]" );
+ Log.ERROR( $"ユーザ「{user.プロパティ.名前}」のファイルへの保存に失敗しました。スキップします。[{e.Message}]" );
保存失敗件数++;
}
}
// 条件に適合するフォルダをユーザフォルダとみなし、そのパスを列挙する。
var ユーザフォルダパスリスト =
- from dir in Directory.GetDirectories( SST.IO.Folder.UserRoot ) // (1) $(UserRoot) 配下のフォルダで、かつ、
- where File.Exists( Path.Combine( dir, @"Properties.xml" ) ) // (2) 中に Properties.xml ファイルが存在している。
+ from dir in Directory.GetDirectories( SST.IO.Folder.UserRoot ) // (1) $(UserRoot) 配下のフォルダで、かつ、
+ where File.Exists( Path.Combine( dir, ユーザ._Propertiesファイル名 ) ) // (2) 中にプロパティファイルが存在している。
select dir;
// 列挙されたそれぞれのパスについて、ユーザインスタンスの復元を試みる。