~ubuntu-branches/ubuntu/oneiric/nux/oneiric

« back to all changes in this revision

Viewing changes to NuxGraphics/IniFile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-06-22 17:16:16 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20110622171616-3cyhhiwsb6ga9d30
Tags: 1.0.2-0ubuntu1
* New upstream release.
* Cherry-pick a fix for FTBFS with -fpermissive
* debian/control:
  - add new libxdamage-dev and libxcomposite-dev build-dep
  - add new libboost1.42-dev dep as well, should be transitionned to 1.46 once
    compiz is transitionned as well
* remove debian/patches/01_build_with_gcc46.patch as included upstream
* debian/rules:
  - disable google code tests while building
* debian/control, debian/rules, debian/libnux-1.0-common.install,
  debian/libnux-1.0-dev.install, debian/libnux-1.0-doc.install,
  debian/libnux-1.0-0.install:
  - change, prepare next ABI breakage and remove no more needed Breaks: with
    new soname bump
* libnux-1.0-common now replaces: libnux-0.9-common for the apport hook

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2010 Inalogic® Inc.
3
 
 *
4
 
 * This program is free software: you can redistribute it and/or modify it
5
 
 * under the terms of the GNU Lesser General Public License, as
6
 
 * published by the  Free Software Foundation; either version 2.1 or 3.0
7
 
 * of the License.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful, but
10
 
 * WITHOUT ANY WARRANTY; without even the implied warranties of
11
 
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12
 
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
13
 
 * License for more details.
14
 
 *
15
 
 * You should have received a copy of both the GNU Lesser General Public
16
 
 * License along with this program. If not, see <http://www.gnu.org/licenses/>
17
 
 *
18
 
 * Authored by: Jay Taoko <jaytaoko@inalogic.com>
19
 
 *
20
 
 */
21
 
 
22
 
 
23
 
#include "NuxCore/NuxCore.h"
24
 
#include "GLResource.h"
25
 
#include "IniFile.h"
26
 
 
27
 
namespace nux
28
 
