~thumper/nux/next-changes

« back to all changes in this revision

Viewing changes to NuxGraphics/IniFile.cpp

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 21:15:42 UTC
  • Revision ID: neil.patel@canonical.com-20100901211542-cw2ce3ak28unouwb
Add NuxGraphics with licensing

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