UTF8 ini

Vistaになってiniファイルに対して勝手なことされるので、.netのcpp/cliでUTF8でiniを扱うクラスを作りました。Windows98系でも動くはずです。
iniファイルとの整合性は全然取れてませんけど。


// WProfile.h
#pragma onceusing namespace System;
using namespace System::Collections;
namespace WProfiler {public ref class WProfile
 {
 private:
  WProfile(){}
  ~WProfile(){}

static Hashtable^ readall(String^ inipath);
  static bool writeall(Hashtable^ al, String^ inipath);
 public:
  static System::Boolean WProfile::WGetPrivateProfileInt(String^ app, String^ key, int def, int% ret, String^ inipath);
  static System::Boolean WProfile::WWritePrivateProfileInt(String^ app, String^ key, int val, String^ inipath);
  static System::Boolean WProfile::WGetPrivateProfileString(String^ app, String^ key, String^ def, String^% ret, String^ inipath);
  static System::Boolean WProfile::WWritePrivateProfileString(String^ app, String^ key, String^ val, String^ inipath);
 };
}


// これは メイン DLL ファイルです。
#include "stdafx.h"#include
#include "WProfile.h"
using namespace System;
using namespace System::Collections;

namespace WProfiler {

Hashtable^ WProfile::readall(String^ inipath)
 {
  Hashtable^ al = gcnew Hashtable;
  try {
  System::IO::StreamReader sr(inipath, System::Text::Encoding::UTF8);

String^ line = nullptr;
  Hashtable^ cursec = nullptr;

while ( (line=sr.ReadLine()) != nullptr )
  {
  line = line->TrimStart();
  if ( line->Length==0 || line[0] == L'#' )
  continue;

if ( line[0] == L'[' )
  {
  String^ secname = line->Trim( gcnew array{'[', ']'} );
  cursec = (Hashtable^)al[secname];
  if ( cursec == nullptr )
  {
  cursec = gcnew Hashtable;
  al[secname] = cursec;
  }
  continue;
  }
  else
  {
  if ( cursec == nullptr )
  continue;

array^ vals = line->Split( gcnew array{L'='}, 2 );
  if ( vals->Length < 2 )
  cursec[vals[0]] = L"";
  else
  cursec[vals[0]] = vals[1];
  }
  }
  }
  catch ( System::Exception^ )
  {
  return nullptr;
  }
  return al;
 }

bool WProfile::writeall(Hashtable^ al, String^ inipath)
 {
  if(!al)
  return false;

try {
  System::IO::StreamWriter sw(inipath, false, System::Text::Encoding::UTF8);

for each(String^ secname in al->Keys)
  {
  sw.Write(L"[");
  sw.Write(secname);
  sw.Write(L"]");
  sw.WriteLine();

Hashtable^ sec = (Hashtable^)al[secname];
  if ( !sec )
  continue;

for each( String^ keyname in sec->Keys )
  {
  sw.Write(keyname);
  sw.Write(L"=");
  sw.Write(sec[keyname]);
  sw.WriteLine();
  }
  sw.WriteLine();
  }
  }
  catch(System::Exception^ )
  {
  return false;
  }
  return true;
 }

System::Boolean WProfile::WGetPrivateProfileInt(String^ app, String^ key, int def, int% ret, String^ inipath)
 {
  ret = def;
  Hashtable^ al = readall(inipath);
  if ( !al )
  return false;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  return false;

String^ val = (String^)sec[key];
  if ( !val )
  return false;

if ( !System::Int32::TryParse(val, ret) )
  return false;

return true;
 }

System::Boolean WProfile::WWritePrivateProfileInt(String^ app, String^ key, int val, String^ inipath)
 {
  Hashtable^ al = readall(inipath);
  if ( !al )
  al = gcnew Hashtable;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  {
  sec = gcnew Hashtable;
  al[app] = sec;
  }

sec[key] = val;

return writeall(al, inipath);
 }

System::Boolean WProfile::WGetPrivateProfileString(String^ app, String^ key, String^ def, String^% ret, String^ inipath)
 {
  ret = def;
  Hashtable^ al = readall(inipath);
  if ( !al )
  return false;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  return false;

String^ val = (String^)sec[key];
  if ( !val )
  return false;

ret = val;
  return true;
 }

System::Boolean WProfile::WWritePrivateProfileString(String^ app, String^ key, String^ val, String^ inipath)
 {
  Hashtable^ al = readall(inipath);
  if ( !al )
  al = gcnew Hashtable;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  {
  sec = gcnew Hashtable;
  al[app] = sec;
  }

sec[key] = val;

return writeall(al, inipath);
 }
}

ダウンロード

Leave a Reply

Your email address will not be published. Required fields are marked *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)