{
29
 
 
30
 
  struct RecordSectionIs : std::unary_function<CIniFile::Record, bool>
31
 
  {
32
 
    std::string section_;
33
 
 
34
 
    RecordSectionIs (const std::string &section) : section_ (section) {}
35
 
 
36
 
    bool operator() ( const CIniFile::Record &rec ) const
37
 
    {
38
 
      return rec.Section == section_;
39
 
    }
40
 
  };
41
 
 
42
 
  struct RecordSectionKeyIs : std::unary_function<CIniFile::Record, bool>
43
 
  {
44
 
    std::string section_;
45
 
    std::string key_;
46
 
 
47
 
    RecordSectionKeyIs (const std::string &section, const std::string &key) : section_ (section), key_ (key) {}
48
 
 
49
 
    bool operator() ( const CIniFile::Record &rec ) const
50
 
    {
51
 
      return ( (rec.Section == section_) && (rec.Key == key_) );
52
 
    }
53
 
  };
54
 
 
55
 
  struct AscendingSectionSort
56
 
  {
57
 
    bool operator() (const CIniFile::Record &Start, const CIniFile::Record &End)
58
 
    {
59
 
      return Start.Section < End.Section;
60
 
    }
61
 
  };
62
 
 
63
 
  struct DescendingSectionSort
64
 
  {
65
 
    bool operator() (const CIniFile::Record &Start, const CIniFile::Record &End)
66
 
    {
67
 
      return Start.Section > End.Section;
68
 
    }
69
 
  };
70
 
 
71
 
  struct AscendingRecordSort
72
 
  {
73
 
    bool operator() (const CIniFile::Record &Start, const CIniFile::Record &End)
74
 
    {
75
 
      return Start.Key < End.Key;
76
 
    }
77
 
  };
78
 
 
79
 
  struct DescendingRecordSort
80
 
  {
81
 
    bool operator() (const CIniFile::Record &Start, const CIniFile::Record &End)
82
 
    {
83
 
      return Start.Key > End.Key;
84
 
    }
85
 
  };
86
 
 
87
 
  CIniFile::CIniFile (void)                                                                                                     // Default constructor
88
 
  {
89
 
  }
90
 
 
91
 
  CIniFile::~CIniFile (void)
92
 
  {
93
 
  }
94
 
 
95
 
// A function to trim whitespace from both sides of a given string
96
 
  void Trim (std::string &str, const std::string &ChrsToTrim = " \t\n\r", int TrimDir = 0)
97
 
  {
98
 
    size_t startIndex = str.find_first_not_of (ChrsToTrim);
99
 
 
100
 
    if (startIndex == std::string::npos)
101
 
    {
102
 
      str.erase();
103
 
      return;
104
 
    }
105
 
 
106
 
    if (TrimDir < 2) str = str.substr (startIndex, str.size() - startIndex);
107
 
 
108
 
    if (TrimDir != 1) str = str.substr (0, str.find_last_not_of (ChrsToTrim) + 1);
109
 
  }
110
 
 
111
 
//inline void TrimRight(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
112
 
//{
113
 
//    Trim(str, ChrsToTrim, 2);
114
 
//}
115
 
 
116
 
//inline void TrimLeft(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
117
 
//{
118
 
//    Trim(str, ChrsToTrim, 1);
119
 
//}
120
 
 
121
 
// A function to transform a string to uppercase if neccessary
122
 
//void UCase(string& str, bool ucase)
123
 
//{
124
 
//      if(ucase) transform(str.begin(), str.end(), str.begin(), toupper);
125
 
//}
126
 
 
127
 
  bool CIniFile::Load (std::string FileName, std::vector<Record>& content)
128
 
  {
129
 
    std::string s;                                                                                                                              // Holds the current line from the ini file
130
 
    std::string CurrentSection;                                                                                                 // Holds the current section name
131
 
 
132
 
    std::ifstream inFile (FileName.c_str() );                                                                           // Create an input filestream
133
 
 
134
 
    if (!inFile.is_open() ) return false;                                                                       // If the input file doesn't open, then return
135
 
 
136
 
    content.clear();                                                                                                            // Clear the content vector
137
 
 
138
 
    std::string comments = "";                                                                                                  // A string to store comments in
139
 
 
140
 
    while (!inFile.eof() /*!std::getline(inFile, s).eof()*/)                                                                    // Read until the end of the file
141
 
    {
142
 
      std::getline (inFile, s);
143
 
      Trim (s);                                                                                                                 // Trim whitespace from the ends
144
 
 
145
 
      if (!s.empty() )                                                                                                          // Make sure its not a blank line
146
 
      {
147
 
        Record r;                                                                                                               // Define a new record
148
 
 
149
 
        if ( (s[0] == '#') || (s[0] == ';') )                                                                   // Is this a commented line?
150
 
        {
151
 
          if ( (s.find ('[') == std::string::npos) &&                                                   // If there is no [ or =
152
 
               (s.find ('=') == std::string::npos) )                                                    // Then it's a comment
153
 
          {
154
 
            comments += s + '\n';                                                                       // Add the comment to the current comments string
155
 
          }
156
 
          else
157
 
          {
158
 
            r.Commented = s[0];                                                                         // Save the comment character
159
 
            s.erase (s.begin() );                                                                               // Remove the comment for further processing
160
 
            Trim (s);
161
 
          }// Remove any more whitespace
162
 
        }
163
 
        else r.Commented = ' ';                                                                         // else mark it as not being a comment
164
 
 
165
 
        if (s.find ('[') != std::string::npos)                                                                  // Is this line a section?
166
 
        {
167
 
          s.erase (s.begin() );                                                                                 // Erase the leading bracket
168
 
          s.erase (s.find (']') );                                                                              // Erase the trailing bracket
169
 
          Trim (s);
170
 
          r.Comments = comments;                                                                                // Add the comments string (if any)
171
 
          comments = "";                                                                                                // Clear the comments for re-use
172
 
          r.Section = s;                                                                                                // Set the Section value
173
 
          r.Key = "";                                                                                                   // Set the Key value
174
 
          r.Value = "";                                                                                         // Set the Value value
175
 
          CurrentSection = s;
176
 
        }
177
 
 
178
 
        if (s.find ('=') != std::string::npos)                                                                  // Is this line a Key/Value?
179
 
        {
180
 
          r.Comments = comments;                                                                                // Add the comments string (if any)
181
 
          comments = "";                                                                                                // Clear the comments for re-use
182
 
          r.Section = CurrentSection;                                                                   // Set the section to the current Section
183
 
          r.Key = s.substr (0, s.find ('=') );                                                  // Set the Key value to everything before the = sign
184
 
          Trim (r.Key);
185
 
          r.Value = s.substr (s.find ('=') + 1);                                                        // Set the Value to everything after the = sign
186
 
          Trim (r.Value);
187
 
        }
188
 
 
189
 
        if (comments == "")                                                                                             // Don't add a record yet if its a comment line
190
 
          content.push_back (r);                                                                                // Add the record to content
191
 
      }
192
 
    }
193
 
 
194
 
    inFile.close();                                                                                                                     // Close the file
195
 
    return true;
196
 
  }
197
 
 
198
 
  bool CIniFile::Save (std::string FileName, std::vector<Record>& content)
199
 
  {
200
 
    std::ofstream outFile (FileName.c_str() );                                                                  // Create an output filestream
201
 
 
202
 
    if (!outFile.is_open() ) return false;                                                                      // If the output file doesn't open, then return
203
 
 
204
 
    for (int i = 0; i < (int) content.size(); i++)                                                                      // Loop through each vector
205
 
    {
206
 
      outFile << content[i].Comments;                                                                           // Write out the comments
207
 
 
208
 
      if (content[i].Key == "")                                                                                 // Is this a section?
209
 
        outFile << content[i].Commented << "["
210
 
                << content[i].Section << "]" << std::endl;                                                      // Then format the section
211
 
      else
212
 
        outFile << content[i].Commented << content[i].Key
213
 
                << "=" << content[i].Value << std::endl;                                                                // Else format a key/value
214
 
    }
215
 
 
216
 
    outFile.close();                                                                                                            // Close the file
217
 
    return true;
218
 
  }
219
 
 
220
 
  std::string CIniFile::Content (std::string FileName)
221
 
  {
222
 
    std::string s = "";                               // Hold our return string
223
 
    std::vector<Record> content;                      // Holds the current record // Holds the current record
224
 
 
225
 
    if (Load (FileName, content) )                    // Make sure the file loads
226
 
    {
227
 
      for (int i = 0; i < (int) content.size(); i++)  // Loop through the content
228
 
      {
229
 
        if (content[i].Comments != "") s += content[i].Comments;                        // Add the comments
230
 
 
231
 
        if (content[i].Commented != ' ') s += content[i].Commented;             // If this is commented, then add it
232
 
 
233
 
        if ( (content[i].Key == "") )                                                                           // Is this a section?
234
 
          s += '[' + content[i].Section + ']';                                          // Add the section
235
 
        else s += content[i].Key + '=' + content[i].Value;                              // Or the Key value to the return srting
236
 
 
237
 
        if (i != (int) content.size() ) s += '\n';                                                              // If this is not the last line, add a CrLf
238
 
      }
239
 
 
240
 
      return s;                                                                                                                 // Return the contents
241
 
    }
242
 
 
243
 
    return "";
244
 
  }
245
 
 
246
 
  std::vector<std::string> CIniFile::GetSectionNames (std::string FileName)
247
 
  {
248
 
    std::vector<std::string> data;                                                                                                      // Holds the return data
249
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
250
 
 
251
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
252
 
    {
253
 
      for (int i = 0; i < (int) content.size(); i++)                                                            // Loop through the content
254
 
      {
255
 
        if (content[i].Key == "")                                                                                       // If there is no key value, then its a section
256
 
          data.push_back (content[i].Section);                                                  // Add the section to the return data
257
 
      }
258
 
    }
259
 
 
260
 
    return data;                                                                                                                        // Return the data
261
 
  }
262
 
 
263
 
  std::vector<CIniFile::Record> CIniFile::GetSection (std::string SectionName, std::string FileName)
264
 
  {
265
 
    std::vector<Record> data;                                                                                                   // Holds the return data
266
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
267
 
 
268
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
269
 
    {
270
 
      for (int i = 0; i < (int) content.size(); i++)                                                            // Loop through the content
271
 
      {
272
 
        if ( (content[i].Section == SectionName) &&                                             // If this is the section name we want
273
 
             (content[i].Key != "") )                                                                           // but not the section name itself
274
 
          data.push_back (content[i]);                                                                  // Add the record to the return data
275
 
      }
276
 
    }
277
 
 
278
 
    return data;                                                                                                                        // Return the data
279
 
  }
280
 
 
281
 
  bool CIniFile::RecordExists (std::string KeyName, std::string SectionName, std::string FileName)
282
 
  {
283
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
284
 
 
285
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
286
 
    {
287
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
288
 
                                           content.end(),
289
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Section/Key
290
 
 
291
 
      if (iter == content.end() ) return false;                                                 // The Section/Key was not found
292
 
    }
293
 
 
294
 
    return true;                                                                                                                        // The Section/Key was found
295
 
  }
296
 
 
297
 
  bool CIniFile::SectionExists (std::string SectionName, std::string FileName)
298
 
  {
299
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
300
 
 
301
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
302
 
    {
303
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
304
 
                                           content.end(),
305
 
                                           RecordSectionIs (SectionName) );                                     // Locate the Section
306
 
 
307
 
      if (iter == content.end() ) return false;                                                 // The Section was not found
308
 
    }
309
 
 
310
 
    return true;                                                                                                                        // The Section was found
311
 
  }
