1/////////////////////////////////////////////////////////////////////////////// 2// Name: src/os2/iniconf.cpp 3// Purpose: implementation of wxIniConfig class 4// Author: David Webster 5// Modified by: 6// Created: 10/09/99 7// RCS-ID: $Id: iniconf.cpp 38920 2006-04-26 08:21:31Z ABX $ 8// Copyright: David Webster 9// Licence: wxWindows licence 10/////////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#if wxUSE_CONFIG 16 17#ifndef WX_PRECOMP 18 #include "wx/dynarray.h" 19 #include "wx/string.h" 20 #include "wx/intl.h" 21 #include "wx/event.h" 22 #include "wx/app.h" 23 #include "wx/utils.h" 24 #include "wx/log.h" 25#endif //WX_PRECOMP 26 27#include "wx/config.h" 28 29#include "wx/os2/iniconf.h" 30 31#define INCL_PM 32#include <os2.h> 33 34// ---------------------------------------------------------------------------- 35// constants 36// ---------------------------------------------------------------------------- 37 38// we replace all path separators with this character 39#define PATH_SEP_REPLACE '_' 40 41// ============================================================================ 42// implementation 43// ============================================================================ 44 45// ---------------------------------------------------------------------------- 46// ctor & dtor 47// ---------------------------------------------------------------------------- 48 49wxIniConfig::wxIniConfig(const wxString& strAppName, 50 const wxString& strVendor, 51 const wxString& localFilename, 52 const wxString& globalFilename, 53 long style) 54 : wxConfigBase(!strAppName && wxTheApp ? wxTheApp->GetAppName() 55 : strAppName, 56 !strVendor ? (wxTheApp ? wxTheApp->GetVendorName() 57 : strAppName) 58 : strVendor, 59 localFilename, globalFilename, style) 60{ 61 m_strLocalFilename = localFilename; 62 if (m_strLocalFilename.empty()) 63 { 64 m_strLocalFilename = GetAppName() + wxT(".ini"); 65 } 66 67 // append the extension if none given and it's not an absolute file name 68 // (otherwise we assume that they know what they're doing) 69 if ( !wxIsPathSeparator(m_strLocalFilename[(size_t) 0]) && 70 m_strLocalFilename.Find('.') == wxNOT_FOUND ) 71 { 72 m_strLocalFilename << wxT(".ini"); 73 } 74 75 // set root path 76 SetPath(wxEmptyString); 77} 78 79wxIniConfig::~wxIniConfig() 80{ 81} 82 83// ---------------------------------------------------------------------------- 84// path management 85// ---------------------------------------------------------------------------- 86 87void wxIniConfig::SetPath(const wxString& strPath) 88{ 89 wxArrayString aParts; 90 91 if ( strPath.empty() ) 92 { 93 // nothing 94 } 95 else if ( strPath[(size_t) 0] == wxCONFIG_PATH_SEPARATOR ) 96 { 97 // absolute path 98 wxSplitPath(aParts, strPath); 99 } 100 else 101 { 102 // relative path, combine with current one 103 wxString strFullPath = GetPath(); 104 strFullPath << wxCONFIG_PATH_SEPARATOR << strPath; 105 wxSplitPath(aParts, strFullPath); 106 } 107 108 size_t nPartsCount = aParts.Count(); 109 m_strPath.Empty(); 110 if ( nPartsCount == 0 ) 111 { 112 // go to the root 113 m_strGroup = (wxChar*)PATH_SEP_REPLACE; 114 } 115 else 116 { 117 // translate 118 m_strGroup = aParts[(size_t) 0]; 119 for ( size_t nPart = 1; nPart < nPartsCount; nPart++ ) 120 { 121 if ( nPart > 1 ) 122 m_strPath << PATH_SEP_REPLACE; 123 m_strPath << aParts[nPart]; 124 } 125 } 126 127 // other functions assume that all this is true, i.e. there are no trailing 128 // underscores at the end except if the group is the root one 129 wxASSERT( (m_strPath.empty() || m_strPath.Last() != PATH_SEP_REPLACE) && 130 (m_strGroup == wxString((wxChar)PATH_SEP_REPLACE) || 131 m_strGroup.Last() != PATH_SEP_REPLACE) ); 132} 133 134const wxString& wxIniConfig::GetPath() const 135{ 136 static wxString s_str; 137 138 // always return abs path 139 s_str = wxCONFIG_PATH_SEPARATOR; 140 141 if ( m_strGroup == wxString((wxChar)PATH_SEP_REPLACE) ) 142 { 143 // we're at the root level, nothing to do 144 } 145 else 146 { 147 s_str << m_strGroup; 148 if ( !m_strPath.empty() ) 149 s_str << wxCONFIG_PATH_SEPARATOR; 150 for ( const wxChar *p = m_strPath; *p != '\0'; p++ ) 151 { 152 s_str << (*p == PATH_SEP_REPLACE ? wxCONFIG_PATH_SEPARATOR : *p); 153 } 154 } 155 156 return s_str; 157} 158 159wxString wxIniConfig::GetPrivateKeyName(const wxString& szKey) const 160{ 161 wxString strKey; 162 163 if ( !m_strPath.empty() ) 164 strKey << m_strPath << PATH_SEP_REPLACE; 165 166 strKey << szKey; 167 168 return strKey; 169} 170 171wxString wxIniConfig::GetKeyName(const wxString& szKey) const 172{ 173 wxString strKey; 174 175 if (m_strGroup != wxString((wxChar)PATH_SEP_REPLACE)) 176 strKey << m_strGroup << PATH_SEP_REPLACE; 177 if ( !m_strPath.empty() ) 178 strKey << m_strPath << PATH_SEP_REPLACE; 179 180 strKey << szKey; 181 182 return strKey; 183} 184 185// ---------------------------------------------------------------------------- 186// enumeration 187// ---------------------------------------------------------------------------- 188 189// not implemented 190bool wxIniConfig::GetFirstGroup(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const 191{ 192 wxFAIL_MSG(wxT("not implemeted")); 193 194 return false; 195} 196 197bool wxIniConfig::GetNextGroup(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const 198{ 199 wxFAIL_MSG(wxT("not implemeted")); 200 201 return false; 202} 203 204bool wxIniConfig::GetFirstEntry(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const 205{ 206 wxFAIL_MSG(wxT("not implemeted")); 207 208 return false; 209} 210 211bool wxIniConfig::GetNextEntry(wxString& WXUNUSED(str), long& WXUNUSED(lIndex)) const 212{ 213 wxFAIL_MSG(wxT("not implemeted")); 214 215 return false; 216} 217 218// ---------------------------------------------------------------------------- 219// misc info 220// ---------------------------------------------------------------------------- 221 222// not implemented 223size_t wxIniConfig::GetNumberOfEntries(bool WXUNUSED(bRecursive)) const 224{ 225 wxFAIL_MSG(wxT("not implemeted")); 226 227 return (size_t)-1; 228} 229 230size_t wxIniConfig::GetNumberOfGroups(bool WXUNUSED(bRecursive)) const 231{ 232 wxFAIL_MSG(wxT("not implemeted")); 233 234 return (size_t)-1; 235} 236 237bool wxIniConfig::HasGroup(const wxString& WXUNUSED(strName)) const 238{ 239 wxFAIL_MSG(wxT("not implemeted")); 240 241 return false; 242} 243 244bool wxIniConfig::HasEntry(const wxString& WXUNUSED(strName)) const 245{ 246 wxFAIL_MSG(wxT("not implemeted")); 247 248 return false; 249} 250 251// is current group empty? 252bool wxIniConfig::IsEmpty() const 253{ 254 char szBuf[1024]; 255 256// GetPrivateProfileString(m_strGroup, NULL, "", 257// szBuf, WXSIZEOF(szBuf), m_strLocalFilename); 258 if ( !::IsEmpty(szBuf) ) 259 return false; 260 261// GetProfileString(m_strGroup, NULL, "", szBuf, WXSIZEOF(szBuf)); 262// if ( !::IsEmpty(szBuf) ) 263// return false; 264 265 return true; 266} 267 268// ---------------------------------------------------------------------------- 269// read/write 270// ---------------------------------------------------------------------------- 271 272bool wxIniConfig::Read(const wxString& szKey, wxString *pstr) const 273{ 274 wxConfigPathChanger path(this, szKey); 275 wxString strKey = GetPrivateKeyName(path.Name()); 276 277 wxChar szBuf[1024]; // @@ should dynamically allocate memory... 278 279 // first look in the private INI file 280 281 // NB: the lpDefault param to GetPrivateProfileString can't be NULL 282// GetPrivateProfileString(m_strGroup, strKey, "", 283// szBuf, WXSIZEOF(szBuf), m_strLocalFilename); 284 if ( ::IsEmpty((PSZ)szBuf) ) 285 { 286 // now look in win.ini 287 wxString strKey = GetKeyName(path.Name()); 288 // GetProfileString(m_strGroup, strKey, "", szBuf, WXSIZEOF(szBuf)); 289 } 290 291 if ( ::IsEmpty((PSZ)szBuf) ) 292 { 293 return false; 294 } 295 296 *pstr = szBuf ; 297 return true; 298} 299 300bool wxIniConfig::Read(const wxString& szKey, wxString *pstr, 301 const wxString& szDefault) const 302{ 303 wxConfigPathChanger path(this, szKey); 304 wxString strKey = GetPrivateKeyName(path.Name()); 305 306 wxChar szBuf[1024]; // @@ should dynamically allocate memory... 307 308 // first look in the private INI file 309 310 // NB: the lpDefault param to GetPrivateProfileString can't be NULL 311 // GetPrivateProfileString(m_strGroup, strKey, "", 312 // szBuf, WXSIZEOF(szBuf), m_strLocalFilename); 313 if ( ::IsEmpty((PSZ)szBuf) ) 314 { 315 // now look in win.ini 316 wxString strKey = GetKeyName(path.Name()); 317 // GetProfileString(m_strGroup, strKey, "", szBuf, WXSIZEOF(szBuf)); 318 } 319 320 if ( ::IsEmpty((PSZ)szBuf) ) 321 { 322 *pstr = szDefault; 323 return false; 324 } 325 else 326 { 327 *pstr = szBuf ; 328 return true; 329 } 330} 331 332bool wxIniConfig::Read(const wxString& szKey, long *pl) const 333{ 334 wxConfigPathChanger path(this, szKey); 335 wxString strKey = GetPrivateKeyName(path.Name()); 336 337 // hack: we have no mean to know if it really found the default value or 338 // didn't find anything, so we call it twice 339 340 static const int nMagic = 17; // 17 is some "rare" number 341 static const int nMagic2 = 28; // arbitrary number != nMagic 342 long lVal = 0; // = GetPrivateProfileInt(m_strGroup, strKey, nMagic, m_strLocalFilename); 343 344 if ( lVal != nMagic ) 345 { 346 // the value was read from the file 347 *pl = lVal; 348 return true; 349 } 350 351 // is it really nMagic? 352 // lVal = GetPrivateProfileInt(m_strGroup, strKey, nMagic2, m_strLocalFilename); 353 if ( lVal == nMagic2 ) 354 { 355 // the nMagic it returned was indeed read from the file 356 *pl = lVal; 357 return true; 358 } 359 360 // no, it was just returning the default value, so now look in win.ini 361 // *pl = GetProfileInt(GetVendorName(), GetKeyName(szKey), *pl); 362 363 return true; 364} 365 366bool wxIniConfig::Write(const wxString& szKey, const wxString& WXUNUSED(szValue)) 367{ 368 wxConfigPathChanger path(this, szKey); 369 wxString strKey = GetPrivateKeyName(path.Name()); 370 371 bool bOk = false; // = WritePrivateProfileString(m_strGroup, strKey, 372// szValue, m_strLocalFilename) != 0; 373 374 if ( !bOk ) 375 wxLogLastError(wxT("WritePrivateProfileString")); 376 377 return bOk; 378} 379 380bool wxIniConfig::Write(const wxString& szKey, long lValue) 381{ 382 // ltoa() is not ANSI :-( 383 wxChar szBuf[40]; // should be good for sizeof(long) <= 16 (128 bits) 384 wxSprintf(szBuf, wxT("%ld"), lValue); 385 386 return Write(szKey, szBuf); 387} 388 389bool wxIniConfig::Flush(bool /* bCurrentOnly */) 390{ 391 // this is just the way it works 392 // return WritePrivateProfileString(NULL, NULL, NULL, m_strLocalFilename) != 0; 393 return false; 394} 395 396// ---------------------------------------------------------------------------- 397// delete 398// ---------------------------------------------------------------------------- 399 400bool wxIniConfig::DeleteEntry(const wxString& szKey, bool bGroupIfEmptyAlso) 401{ 402 // passing NULL as value to WritePrivateProfileString deletes the key 403 // if ( !Write(szKey, (const char *)NULL) ) 404 // return false; 405 wxConfigPathChanger path(this, szKey); 406 wxString strKey = GetPrivateKeyName(path.Name()); 407 408 // if (WritePrivateProfileString(m_strGroup, szKey, 409 // (const char*) NULL, m_strLocalFilename) == 0) 410 // return false; 411 412 if ( !bGroupIfEmptyAlso || !IsEmpty() ) 413 return true; 414 415 // delete the current group too 416 bool bOk = false; // = WritePrivateProfileString(m_strGroup, NULL, 417 // NULL, m_strLocalFilename) != 0; 418 419 if ( !bOk ) 420 wxLogLastError(wxT("WritePrivateProfileString")); 421 422 return bOk; 423} 424 425bool wxIniConfig::DeleteGroup(const wxString& szKey) 426{ 427 wxConfigPathChanger path(this, szKey); 428 429 // passing NULL as section name to WritePrivateProfileString deletes the 430 // whole section according to the docs 431 bool bOk = false; // = WritePrivateProfileString(path.Name(), NULL, 432 // NULL, m_strLocalFilename) != 0; 433 434 if ( !bOk ) 435 wxLogLastError(wxT("WritePrivateProfileString")); 436 437 return bOk; 438} 439 440#ifndef MAX_PATH 441#define MAX_PATH 256 442#endif 443 444bool wxIniConfig::DeleteAll() 445{ 446 // first delete our group in win.ini 447 // WriteProfileString(GetVendorName(), NULL, NULL); 448 449 // then delete our own ini file 450 wxChar szBuf[MAX_PATH]; 451 size_t nRc = 0; // = GetWindowsDirectory(szBuf, WXSIZEOF(szBuf)); 452 if ( nRc == 0 ) 453 { 454 wxLogLastError(wxT("GetWindowsDirectory")); 455 } 456 else if ( nRc > WXSIZEOF(szBuf) ) 457 { 458 wxFAIL_MSG(_("buffer is too small for Windows directory.")); 459 } 460 461 wxString strFile = szBuf; 462 strFile << wxT('\\') << m_strLocalFilename; 463 464 if ( !wxRemoveFile(strFile) ) 465 { 466 wxLogSysError(_("Can't delete the INI file '%s'"), strFile.c_str()); 467 return false; 468 } 469 470 return true; 471} 472 473bool wxIniConfig::RenameEntry(const wxString& WXUNUSED(oldName), const wxString& WXUNUSED(newName)) 474{ 475 // Not implemented 476 return false; 477} 478 479bool wxIniConfig::RenameGroup(const wxString& WXUNUSED(oldName), const wxString& WXUNUSED(newName)) 480{ 481 // Not implemented 482 return false; 483} 484 485#endif //wxUSE_CONFIG 486