SHOJI's Code
 仕事や趣味で書いた各種言語のプログラミングコード(エクセルVBA,PHP,C/C++/C#,JavaScript等)、その他雑記。
2018.09<<12345678910111213141516171819202122232425262728293031>>2018.11
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

タイトルの通り。とりあえず作ってみた。相変わらずテストは適当なので、使うときはご注意。

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;

namespace SHOJIsCode.Components
{
/// <summary>
/// INI形式ファイルへアクセスします
/// </summary>
[Description("INI形式ファイルへアクセスします")]
public partial class IniFile : Component
{
#region "メンバー変数"
/// <summary>
/// セクションのハッシュテーブル
/// </summary>
private Hashtable sections;

/// <summary>
/// INIファイル
/// </summary>
private string filename;
#endregion

#region "プロパティ"
/// <summary>
/// INIファイル
/// </summary>
[Description("INIファイル名")]
public string FileName {
get {
try {
return Path.GetFullPath(filename);
}
catch {
return filename;
}
}
set {
if (filename!=value) {
filename = value;
sections.Clear();
}
}
}

/// <summary>
/// セクション
/// </summary>
/// <param name="appname">セクション名</param>
/// <returns>セクション</returns>
[Browsable(false)]
public Section this[string appname] {get{return GetSection(appname);}}
#endregion

#region "コンストラクタ"
/// <summary>
/// コンストラクタ
/// </summary>
public IniFile() {
sections = new Hashtable();
}

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="filename"></param>
public IniFile(string inifile):this() {
filename = inifile;
}
#endregion

#region "メソッド"
/// <summary>
/// セクションの取得
/// </summary>
/// <param name="appname">セクション名</param>
/// <returns>セクション</returns>
public Section GetSection(string appname) {
appname = appname.ToUpper();
if (!sections.Contains(appname)) {
sections.Add(appname, new Section(appname, this));
}
return (Section)sections[appname];
}
#endregion

/// <summary>
/// セクションクラス
/// </summary>
public class Section {
#region "メンバー変数"
/// <summary>
/// キーのハッシュテーブル
/// </summary>
private Hashtable keys;
#endregion

#region "プロパティ"
/// <summary>
/// 属するINIファイル
/// </summary>
public IniFile Ini {get;private set;}

/// <summary>
/// セクション名
/// </summary>
public string Name {get;private set;}

/// <summary>
/// ファイル名
/// </summary>
public string FileName {get{return Ini.FileName;}}

/// <summary>
/// キー
/// </summary>
/// <param name="keyname">キー名</param>
/// <returns>キー</returns>
public Key this[string keyname] {get{return GetKey(keyname);}}
#endregion

#region "コンストラクタ"
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="name"></param>
/// <param name="ini"></param>
public Section(string name, IniFile ini) {
keys = new Hashtable();
Name = name;
Ini = ini;
}
#endregion

#region "メソッド"
/// <summary>
/// キーの取得
/// </summary>
/// <param name="keyname">キー名</param>
/// <returns>キー</returns>
public Key GetKey(string keyname) {
keyname = keyname.ToUpper();
if (!keys.Contains(keyname)) {
keys.Add(keyname, new Key(keyname, this));
}
return (Key)keys[keyname];
}

/// <summary>
/// セクションの削除
/// </summary>
public void Clear() {
try {
/// WIN32の WritePrivateProfileString を呼び出す
WritePrivateProfileStringByPtr(Name, IntPtr.Zero, IntPtr.Zero, FileName);

/// キーのクリア
keys.Clear();
}
finally {
}
}
#endregion
}

/// <summary>
/// キークラス
/// </summary>
public class Key {
/// <summary>
/// 定数
/// </summary>
private const int DEFAULT_INTEGER_VALUE = default(int); // デフォルト整数値
private const string DEFAULT_STRING_VALUE = default(string); // デフォルト文字列
private const uint DEFAULT_STRING_SIZE = 1024; // デフォルト文字列サイズ

#region "プロパティ"
/// <summary>
/// 属するセクション
/// </summary>
public Section Section {get;private set;}

/// <summary>
/// キー名
/// </summary>
public string Name {get;private set;}

/// <summary>
/// セクション名
/// </summary>
public string AppName {get{return Section.Name;}}

/// <summary>
/// ファイル名
/// </summary>
public string FileName {get{return Section.FileName;}}

/// <summary>
/// 値
/// </summary>
public object Value {
get {
return Read();
}
set {
Write(value);
}
}
#endregion

#region "コンストラクタ"
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="name">キー名</param>
/// <param name="section">属するセクション</param>
public Key(string name, Section section) {
Section = section;
Name = name;
}
#endregion

#region "整数系入出力メソッド"
/// <summary>
/// 整数(Int32)の読出し
/// (デフォルト値指定)
/// </summary>
/// <param name="nDefault">デフォルト値</param>
/// <returns>読み出した整数値</returns>
public int ReadInt(int nDefault) {
try {
/// WIN32のGetPrivateProfileIntを呼び出す
return GetPrivateProfileInt(AppName, Name, nDefault, FileName);
}
catch {
/// エラーのときはデフォルト値を返す
return nDefault;
}
}

/// <summary>
/// 整数(Int32)の読出し
/// (デフォルト値省略)
/// </summary>
/// <returns>読み出した整数値</returns>
public int ReadInt() {
return ReadInt(DEFAULT_INTEGER_VALUE);
}

/// <summary>
/// 整数(Int32)の書き出し
/// </summary>
/// <param name="nValue">書きだす整数値</param>
public void WriteInt(int nValue) {
WriteString(nValue.ToString());
}
#endregion

#region "文字列系入出力メソッド"
/// <summary>
/// 文字列の読出し
/// (デフォルト値、最大サイズ指定)
/// </summary>
/// <param name="lpDefault">デフォルト値</param>
/// <param name="size">最大サイズ</param>
/// <returns>読み出した文字列</returns>
public string ReadString(string lpDefault, uint size) {
try {
/// WIN32の GetPrivateProfileString を呼び出す
StringBuilder lpReturned = new StringBuilder((int)size);
GetPrivateProfileString(AppName, Name, lpDefault, lpReturned, size, FileName);
return lpReturned.ToString();
}
catch {
/// エラーの時はデフォルト値を返す
return lpDefault;
}
}

/// <summary>
/// 文字列の読出し
/// (デフォルト値指定、最大サイズ省略)
/// </summary>
/// <param name="lpDefault">デフォルト値</param>
/// <returns>読み出した文字列</returns>
public string ReadString(string lpDefault) {
return ReadString(lpDefault, DEFAULT_STRING_SIZE);
}

/// <summary>
/// 文字列の読出し
/// (デフォルト値、最大サイズ省略)
/// </summary>
/// <returns>読み出した文字列</returns>
public string ReadString() {
return ReadString(DEFAULT_STRING_VALUE);
}

/// <summary>
/// 文字列の書き出し
/// </summary>
/// <param name="lpString">書き出す文字列</param>
public void WriteString(string lpString) {
/// 文字列がnullの場合はキーの削除とみなす
if (lpString==null) { Clear(); return; }

/// WIN32の WritePrivateProfileString を呼び出す
WritePrivateProfileString(AppName, Name, lpString, FileName);
}
#endregion

#region "構造体系入出力メソッド"
/// <summary>
/// 構造体の読出し
/// (型指定)
/// </summary>
/// <param name="type">構造体の型</param>
/// <returns>読み出した構造体</returns>
public object ReadStruct(Type type) {
IntPtr p = IntPtr.Zero;
object struc = null;

try {
/// 構造体をマーシャリング
int size = Marshal.SizeOf(type);
p = Marshal.AllocCoTaskMem(size);

/// WIN32の GetPrivateProfileStruct を呼び出す
GetPrivateProfileStruct(AppName, Name, p, (uint)size, FileName);

/// マーシャリングされたポインタを構造体にセット
struc = Marshal.PtrToStructure(p, type);
}
finally {
/// ポインタがNULLでなければ解放
if (p!=IntPtr.Zero) Marshal.FreeCoTaskMem(p);
}

return struc;
}

/// <summary>
/// 構造体の読出し
/// (型パラメータ指定)
/// </summary>
/// <typeparam name="T">構造体の型</typeparam>
/// <returns>読み出した構造体</returns>
public T ReadStruct<T>() {
try {
return (T)ReadStruct(typeof(T));
}
catch {
return default(T);
}
}

/// <summary>
/// 構造体の書き出し
/// </summary>
/// <param name="lpStruct">書き出す構造体</param>
public void WriteStruct(object lpStruct) {
/// オブジェクトがNULLのときはキーの削除とみなす
if (lpStruct==null) { Clear(); return; }

IntPtr p = IntPtr.Zero;
try {
/// 構造体をマーシャリングする
int size = Marshal.SizeOf(lpStruct.GetType());
p = Marshal.AllocCoTaskMem(size);
Marshal.StructureToPtr(lpStruct, p, false);

/// WIN32の WritePrivateProfileStructを呼び出す
WritePrivateProfileStruct(AppName, Name, p, (uint)size, FileName);
}
finally {
/// ポインタがNULLでなければ解放
if (p!=IntPtr.Zero) Marshal.FreeCoTaskMem(p);
}
}
#endregion

#region "汎用入出力メソッド"
/// <summary>
/// 汎用読出し
/// (型指定)
/// </summary>
/// <param name="type">読み出す型</param>
/// <returns>読み出した値</returns>
public object Read(Type type) {
try {
/// 型が整数(Uint32)ならば、ReadIntメソッドを使用する
if (type==typeof(uint)) return ReadInt();

/// 型が文字列ならば、ReadStringメソッドを使用する
if (type==typeof(string)) return ReadString();

/// Parseメソッドを持つ型ならば、Parseメソッドを使用して値を取得する
MethodInfo mi = GetParseMethod(type);
if (mi!=null) {
return mi.Invoke(null, new object[] {ReadString()});
}

/// それ以外は構造体の読み出すを試す
return ReadStruct(type);
}
catch {
return null;
}
}

/// <summary>
/// 汎用読出し
/// (型パラメータ)
/// </summary>
/// <typeparam name="T">読み出す型</typeparam>
/// <returns>読み出した値</returns>
public T Read<T>() {
try {
return (T)Read(typeof(T));
}
catch {
return default(T);
}
}

/// <summary>
/// 汎用読出し
/// (型省略)
/// ※ このメソッドの場合、構造体に読出しは行わない
/// </summary>
/// <returns>読み出した値</returns>
public object Read() {
try {
/// とりあえず、文字列として読み出す
string s = ReadString();

/// 主な型でパースし、パースできればその値を返す
int i; if (int.TryParse(s, out i)) return i;
uint n; if (uint.TryParse(s, out n)) return n;
bool b; if (bool.TryParse(s, out b)) return b;
long l; if (long.TryParse(s, out l)) return l;
ulong u; if (ulong.TryParse(s, out u)) return u;
double r; if (double.TryParse(s, out r)) return r;
DateTime dt; if (DateTime.TryParse(s, out dt)) return dt;

/// そのまま文字列を返す
return s;
}
catch {
return null;
}
}

/// <summary>
/// 汎用書き出し
/// </summary>
/// <param name="objValue">書き出すオブジェクト</param>
public void Write(object objValue) {
try {
/// NULLならばキーの削除
if (objValue==null) {
Clear();
return;
}

/// 書き出すオブジェクトの型を取得
Type type = objValue.GetType();

/// 型がInt32ならば、WriteIntメソッドを使用する
if (type==typeof(int)) {
WriteInt((int)objValue);
return;
}

/// 型が文字列ならば、WriteStringメソッドを使用する
if (type==typeof(string)) {
WriteString((string)objValue);
return;
}

/// Parseメソッドを持つ型ならば、文字列を書き込む
if (GetParseMethod(type)!=null) {
WriteString(objValue.ToString());
return;
}

/// 構造体の書き込みを試す
WriteStruct(objValue);
}
finally {
}
}
#endregion


#region "その他のメソッド"
/// <summary>
/// キーの削除
/// </summary>
public void Clear() {
IntPtr p = IntPtr.Zero;

try {
/// キー名をマーシャリング
p = Marshal.StringToCoTaskMemAuto(Name);

/// WIN32の WritePrivateProfileString を呼び出す
WritePrivateProfileStringByPtr(AppName, p, IntPtr.Zero, FileName);
}
finally {
/// ポインタがNULLでなければ解放
if (p!=IntPtr.Zero) Marshal.FreeCoTaskMem(p);
}
}
#endregion

#region "演算子再定義"
/// <summary>
/// 文字列へのキャスト
///
/// 例)
/// string a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>文字列</returns>
public static implicit operator string(Key key) {
return key.ReadString();
}

/// <summary>
/// 整数(Int32)へのキャスト
///
/// 例)
/// int a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>整数</returns>
public static implicit operator int(Key key) {
return key.ReadInt();
}

/// <summary>
/// 整数(UInt32)へのキャスト
///
/// 例)
/// uint a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>整数</returns>
public static implicit operator uint(Key key) {
return key.Read<uint>();
}

/// <summary>
/// Booleanへのキャスト
///
/// 例)
/// bool a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>Boolean</returns>
public static implicit operator bool(Key key) {
return key.Read<bool>();
}

/// <summary>
/// 整数(Int64)へのキャスト
///
/// 例)
/// long a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>整数</returns>
public static implicit operator long(Key key) {
return key.Read<long>();
}

/// <summary>
/// 整数(UInt64)へのキャスト
///
/// 例)
/// ulong a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>整数</returns>
public static implicit operator ulong(Key key) {
return key.Read<ulong>();
}

/// <summary>
/// 実数(float)へのキャスト
///
/// 例)
/// float a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>実数</returns>
public static implicit operator float(Key key) {
return key.Read<float>();
}

/// <summary>
/// 実数(double)へのキャスト
///
/// 例)
/// double a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>実数</returns>
public static implicit operator double(Key key) {
return key.Read<double>();
}

/// <summary>
/// 実数(decimal)へのキャスト
///
/// 例)
/// decimal a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>実数</returns>
public static implicit operator decimal(Key key) {
return key.Read<decimal>();
}

/// <summary>
/// 日時へのキャスト
///
/// 例)
/// DateTime a = Ini[appname][keyname];
/// </summary>
/// <param name="key">キー</param>
/// <returns>日時</returns>
public static implicit operator DateTime(Key key) {
return key.Read<DateTime>();
}
#endregion

#region "プライベート関数"
/// <summary>
/// Parseメソッドの取得
/// </summary>
/// <param name="type">型</param>
/// <returns>Parseメソッドのメソッド情報</returns>
private MethodInfo GetParseMethod(Type type) {
Type[] args = {typeof(string)};
return type.GetMethod("Parse", args);
}
#endregion

}

#region "API定義"
[DllImport("kernel32.dll")]
internal static extern int GetPrivateProfileInt(string lpAppName, string lpKeyName, int nDefault, string lpFileName);

[DllImport("kernel32.dll")]
internal static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturned, uint nSize, string lpFileName);

[DllImport("kernel32.dll")]
internal static extern uint GetPrivateProfileStruct(string lpAppName, string lpKeyName, IntPtr lpStruct, uint nSize, string lpFileName);

[DllImport("kernel32.dll")]
internal static extern uint WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);

[DllImport("kernel32.dll", EntryPoint="WritePrivateProfileString")]
internal static extern uint WritePrivateProfileStringByPtr(string lpAppName, IntPtr lpKeyName, IntPtr lpString, string lpFileName);

[DllImport("kernel32.dll")]
internal static extern uint WritePrivateProfileStruct(string lpAppName, string lpKeyName, IntPtr lpStruct, uint nSize, string lpFileName);
#endregion
}
}


テーマ:プログラミング - ジャンル:コンピュータ
コメント
この記事へのコメント
コメントを投稿する

管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
copyright © 2004-2006 SHOJI, Powered By FC2ブログ all rights reserved.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。