312
 
 
313
 
  std::vector<CIniFile::Record> CIniFile::GetRecord (std::string KeyName, std::string SectionName, std::string FileName)
314
 
  {
315
 
    std::vector<Record> data;                                                                                                   // Holds the return data
316
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
317
 
 
318
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
319
 
    {
320
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
321
 
                                           content.end(),
322
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Record
323
 
 
324
 
      if (iter == content.end() ) return data;                                                          // The Record was not found
325
 
 
326
 
      data.push_back (*iter);                                                                                           // The Record was found
327
 
    }
328
 
 
329
 
    return data;                                                                                                                        // Return the Record
330
 
  }
331
 
 
332
 
  std::string CIniFile::GetValue (std::string KeyName, std::string SectionName, std::string FileName)
333
 
  {
334
 
    std::vector<Record> content = GetRecord (KeyName, SectionName, FileName);           // Get the Record
335
 
 
336
 
    if (!content.empty() )                                                                                                      // Make sure there is a value to return
337
 
      return content[0].Value;                                                                                  // And return the value
338
 
 
339
 
    return "";                                                                                                                          // No value was found
340
 
  }
341
 
 
342
 
  bool CIniFile::SetValue (std::string KeyName, std::string Value, std::string SectionName, std::string FileName)
343
 
  {
344
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
345
 
 
346
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
347
 
    {
348
 
      if (!SectionExists (SectionName, FileName) )                                                      // If the Section doesn't exist
349
 
      {
350
 
        Record s = {"", ' ', SectionName, "", ""};                                                      // Define a new section
351
 
        Record r = {"", ' ', SectionName, KeyName, Value};                                      // Define a new record
352
 
        content.push_back (s);                                                                                  // Add the section
353
 
        content.push_back (r);                                                                                  // Add the record
354
 
        return Save (FileName, content);                                                                        // Save
355
 
      }
356
 
 
357
 
      if (!RecordExists (KeyName, SectionName, FileName) )                                              // If the Key doesn't exist
358
 
      {
359
 
        std::vector<Record>::iterator iter = std::find_if (content.begin(),
360
 
                                             content.end(),
361
 
                                             RecordSectionIs (SectionName) );                  // Locate the Section
362
 
        iter++;                                                         // Advance just past the section
363
 
        Record r = {"", ' ', SectionName, KeyName, Value};              // Define a new record
364
 
        content.insert (iter, r);                                                                                       // Add the record
365
 
        return Save (FileName, content);                                                                        // Save
366
 
      }
367
 
 
368
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
369
 
                                           content.end(),
370
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Record
371
 
 
372
 
      iter->Value = Value;                                                                                              // Insert the correct value
373
 
      return Save (FileName, content);                                                                          // Save
374
 
    }
375
 
 
376
 
    return false;                                                                                                                       // In the event the file does not load
377
 
  }
