Mass++ Common Libraries v2.7.5
 All Classes Namespaces Files Functions Variables Enumerations Macros
IniFile.cpp
Go to the documentation of this file.
1 
12 #include "stdafx.h"
13 #include "IniFile.h"
14 
15 #include <list>
16 
17 
18 #define INI_LINE_BUFFER_SIZE 0x1000
19 
20 // >>>>>> 暗号化 @Date:2013/10/18 <Add> A.Ozaki
21 //
22 //#define _CRT_SECURE_NO_DEPRECATE // 重複していると外します
23 #define CRYPTOPP_DEFAULT_NO_DLL
24 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
25 
26 // ここからは「おまじない」
27 #pragma push_macro( "new" )
28 #undef new
29 #include "dll.h"
30 #pragma pop_macro( "new" )
31 // 「おまじない」おわり
32 
33 #pragma comment( lib, "cryptlib.lib" ) // ライブラリの指定
34 USING_NAMESPACE(CryptoPP)
35 typedef unsigned char BYTE;
36 //
37 // <<<<<< 暗号化 @Date:2013/10/18 <Add> A.Ozaki
38 
39 using namespace kome::core;
40 
41 
42 #include <crtdbg.h>
43 #ifdef _DEBUG
44  #define new new( _NORMAL_BLOCK, __FILE__, __LINE__ )
45  #define malloc( s ) _malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ )
46 #endif // _DEBUG
47 
48 
49 
50 // constructor
51 IniFile::IniFile() {
52 }
53 
54 // destructor
56 }
57 
58 // get file path
59 const char* IniFile::getFilePath() {
60  return m_filePath.c_str();
61 }
62 
63 // set string value
64 void IniFile::setString( const char* section, const char* key, const char* value ) {
65  // create string object
66  std::string sec = NVL( section, "" );
67 
68  // set section
69  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
70  m_sections.push_back( sec );
71  }
72 
73  // set value
74  m_sectionMap[ sec ].setValue( key, value );
75 }
76 
77 // get string value
78 const char* IniFile::getString( const char* section, const char* key, const char* defaultValue ) {
79  // create string object
80  std::string sec = NVL( section, "" );
81 
82  // search section
83  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
84  return defaultValue;
85  }
86 
87  // get parameter
88  return m_sectionMap[ sec ].getStringValue( key, defaultValue );
89 }
90 
91 bool IniFile::decryptPassword( const char* pcPassword, char* pcDecrypt, const size_t szDecrypt )
92 {
93  if ( (char *)NULL == pcPassword || (char *)NULL == pcDecrypt )
94  {
95  return false;
96  }
97 
98  std::string strVal = pcPassword;
99  if ( -1 != strVal.find( "@@@" ) )
100  {
101  try
102  {
103  byte bKey[AES::DEFAULT_KEYLENGTH]; // 共通鍵
104  byte bIv[AES::BLOCKSIZE]; // IV
105 
106  // キーとIVに適当な値設定します
107  // 暗号化・符号化に同じ値を設定する必要があります
108  memset( (void *)bKey, 0x01, AES::DEFAULT_KEYLENGTH );
109  memset( (void *)bIv, 0x01, AES::BLOCKSIZE );
110 
111  //------------------------------------------------
112  // 復号化
113  //------------------------------------------------
114  int i = strVal.find_last_of( "@@@" );
115  strVal = strVal.substr( i + 1, ( strVal.length( ) - i ) );
116 
117  std::string strInputDec;
118  HexDecoder insHexDecode( new StringSink( strInputDec ) );
119  insHexDecode.Put( (BYTE*)( strVal.c_str( ) ), strVal.size( ) );
120  insHexDecode.MessageEnd( );
121 
122  // 復号化オブジェクト作成
123  CTR_Mode<AES>::Decryption insDecryption;
124  insDecryption.SetKeyWithIV( bKey, sizeof( bKey ), bIv ); // キーとIVを復号化オブジェクトに設定
125 
126  // 変換フィルタを作成し、暗号文と復号後の出力先バッファを渡す
127  std::string strOutputDec;
128  StreamTransformationFilter insStfDec( insDecryption, new StringSink( strOutputDec ) );
129  insStfDec.Put( (BYTE*)strInputDec.c_str( ), strInputDec.size( ) );
130  insStfDec.MessageEnd( );
131 
132  strVal = strOutputDec;
133  }
134  catch ( ... )
135  {
136  }
137  }
138 
139  memset( (void *)pcDecrypt, 0x00, szDecrypt );
140  if ( szDecrypt <= strVal.length( ) )
141  {
142  return false;
143  }
144  memcpy( (void *)pcDecrypt, (char *)strVal.c_str( ), strVal.length( ) );
145 
146  return true;
147 }
148 
149 bool IniFile::encryptPassword( const char* pcPassword, char* pcEncrypt, const size_t szEncrypt )
150 {
151  if ( (char *)NULL == pcPassword || (char *)NULL == pcEncrypt )
152  {
153  return false;
154  }
155 
156  std::string strVal = pcPassword;
157  try
158  {
159  byte bKey[AES::DEFAULT_KEYLENGTH]; // 共通鍵
160  byte bIv[AES::BLOCKSIZE]; // IV
161 
162  // キーとIVに適当な値設定します
163  // 暗号化・符号化に同じ値を設定する必要があります
164  memset( (void *)bKey, 0x01, AES::DEFAULT_KEYLENGTH );
165  memset( (void *)bIv, 0x01, AES::BLOCKSIZE );
166 
167  //------------------------------------------------
168  // 暗号化
169  //------------------------------------------------
170  // 暗号化オブジェクト作成
171  CTR_Mode<AES>::Encryption insEncryptor;
172  insEncryptor.SetKeyWithIV( bKey, sizeof( bKey ), bIv ); // キーとIVを暗号化オブジェクトに設定
173 
174  // 変換フィルタを作成し、平文と変換後の出力先バッファを渡します
175  std::string strInputEnc = strVal;
176  std::string strOutputEnc;
177  StreamTransformationFilter insStfEnc( insEncryptor, new StringSink( strOutputEnc ) );
178  insStfEnc.Put( (BYTE*)( strInputEnc.c_str( ) ), strInputEnc.size( ) );
179  insStfEnc.MessageEnd( );
180 
181  // 暗号化されたモノをHex形式に変換します
182  std::string strHex;
183  HexEncoder insHexEncode( new StringSink( strHex ) );
184  insHexEncode.Put( (BYTE*)( strOutputEnc.c_str( ) ), strOutputEnc.size( ) );
185  insHexEncode.MessageEnd( );
186 
187  strVal.clear( );
188  strVal.append( "@@@" );
189  strVal.append( strHex );
190  }
191  catch ( ... )
192  {
193  }
194 
195  memset( (void *)pcEncrypt, 0x00, szEncrypt );
196  if ( szEncrypt <= strVal.length( ) )
197  {
198  return false;
199  }
200  memcpy( (void *)pcEncrypt, (char *)strVal.c_str( ), strVal.length( ) );
201 
202  return true;
203 
204 }
205 
206 // set boolean value
207 void IniFile::setBool( const char* section, const char* key, const bool value ) {
208  // create string object
209  std::string sec = NVL( section, "" );
210 
211  // set section
212  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
213  m_sections.push_back( sec );
214  }
215 
216  // set value
217  m_sectionMap[ sec ].setValue( key, ( value ? "true" : "false" ) );
218 }
219 
220 // get boolean value
221 bool IniFile::getBool( const char* section, const char* key, const bool defaultValue ) {
222  // create string object
223  std::string sec = NVL( section, "" );
224 
225  // search section
226  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
227  return defaultValue;
228  }
229 
230  // get parameter
231  return m_sectionMap[ sec ].getBoolValue( key, defaultValue );
232 }
233 
234 // set integer value
235 void IniFile::setInt( const char* section, const char* key, const int value ) {
236  // create string object
237  std::string sec = NVL( section, "" );
238 
239  // set section
240  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
241  m_sections.push_back( sec );
242  }
243 
244  // set value
245  m_sectionMap[ sec ].setValue( key, FMT( "%d", value ).c_str() );
246 }
247 
248 // get integer value
249 int IniFile::getInt( const char* section, const char* key, const int defaultValue ) {
250  // create string object
251  std::string sec = NVL( section, "" );
252 
253  // search section
254  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
255  return defaultValue;
256  }
257 
258  // get parameter
259  return m_sectionMap[ sec ].getIntValue( key, defaultValue );
260 }
261 
262 // set double value
263 void IniFile::setDouble( const char* section, const char* key, const double value ) {
264  // create string object
265  std::string sec = NVL( section, "" );
266 
267  // set section
268  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
269  m_sections.push_back( sec );
270  }
271 
272  // set value
273  m_sectionMap[ sec ].setValue( key, FMT( "%f", value ).c_str() );
274 }
275 
276 // delete value
277 void IniFile::deleteValue( const char* section, const char* key ) {
278  // create string object
279  std::string sec = NVL( section, "" );
280 
281  // check the map
282  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
283  return;
284  }
285 
286  // delete
287  m_sectionMap[ sec ].deleteParameter( key );
288  if( m_sectionMap[ sec ].getNumberOfProperties() == 0 ) {
289  m_sectionMap.erase( sec );
290 
291  for( std::vector< std::string >::iterator it = m_sections.begin(); it != m_sections.end(); it++ )
292  {
293  if (!it->compare( sec ))
294  {
295  m_sections.erase(it);
296  break;
297  }
298  }
299  }
300 }
301 
302 // get properties
303 Properties* IniFile::getProperties( const char* section ) {
304  // check the parameter
305  if( section == NULL ) {
306  return NULL;
307  }
308 
309  // check the map
310  if( m_sectionMap.find( section ) == m_sectionMap.end() ) {
311  return NULL;
312  }
313 
314  // get properties
315  return &m_sectionMap[ section ];
316 }
317 
318 // get double value
319 double IniFile::getDouble( const char* section, const char* key, const double defaultValue ) {
320  // create string object
321  std::string sec = NVL( section, "" );
322 
323  // search section
324  if( m_sectionMap.find( sec ) == m_sectionMap.end() ) {
325  return defaultValue;
326  }
327 
328  // get parameter
329  return m_sectionMap[ sec ].getDoubleValue( key, defaultValue );
330 }
331 
332 // get the number of sections
334  return m_sections.size();
335 }
336 
337 // get section
338 const char* IniFile::getSection( const unsigned int index ) {
339  // check the parameter
340  if( index >= m_sections.size() ) {
341  return NULL;
342  }
343 
344  return m_sections[ index ].c_str();
345 }
346 
347 // get the number of parameters
348 unsigned int IniFile::getNumberOfParameters( const char* section ) {
349  // get properties
350  Properties* properties = getProperties( section );
351 
352  // get size
353  if( properties == NULL ) {
354  return 0;
355  }
356  return properties->getNumberOfProperties();
357 }
358 
359 // get parameter name
360 const char* IniFile::getParameterName( const char* section, const unsigned int index ) {
361  // get properties
362  Properties* properties = getProperties( section );
363 
364  // get parameter name
365  if( properties == NULL ) {
366  return NULL;
367  }
368  return properties->getKey( index );
369 }
370 
371 // get parameter value
372 const char* IniFile::getParameterValue( const char* section, const unsigned int index ) {
373  // get properties
374  Properties* properties = getProperties( section );
375 
376  // get parameter name
377  if( properties == NULL ) {
378  return NULL;
379  }
380  return properties->getValue( index );
381 }
382 
383 // load the file
384 bool IniFile::load( const char* path ) {
385  // log
386  LOG_INFO( FMT( "Loading INI file... [%s]", NVL( path, "" ) ) );
387 
388  // check file
389  if( !checkfile( path ) ) {
390  LOG_WARN( FMT( "Illegal path [%s]", NVL( path, "" ) ) );
391  return false;
392  }
393 
394  // clear
395  m_sections.clear();
396  m_sectionMap.clear();
397  m_filePath.clear();
398 
399  // open
400  std::string p = absolutepath( path );
401  FILE* fp = fileopen( p.c_str(), "r" );
402  if( fp == NULL ) {
403  LOG_WARN( FMT( "Failed to open the file. [%s]", NVL( path, "" ) ) );
404  return false;
405  }
406  m_filePath = p;
407 
408  // read
409  char line[ INI_LINE_BUFFER_SIZE ];
410  Properties* params = NULL;
411  std::string section;
412 
413  while( fgets( line, INI_LINE_BUFFER_SIZE, fp ) != NULL ) { // read line
414  // read line
415  line[ INI_LINE_BUFFER_SIZE - 1 ] = '\0';
416 
417  if( line[ 0 ] == '#' || line[ 0 ] == ';' ) { // comment
418  continue;
419  }
420 
421  // trim
422  std::string l = trimstring( line );
423  memcpy( line, l.c_str(), l.length() );
424  line[ l.length() ] = '\0';
425 
426  if( line[ 0 ] == '[' ) { // section
427  char* c = strstr( line, "]" );
428  if( c != NULL ) {
429  *c = '\0';
430  }
431  c = strstr( line, "[" );
432  if( c != NULL ) {
433  *c = '\0';
434  }
435 
436  section = std::string( line + 1 );
437  params = NULL;
438  }
439  else {
440  char* key = line;
441  char* value = strstr( line, "=" );
442  if( value != NULL ) {
443  *value = '\0';
444  value++;
445 
446  if( params == NULL ) {
447  params = &m_sectionMap[ section ];
448  m_sections.push_back( section );
449  }
450  // >>>>>> @Date:2014/02/07 <Add> A.Ozaki
451  //
452  // パスワードの符号化処理
453  // アプリケーション内は、符号化された内容を保有するように変更
454  // 符号化対象は、
455  // key:"PASSWORD"/"COMMON_DB_PASSWORD"
456  // value:先頭3文字が"@@@"で始まる
457  //
458  std::string strKey = tolowercase( key );
459  std::string strValue = value;
460  if ( ( 0 == strKey.compare( "password" ) ||
461  0 == strKey.compare( "common_db_password" ) )
462  && -1 != strValue.find( "@@@" ) )
463  {
464  char cBuff[256];
465 
466  if ( true == decryptPassword( strValue.c_str( ), cBuff, sizeof( cBuff ) ) )
467  {
468  strValue = cBuff;
469  }
470  }
471 // params->setValue( key, value );
472  params->setValue( key, strValue.c_str( ) );
473  //
474  // <<<<<< @Date:2014/02/07 <Add> A.Ozaki
475  }
476  }
477  }
478 
479  // close
480  fclose( fp );
481 
482  return true;
483 }
484 
485 // save
486 bool IniFile::save( const char* path ) {
487  // absolutepath
488  std::string p = absolutepath( NVL( path, m_filePath.c_str() ) );
489 
490  // log
491  LOG_INFO( FMT( "Saving INI file... [%s]", p.c_str() ) );
492 
493  // file open
494  FILE* fp = fileopen( p.c_str(), "w" );
495  if( fp == NULL ) {
496  LOG_ERROR(
497  FMT(
498  "Failed to open the file. [%s]",
499  p.c_str()
500  )
501  );
502  return false;
503  }
504 
505  // write to file
506  for( unsigned int i = 0; i < m_sections.size(); i++ ) {
507  // write section
508  std::string section = m_sections[ i ];
509 
510  if( !section.empty() ) {
511  fprintf( fp, "[%s]\n", section.c_str() );
512  }
513 
514  // write Properties
515  Properties* params = &m_sectionMap[ section ];
516  for( unsigned int i = 0; i < params->getNumberOfProperties(); i++ ) {
517  // >>>>>> @Date:2014/02/07 <Add> A.Ozaki
518  //
519  // パスワードの暗号化処理
520  // iniファイルに出力するときに暗号化します
521  // 暗号化対象は、
522  // key:"PASSWORD"/"COMMON_DB_PASSWORD"
523  // value:"none"以外
524  //
525  std::string strKey = tolowercase( params->getKey( i ) );
526  std::string strValue = params->getValue( i );
527  if ( ( 0 == strKey.compare( "password" ) || 0 == strKey.compare( "common_db_password" ) )
528  && ( 0 != strValue.compare( "none" ) ) )
529  {
530  char cBuff[256];
531 
532  if ( true == encryptPassword( params->getValue( i ), cBuff, sizeof( cBuff ) ) )
533  {
534  strValue = cBuff;
535  }
536  }
537 // fprintf( fp, "%s=%s\n", params->getKey( i ), params->getValue( i ) );
538  fprintf( fp, "%s=%s\n", params->getKey( i ), strValue.c_str( ) );
539 
540  //
541  // <<<<<< @Date:2014/02/07 <Add> A.Ozaki
542  }
543 
544  fprintf( fp, "\n" );
545  }
546 
547  // close
548  fflush( fp );
549  fclose( fp );
550 
551  return true;
552 }
553 
554 // load ini file
555 IniFile* IniFile::loadIniFile( const char* path ) {
556  // manager
558 
559  // absolute path
560  std::string p = absolutepath( path );
561 
562  // get object from map
563  IniFile* iniFile = mgr.getFile( path );
564  if( iniFile == NULL ) { // create new object
565  iniFile = new IniFile();
566  if( iniFile->load( p.c_str() ) ) { // success
567  mgr.setFile( iniFile );
568  }
569  else{ // fail
570  delete iniFile;
571  iniFile = NULL;
572  }
573  }
574 
575  return iniFile;
576 }
577 
578 // get ini file information object
579 IniFile* IniFile::getIniFile( const char* path ) {
580  // manager
582 
583  // absolutepath
584  std::string p = absolutepath( path );
585 
586  // get object from map
587  IniFile* iniFile = mgr.getFile( p.c_str() );
588  if( iniFile == NULL ) {
589  if( fileexists( p.c_str() ) ) { // load file
590  iniFile = loadIniFile( p.c_str() );
591  }
592  else { // create new file
593  iniFile = new IniFile();
594  iniFile->m_filePath = p;
595  mgr.setFile( iniFile );
596  }
597  }
598 
599  return iniFile;
600 }
601 
602 // save all ini files
604  // manager
606 
607  // save
608  mgr.save();
609 }
610 
611 
612 
613 // IniFileManager --------------------------------------------------------
614 
615 // constructor
617 }
618 
619 // destructor
621  // delete ini file
622  for( std::map< std::string, IniFile* >::iterator it = m_fileMap.begin();
623  it != m_fileMap.end(); it++ ) {
624  IniFile* ini = (*it).second;
625  delete ini;
626  }
627  m_fileMap.clear();
628 }
629 
630 // set ini file information to map
632  // check parameter
633  if( file == NULL ) {
634  return;
635  }
636 
637  // absolutepath
638  std::string path = absolutepath( file->getFilePath() );
639 
640  // search map
641  if( m_fileMap.find( path ) != m_fileMap.end() ) {
642  delete m_fileMap[ path ];
643  }
644 
645  // set to map
646  m_fileMap[ path ] = file;
647 }
648 
649 // get ini file information from map
651  // absolute path
652  std::string p = absolutepath( path );
653 
654  // search map
655  if( m_fileMap.find( p ) == m_fileMap.end() ) {
656  return NULL;
657  }
658 
659  return m_fileMap[ p ];
660 }
661 
662 // save all ini file
664  // delete ini file
665  for( std::map< std::string, IniFile* >::iterator it = m_fileMap.begin();
666  it != m_fileMap.end(); it++ ) {
667  IniFile* ini = (*it).second;
668  ini->save();
669  }
670 }
671 
672 // get instance
674  // create object
675  static IniFileManager mgr;
676 
677  return mgr;
678 }
Properties * getProperties(const char *section)
gets properties object specified section
Definition: IniFile.cpp:303
bool encryptPassword(const char *pcPassword, char *pcEncrypt, const size_t szEncrypt)
decrypt password
Definition: IniFile.cpp:149
virtual ~IniFileManager()
destructor
Definition: IniFile.cpp:620
double getDouble(const char *section, const char *key, const double defaultValue)
gets real number value
Definition: IniFile.cpp:319
static void saveAllIniFiles()
save all ini files
Definition: IniFile.cpp:603
void setBool(const char *section, const char *key, const bool value)
sets boolean value
Definition: IniFile.cpp:207
bool save(const char *path=NULL)
save the ini file
Definition: IniFile.cpp:486
keys and values management class
Definition: Properties.h:29
IniFile object management class.
Definition: IniFile.h:274
static IniFileManager & getInstance()
gets ini file manager object (This is the only object.)
Definition: IniFile.cpp:673
std::string m_filePath
Definition: IniFile.h:54
void setValue(const char *key, const char *value)
sets parameter value
Definition: Properties.cpp:39
const char * getParameterName(const char *section, const unsigned int index)
gets parameter name
Definition: IniFile.cpp:360
const char * getString(const char *section, const char *key, const char *defaultValue)
gets string value
Definition: IniFile.cpp:78
static IniFile * getIniFile(const char *path)
gets ini file object. If specified file is not opened, this method calls loadIniFile method...
Definition: IniFile.cpp:579
void setInt(const char *section, const char *key, const int value)
sets integer number value
Definition: IniFile.cpp:235
bool getBool(const char *section, const char *key, const bool defaultValue)
gets boolean value
Definition: IniFile.cpp:221
unsigned int getNumberOfSections()
gets the number of sections
Definition: IniFile.cpp:333
const char * getValue(const unsigned int index)
gets the parameter value
Definition: Properties.cpp:175
int getInt(const char *section, const char *key, const int defaultValue)
get integer number value
Definition: IniFile.cpp:249
std::string trimstring(const char *s)
remove white spaces from both ends of specified string
bool fileexists(const char *path)
judge whether file exists
bool checkfile(const char *path)
check file before open. (This function calls fileexists and isdirectory )
unsigned int getNumberOfProperties()
gets the number of Properties
Definition: Properties.cpp:160
std::map< std::string, Properties > m_sectionMap
Definition: IniFile.h:60
const char * getParameterValue(const char *section, const unsigned int index)
gets parameter value
Definition: IniFile.cpp:372
#define NVL(checkVal, replaceVal)
Definition: CoreMacros.h:99
interfaces of IniFile class
#define NULL
Definition: CoreMacros.h:18
std::string tolowercase(const char *s)
convert all of the characters in the string given to lower case
virtual ~IniFile()
destructor
Definition: IniFile.cpp:55
FILE * fileopen(const char *path, const char *mode)
opens file
const char * getKey(const unsigned int index)
gets the name of parameter
Definition: Properties.cpp:165
bool load(const char *path)
load the ini file
Definition: IniFile.cpp:384
static IniFile * loadIniFile(const char *path)
loads ini file and gets IniFile object.
Definition: IniFile.cpp:555
IniFile()
constructor
Definition: IniFile.cpp:51
unsigned int getNumberOfParameters(const char *section)
gets the number of parameters specified section
Definition: IniFile.cpp:348
bool decryptPassword(const char *pcPassword, char *pcDecrypt, const size_t szDecrypt)
decrypt password
Definition: IniFile.cpp:91
std::string absolutepath(const char *path)
get absolute path
void save()
save all ini files
Definition: IniFile.cpp:663
void setDouble(const char *section, const char *key, const double value)
sets real number value
Definition: IniFile.cpp:263
const char * getFilePath()
gets file path
Definition: IniFile.cpp:59
void deleteValue(const char *section, const char *key)
deletes value
Definition: IniFile.cpp:277
void setFile(IniFile *file)
sets ini file information object to map
Definition: IniFile.cpp:631
ini file management class
Definition: IniFile.h:30
std::vector< std::string > m_sections
Definition: IniFile.h:57
IniFile * getFile(const char *path)
gets ini file information object
Definition: IniFile.cpp:650
const char * getSection(const unsigned int index)
gets section
Definition: IniFile.cpp:338
void setString(const char *section, const char *key, const char *value)
sets string value
Definition: IniFile.cpp:64