378
 
 
379
 
  bool CIniFile::RenameSection (std::string OldSectionName, std::string NewSectionName, std::string FileName)
380
 
  {
381
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
382
 
 
383
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
384
 
    {
385
 
      for (std::vector<Record>::iterator iter = content.begin();
386
 
           iter < content.end(); iter++)                                                                        // Loop through the records
387
 
      {
388
 
        if (iter->Section == OldSectionName)                                                            // Is this the OldSectionName?
389
 
          iter->Section = NewSectionName;                                                               // Now its the NewSectionName
390
 
      }
391
 
 
392
 
      return Save (FileName, content);                                                                          // Save
393
 
    }
394
 
 
395
 
    return false;                                                                                                                       // In the event the file does not load
396
 
  }
397
 
 
398
 
  bool CIniFile::CommentRecord (CommentChar cc, std::string KeyName, std::string SectionName, std::string FileName)
399
 
  {
400
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
401
 
 
402
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
403
 
    {
404
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
405
 
                                           content.end(),
406
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Section/Key
407
 
 
408
 
      if (iter == content.end() ) return false;                                                 // The Section/Key was not found
409
 
 
410
 
      iter->Commented = cc;                                                                             // Change the Comment value
411
 
      return Save (FileName, content);                                                                          // Save
412
 
 
413
 
    }
414
 
 
415
 
    return false;                                                                                                                       // In the event the file does not load
416
 
  }
417
 
 
418
 
  bool CIniFile::UnCommentRecord (std::string KeyName, std::string SectionName, std::string FileName)
419
 
  {
420
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
421
 
 
422
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
423
 
    {
424
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
425
 
                                           content.end(),
426
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Section/Key
427
 
 
428
 
      if (iter == content.end() ) return false;                                                 // The Section/Key was not found
429
 
 
430
 
      iter->Commented = ' ';                                                                                            // Remove the Comment value
431
 
      return Save (FileName, content);                                                                          // Save
432
 
 
433
 
    }
434
 
 
435
 
    return false;                                                                                                                       // In the event the file does not load
436
 
  }
437
 
 
438
 
  bool CIniFile::CommentSection (char CommentChar, std::string SectionName, std::string FileName)
439
 
  {
440
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
441
 
 
442
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
443
 
    {
444
 
      for (std::vector<Record>::iterator iter = content.begin(); iter < content.end(); iter++)
445
 
      {
446
 
        if (iter->Section == SectionName)                                                               // Is this the right section?
447
 
          iter->Commented = CommentChar;                                                                // Change the comment value
448
 
      }
449
 
 
450
 
      return Save (FileName, content);                                                                          // Save
451
 
    }
452
 
 
453
 
    return false;                                                                                                                       // In the event the file does not load
454
 
  }
455
 
 
456
 
  bool CIniFile::UnCommentSection (std::string SectionName, std::string FileName)
457
 
  {
458
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
459
 
 
460
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
461
 
    {
462
 
      for (std::vector<Record>::iterator iter = content.begin(); iter < content.end(); iter++)
463
 
      {
464
 
        if (iter->Section == SectionName)                                                               // Is this the right section?
465
 
          iter->Commented = ' ';                                                                                // Remove the comment value
466
 
      }
467
 
 
468
 
      return Save (FileName, content);                                                                          // Save
469
 
    }
470
 
 
471
 
    return false;                                                                                                                       // In the event the file does not load
472
 
  }
473
 
 
474
 
  bool CIniFile::DeleteRecord (std::string KeyName, std::string SectionName, std::string FileName)
475
 
  {
476
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
477
 
 
478
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
479
 
    {
480
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
481
 
                                           content.end(),
482
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Section/Key
483
 
 
484
 
      if (iter == content.end() ) return false;                                                 // The Section/Key was not found
485
 
 
486
 
      content.erase (iter);                                                                                             // Remove the Record
487
 
      return Save (FileName, content);                                                                          // Save
488
 
 
489
 
    }
490
 
 
491
 
    return false;                                                                                                                       // In the event the file does not load
492
 
  }
493
 
 
494
 
  bool CIniFile::DeleteSection (std::string SectionName, std::string FileName)
495
 
  {
496
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
497
 
 
498
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
499
 
    {
500
 
      for (int i = (int) content.size() - 1; i > -1; i--)                                                               // Iterate backwards through the content
501
 
      {
502
 
        if (content[i].Section == SectionName)                                                  // Is this related to the Section?
503
 
          content.erase (content.begin() + i);                                                  // Then erase it
504
 
      }
505
 
 
506
 
      return Save (FileName, content);                                                                          // Save
507
 
    }
508
 
 
509
 
    return false;                                                                                                                       // In the event the file does not load
510
 
  }
511
 
 
512
 
  bool CIniFile::SetSectionComments (std::string Comments, std::string SectionName, std::string FileName)
513
 
  {
514
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
515
 
 
516
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
517
 
    {
518
 
      for (std::vector<Record>::iterator iter = content.begin(); iter < content.end(); iter++)                                                                  // Loop through the records
519
 
      {
520
 
        if ( (iter->Section == SectionName) &&                                                  // Is this the Section?
521
 
             (iter->Key == "") )                                                                                        // And not a record
522
 
        {
523
 
          if (Comments.size() >= 2)                                                                     // Is there a comment?
524
 
          {
525
 
            if (Comments.substr (Comments.size() - 2) != "\n")          // Does the string end in a newline?
526
 
              Comments += "\n";                                                         // If not, add one
527
 
          }
528
 
 
529
 
          iter->Comments = Comments;                                                            // Set the comments
530
 
 
531
 
          return Save (FileName, content);                                                      // Save
532
 
        }
533
 
      }
534
 
    }
535
 
 
536
 
    return false;                                                                                                                       // In the event the file does not load
537
 
  }
538
 
 
539
 
  bool CIniFile::SetRecordComments (std::string Comments, std::string KeyName, std::string SectionName, std::string FileName)
540
 
  {
541
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
542
 
 
543
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
544
 
    {
545
 
      std::vector<Record>::iterator iter = std::find_if (content.begin(),
546
 
                                           content.end(),
547
 
                                           RecordSectionKeyIs (SectionName, KeyName) );                 // Locate the Section/Key
548
 
 
549
 
      if (iter == content.end() ) return false;                                                 // The Section/Key was not found
550
 
 
551
 
      if (Comments.size() >= 2)                                                                                 // Is there a comment?
552
 
      {
553
 
        if (Comments.substr (Comments.size() - 2) != "\n")                                      // Does the string end in a newline?
554
 
          Comments += "\n";                                                                                     // If not, add one
555
 
      }
556
 
 
557
 
      iter->Comments = Comments;                                                                                        // Set the comments
558
 
      return Save (FileName, content);                                                                          // Save
559
 
 
560
 
    }
561
 
 
562
 
    return false;                                                                                                                       // In the event the file does not load
563
 
  }
564
 
 
565
 
  std::vector<CIniFile::Record> CIniFile::GetSections (std::string FileName)
566
 
  {
567
 
    std::vector<Record> data;                                                                                                   // Holds the return data
568
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
569
 
 
570
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
571
 
    {
572
 
      for (int i = 0; i < (int) content.size(); i++)                                                            // Loop through the content
573
 
      {
574
 
        if (content[i].Key == "")                                                                               // If this is a section
575
 
          data.push_back (content[i]);                                                                  // Add the record to the return data
576
 
      }
577
 
    }
578
 
 
579
 
    return data;                                                                                                                        // Return the data
580
 
  }
581
 
 
582
 
 
583
 
  bool CIniFile::Sort (std::string FileName, bool Descending)
584
 
  {
585
 
    std::vector<CIniFile::Record> content;                                                                              // Used to hold the sorted content
586
 
    std::vector<CIniFile::Record> sections = GetSections (FileName);                            // Get a list of Sections
587
 
 
588
 
    if (!sections.empty() )                                                                                                     // Is there anything to process?
589
 
    {
590
 
 
591
 
      if (Descending)                                                                                                           // Descending or Ascending?
592
 
        std::sort (sections.begin(), sections.end(), DescendingSectionSort() );
593
 
      else                                                                                                                              // Sort the Sections
594
 
        std::sort (sections.begin(), sections.end(), AscendingSectionSort() );
595
 
 
596
 
      for (std::vector<Record>::iterator iter = sections.begin(); iter < sections.end(); iter++) // For each Section
597
 
      {
598
 
        content.push_back (*iter);                                                                              // Add the sorted Section to the content
599
 
 
600
 
        std::vector<CIniFile::Record> records = GetSection (iter->Section , FileName); // Get a list of Records for this section
601
 
 
602
 
        if (Descending)                                                                                                 // Descending or Ascending?
603
 
          std::sort (records.begin(), records.end(), DescendingRecordSort() );
604
 
        else                                                                                                                    // Sort the Records
605
 
          std::sort (records.begin(), records.end(), AscendingRecordSort() );
606
 
 
607
 
        for (std::vector<Record>::iterator it = records.begin(); it < records.end(); it++) // For each Record
608
 
          content.push_back (*it);                                                                              // Add the sorted Record to the content
609
 
      }
610
 
 
611
 
      return Save (FileName, content);                                                                          // Save
612
 
    }
613
 
 
614
 
    return false;                                                                                                                       // There were no sections
615
 
  }
616
 
 
617
 
  bool CIniFile::AddSection (std::string SectionName, std::string FileName)
618
 
  {
619
 
    std::vector<Record> content;                                                                                                        // Holds the current record                                                                                                     // Holds the current record
620
 
 
621
 
    if (Load (FileName, content) )                                                                                      // Make sure the file is loaded
622
 
    {
623
 
      Record s = {"", ' ', SectionName, "", ""};                                                                // Define a new section
624
 
      content.push_back (s);                                                                                            // Add the section
625
 
      return Save (FileName, content);                                                                          // Save
626
 
    }
627
 
 
628
 
    return false;                                                                                                                       // The file did not open
629
 
  }
630
 
 
631
 
  bool CIniFile::Create (std::string FileName)
632
 
  {
633
 
    std::vector<Record> content;                                                                                                        // Create empty content
634
 
    return Save (FileName, content);                                                                                    // Save
635
 
  }
636
 
 
637
 
 
638
 
  void Show (std::string FileName)
639
 
  {
640
 
    std::cout << std::endl
641
 
              << "++++++++++++++++++++++++++++++++++++++++"
642
 
              << std::endl
643
 
              << "+ Contents of the file are below       +"
644
 
              << std::endl
645
 
              << "++++++++++++++++++++++++++++++++++++++++"
646
 
              << std::endl
647
 
              << CIniFile::Content (FileName)
648
 
              << std::endl
649
 
              << "++++++++++++++++++++++++++++++++++++++++"
650
 
              << std::endl << std::endl;
651
 
  }
652
 
 
653
 
  int Usage()
654
 
  {
655
 
    //CIniFile IniFile;
656
 
    std::string FileName = "test.ini";
657
 
 
658
 
    // Create a new file
659
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
660
 
    std::cout << "Attempting to create a new file called \"test.ini\"" << std::endl << std::endl;
661
 
    std::cout << "string FileName = \"test.ini\";" << std::endl;
662
 
    std::cout << "CIniFile::Create(FileName);" << std::endl << std::endl;
663
 
 
664
 
    if (CIniFile::Create (FileName) ) std::cout << "File was successfully created" << std::endl << std::endl;
665
 
    else std::cout << "Failed to create the file" << std::endl << std::endl;
666
 
 
667
 
    Show (FileName);
668
 
 
669
 
    // Create a new section
670
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
671
 
    std::cout << "Attempting to create a new section called [MySection]" << std::endl << std::endl;
672
 
    std::cout << "CIniFile::AddSection(\"MySection\", FileName);" << std::endl << std::endl;
673
 
 
674
 
    if (CIniFile::AddSection ("MySection", FileName) ) std::cout << "Section was successfully created" << std::endl << std::endl;
675
 
    else std::cout << "Failed to create the section" << std::endl << std::endl;
676
 
 
677
 
    Show (FileName);
678
 
 
679
 
    // Add a key to the section
680
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
681
 
    std::cout << "Attempting to add a new key/value (MyKey=MyValue) to [MySection]" << std::endl << std::endl;
682
 
    std::cout << "CIniFile::SetValue(\"MyKey\",\"MyValue\",\"MySection\",FileName);" << std::endl << std::endl;
683
 
 
684
 
    if (CIniFile::SetValue ("MyKey", "MyValue", "MySection", FileName) ) std::cout << "Record was successfully created" << std::endl << std::endl;
685
 
    else std::cout << "Failed to create the record" << std::endl << std::endl;
686
 
 
687
 
    Show (FileName);
688
 
 
689
 
    // Add a key and create a section
690
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
691
 
    std::cout << "Attempting to add a new key/value (TestKey=TestValue)" << std::endl << "and create a new section [TestSection] at the same time" << std::endl << std::endl;
692
 
    std::cout << "CIniFile::SetValue(\"TestKey\",\"TestValue\",\"TestSection\",FileName);" << std::endl << std::endl;
693
 
 
694
 
    if (CIniFile::SetValue ("TestKey", "TestValue", "TestSection", FileName) ) std::cout << "Record and section were successfully created" << std::endl << std::endl;
695
 
    else std::cout << "Failed to create the record and section" << std::endl << std::endl;
696
 
 
697
 
    Show (FileName);
698
 
 
699
 
    // Change a key value
700
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
701
 
    std::cout << "Attempting to change the key/value for (MyKey=MyValue) to (MyKey=YourValue)" << std::endl << std::endl;
702
 
    std::cout << "CIniFile::SetValue(\"MyKey\",\"YourValue\",\"MySection\",FileName);" << std::endl << std::endl;
703
 
 
704
 
    if (CIniFile::SetValue ("MyKey", "YourValue", "MySection", FileName) ) std::cout << "Record was successfully changed" << std::endl << std::endl;
705
 
    else std::cout << "Failed to change the record" << std::endl << std::endl;
706
 
 
707
 
    Show (FileName);
708
 
 
709
 
    // Get a value
710
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
711
 
    std::cout << "Attempting to get the value of MyKey" << std::endl << std::endl;
712
 
    std::cout << "CIniFile::GetValue(\"MyKey\",\"MySection\",FileName);" << std::endl << std::endl;
713
 
    std::string v = CIniFile::GetValue ("MyKey", "MySection", FileName);
714
 
    std::cout << "The value of MyKey is: " << v.c_str() << std::endl << std::endl;
715
 
    Show (FileName);
716
 
 
717
 
    // Get a list of Sections
718
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
719
 
    std::cout << "Attempting to get a list of sections" << std::endl << std::endl;
720
 
    std::cout << "CIniFile::GetSectionNames(FileName);" << std::endl << std::endl;
721
 
    std::vector<std::string> s = CIniFile::GetSectionNames (FileName);
722
 
    std::cout << "The sections are returned as a std::vector<std::string>\n\n";
723
 
 
724
 
    for (int i = 0; i < (int) s.size(); i++)
725
 
      std::cout << s[i].c_str() << std::endl;
726
 
 
727
 
    Show (FileName);
728
 
 
729
 
    // Section Exists
730
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
731
 
    std::cout << "Attempting to verify that [MySection] exists" << std::endl << std::endl;
732
 
    std::cout << "CIniFile::SectionExists(\"MySection\",FileName);" << std::endl << std::endl;
733
 
 
734
 
    if (CIniFile::SectionExists ("MySection", FileName) ) std::cout << "Section exists" << std::endl << std::endl;
735
 
    else std::cout << "Section does not exist" << std::endl << std::endl;
736
 
 
737
 
    Show (FileName);
738
 
 
739
 
    // Record Exists
740
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
741
 
    std::cout << "Attempting to verify that MyKey exists" << std::endl << std::endl;
742
 
    std::cout << "CIniFile::RecordExists(\"MyKey\",\"MySection\",FileName);" << std::endl << std::endl;
743
 
 
744
 
    if (CIniFile::RecordExists ("MyKey", "MySection", FileName) ) std::cout << "Record exists" << std::endl << std::endl;
745
 
    else std::cout << "Record does not exist" << std::endl << std::endl;
746
 
 
747
 
    Show (FileName);
748
 
 
749
 
    // Case Sensitive
750
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
751
 
    std::cout << "BE CAREFUL - functions in CIniFile are CASE-SENSITIVE" << std::endl << std::endl;
752
 
    std::cout << "CIniFile::RecordExists(\"mykey\",\"MySection\",FileName);" << std::endl << std::endl;
753
 
 
754
 
    if (CIniFile::RecordExists ("mykey", "MySection", FileName) ) std::cout << "Record exists" << std::endl << std::endl;
755
 
    else std::cout << "Record does not exist" << std::endl << std::endl;
756
 
 
757
 
    Show (FileName);
758
 
 
759
 
    // Add a comment to the section
760
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
761
 
    std::cout << "Attempting to add comments to [MySection]" << std::endl << std::endl;
762
 
    std::cout << "CIniFile::SetSectionComments(\"# This Section was created by CIniFile\\n\",\"MySection\",FileName);" << std::endl << std::endl;
763
 
 
764
 
    if (CIniFile::SetSectionComments ("# This Section was created by CIniFile\n", "MySection", FileName) ) std::cout << "Comments were successfully added" << std::endl << std::endl;
765
 
    else std::cout << "Failed to add the comments" << std::endl << std::endl;
766
 
 
767
 
    Show (FileName);
768
 
 
769
 
    // Add a comment to the record
770
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
771
 
    std::cout << "Attempting to add comments to MyKey" << std::endl << std::endl;
772
 
    std::cout << "CIniFile::SetRecordComments(\"# This Key was created by CIniFile\\n\",\"MyKey\",\"MySection\",FileName);" << std::endl << std::endl;
773
 
 
774
 
    if (CIniFile::SetRecordComments ("# This Key was created by CIniFile\n", "MyKey", "MySection", FileName) ) std::cout << "Comments were successfully added" << std::endl << std::endl;
775
 
    else std::cout << "Failed to add the comments" << std::endl << std::endl;
776
 
 
777
 
    Show (FileName);
778
 
 
779
 
    // Rename Section
780
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
781
 
    std::cout << "Attempting to rename [MySection] to [YourSection]" << std::endl << std::endl;
782
 
    std::cout << "CIniFile::RenameSection(\"MySection\",\"YourSection\",FileName);" << std::endl << std::endl;
783
 
 
784
 
    if (CIniFile::RenameSection ("MySection", "YourSection", FileName) ) std::cout << "Section was successfully changed" << std::endl << std::endl;
785
 
    else std::cout << "Failed to change the section" << std::endl << std::endl;
786
 
 
787
 
    Show (FileName);
788
 
 
789
 
    // Multiple comments
790
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
791
 
    std::cout << "Multiple comments can be added by putting \\n# in the comments string" << std::endl << std::endl;
792
 
    std::cout << "CIniFile::SetSectionComments(\"# This Section was created by CIniFile\\n# Kids, don't try this at home \\n\",\"YourSection\",FileName);" << std::endl << std::endl;
793
 
 
794
 
    if (CIniFile::SetSectionComments ("# This Section was created by CIniFile\n# Kids, don't try this at home", "YourSection", FileName) ) std::cout << "Comments were successfully added" << std::endl << std::endl;
795
 
    else std::cout << "Failed to add the comments" << std::endl << std::endl;
796
 
 
797
 
    Show (FileName);
798
 
 
799
 
    // Remove comments
800
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
801
 
    std::cout << "Comments are removed by setting them to \"\"" << std::endl << std::endl;
802
 
    std::cout << "CIniFile::SetRecordComments(\"\",\"MyKey\",\"YourSection\",FileName);" << std::endl << std::endl;
803
 
 
804
 
    if (CIniFile::SetRecordComments ("", "MyKey", "YourSection", FileName) ) std::cout << "Comments were successfully removed" << std::endl << std::endl;
805
 
    else std::cout << "Failed to remove the comments" << std::endl << std::endl;
806
 
 
807
 
    Show (FileName);
808
 
 
809
 
    // Comment entire section
810
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
811
 
    std::cout << "Attempting to comment the entire section [YourSection]" << std::endl << std::endl;
812
 
    std::cout << "CIniFile::CommentSection(\"#\",\"YourSection\",FileName);" << std::endl << std::endl;
813
 
 
814
 
    if (CIniFile::CommentSection ('#', "YourSection", FileName) ) std::cout << "Section was successfully commented" << std::endl << std::endl;
815
 
    else std::cout << "Failed to comment the section" << std::endl << std::endl;
816
 
 
817
 
    Show (FileName);
818
 
 
819
 
    // UnComment entire section
820
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
821
 
    std::cout << "Attempting to un-comment the entire section [YourSection]" << std::endl << std::endl;
822
 
    std::cout << "CIniFile::UnCommentSection(\"YourSection\",FileName);" << std::endl << std::endl;
823
 
 
824
 
    if (CIniFile::UnCommentSection ("YourSection", FileName) ) std::cout << "Section was successfully un-commented" << std::endl << std::endl;
825
 
    else std::cout << "Failed to un-comment the section" << std::endl << std::endl;
826
 
 
827
 
    Show (FileName);
828
 
 
829
 
    // Comment a single record
830
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
831
 
    std::cout << "Attempting to comment the record MyKey" << std::endl << std::endl;
832
 
    std::cout << "(Note that both # and ; are recognized as commented lines by CIniFile)" << std::endl << std::endl;
833
 
    std::cout << "CIniFile::CommentRecord(CIniFile::CommentChar::Pound,\"MyKey\",\"YourSection\",FileName);" << std::endl << std::endl;
834
 
 
835
 
    if (CIniFile::CommentRecord (CIniFile::Pound, "MyKey", "YourSection", FileName) )
836
 
      std::cout << "Record was successfully commented" << std::endl << std::endl;
837
 
    else
838
 
      std::cout << "Failed to comment the record" << std::endl << std::endl;
839
 
 
840
 
    Show (FileName);
841
 
 
842
 
    // UnComment a single record
843
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
844
 
    std::cout << "Attempting to un-comment the record MyKey" << std::endl << std::endl;
845
 
    std::cout << "CIniFile::UnCommentRecord(\"MyKey\",\"YourSection\",FileName);" << std::endl << std::endl;
846
 
 
847
 
    if (CIniFile::UnCommentRecord ("MyKey", "YourSection", FileName) ) std::cout << "Record was successfully un-commented" << std::endl << std::endl;
848
 
    else std::cout << "Failed to un-comment the record" << std::endl << std::endl;
849
 
 
850
 
    Show (FileName);
851
 
 
852
 
    // Sort
853
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
854
 
    std::cout << "Attempting to sort the file - false means ASCENDING, true means DESCENDING" << std::endl << std::endl;
855
 
    std::cout << "(Note that the comments will stay with their targets)" << std::endl << std::endl;
856
 
    std::cout << "CIniFile::Sort(FileName,false);" << std::endl << std::endl;
857
 
 
858
 
    if (CIniFile::Sort (FileName, false) ) std::cout << "File was successfully sorted" << std::endl << std::endl;
859
 
    else std::cout << "Failed to sort the file" << std::endl << std::endl;
860
 
 
861
 
    Show (FileName);
862
 
 
863
 
    // Delete entire section
864
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
865
 
    std::cout << "Attempting to delete the entire section [TestSection]" << std::endl << std::endl;
866
 
    std::cout << "CIniFile::DeleteSection(\"TestSection\",FileName);" << std::endl << std::endl;
867
 
 
868
 
    if (CIniFile::DeleteSection ("TestSection", FileName) ) std::cout << "Section was successfully deleted" << std::endl << std::endl;
869
 
    else std::cout << "Failed to delete the section" << std::endl << std::endl;
870
 
 
871
 
    Show (FileName);
872
 
 
873
 
    // Delete record
874
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
875
 
    std::cout << "Attempting to delete the record <yKey" << std::endl << std::endl;
876
 
    std::cout << "CIniFile::DeleteRecord(\"MyKey\",\"YourSection\",FileName);" << std::endl << std::endl;
877
 
 
878
 
    if (CIniFile::DeleteRecord ("MyKey", "YourSection", FileName) ) std::cout << "Record was successfully deleted" << std::endl << std::endl;
879
 
    else std::cout << "Failed to delete the record" << std::endl << std::endl;
880
 
 
881
 
    Show (FileName);
882
 
 
883
 
    // Content
884
 
    std::cout << "TestIniFile - Demo program for the CIniFile Class" << std::endl << std::endl;
885
 
    std::cout << "Finally, the content of the file can be retrieved as a std::string" << std::endl << std::endl;
886
 
    std::cout << "CIniFile::Content(FileName);" << std::endl << std::endl;
887
 
    std::cout << "The contents of the file throughout this demo have used this function to display the contents below" << std::endl;
888
 
    Show (FileName);
889
 
 
890
 
    return 0;
891
 
  }
892
 
}