1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include "IniFile.h" 34 #include "Helpers.h" 35 36 #include <string> 37 38 39 IniFile::IniFile() : ISectionalPropertyContainer() { 40 } 41 42 IniFile::~IniFile() { 43 std::vector<TString> keys = FMap.GetKeys(); 44 45 for (size_t index = 0; index < keys.size(); index++) { 46 TString key = keys[index]; 47 48 IniSectionData* item; 49 50 if (FMap.GetValue(key, item) == true) { 51 if (item != NULL) { 52 delete item; 53 item = NULL; 54 } 55 } 56 } 57 } 58 59 bool IniFile::LoadFromFile(const TString FileName) { 60 bool result = false; 61 Platform& platform = Platform::GetInstance(); 62 63 std::list<TString> contents = platform.LoadFromFile(FileName); 64 65 if (contents.empty() == false) { 66 bool found = false; 67 68 // Determine the if file is an INI file or property file. Assign FDefaultSection if it is 69 // an INI file. Otherwise FDefaultSection is NULL. 70 for (std::list<TString>::const_iterator iterator = contents.begin(); iterator != contents.end(); iterator++) { 71 TString line = *iterator; 72 73 if (line[0] == ';') { 74 // Semicolon is a comment so ignore the line. 75 continue; 76 } 77 else { 78 if (line[0] == '[') { 79 found = true; 80 } 81 82 break; 83 } 84 } 85 86 if (found == true) { 87 TString sectionName; 88 89 for (std::list<TString>::const_iterator iterator = contents.begin(); iterator != contents.end(); iterator++) { 90 TString line = *iterator; 91 92 if (line[0] == ';') { 93 // Semicolon is a comment so ignore the line. 94 continue; 95 } 96 else if (line[0] == '[' && line[line.length() - 1] == ']') { 97 sectionName = line.substr(1, line.size() - 2); 98 } 99 else if (sectionName.empty() == false) { 100 TString name; 101 TString value; 102 103 if (Helpers::SplitOptionIntoNameValue(line, name, value) == true) { 104 Append(sectionName, name, value); 105 } 106 } 107 } 108 109 result = true; 110 } 111 } 112 113 return result; 114 } 115 116 bool IniFile::SaveToFile(const TString FileName, bool ownerOnly) { 117 bool result = false; 118 119 //if (GetReadOnly() == false && IsModified()) { 120 std::list<TString> contents; 121 std::vector<TString> keys = FMap.GetKeys(); 122 123 for (unsigned int index = 0; index < keys.size(); index++) { 124 TString name = keys[index]; 125 126 //try { 127 IniSectionData *section;// = FMap[index]; 128 129 if (FMap.GetValue(name, section) == true) { 130 contents.push_back(_T("[") + name + _T("]")); 131 std::list<TString> lines = section->GetLines(); 132 contents.insert(contents.end(), lines.begin(), lines.end()); 133 contents.push_back(_T("")); 134 } 135 // } 136 // catch (std::out_of_range) { 137 // } 138 } 139 140 Platform& platform = Platform::GetInstance(); 141 platform.SaveToFile(FileName, contents, ownerOnly); 142 143 //SetModified(false); 144 result = true; 145 //} 146 147 return result; 148 } 149 150 void IniFile::Append(const TString SectionName, const TString Key, TString Value) { 151 if (FMap.ContainsKey(SectionName) == true) { 152 IniSectionData* section; 153 154 if (FMap.GetValue(SectionName, section) == true && section != NULL) { 155 section->SetValue(Key, Value); 156 } 157 } 158 else { 159 IniSectionData *section = new IniSectionData(); 160 section->SetValue(Key, Value); 161 FMap.Append(SectionName, section); 162 } 163 } 164 165 void IniFile::AppendSection(const TString SectionName, OrderedMap<TString, TString> Values) { 166 if (FMap.ContainsKey(SectionName) == true) { 167 IniSectionData* section; 168 169 if (FMap.GetValue(SectionName, section) == true && section != NULL) { 170 section->Append(Values); 171 } 172 } 173 else { 174 IniSectionData *section = new IniSectionData(Values); 175 FMap.Append(SectionName, section); 176 } 177 } 178 179 bool IniFile::GetValue(const TString SectionName, const TString Key, TString& Value) { 180 bool result = false; 181 IniSectionData* section; 182 183 if (FMap.GetValue(SectionName, section) == true && section != NULL) { 184 result = section->GetValue(Key, Value); 185 } 186 187 return result; 188 } 189 190 bool IniFile::SetValue(const TString SectionName, const TString Key, TString Value) { 191 bool result = false; 192 IniSectionData* section; 193 194 if (FMap.GetValue(SectionName, section) && section != NULL) { 195 result = section->SetValue(Key, Value); 196 } 197 else { 198 Append(SectionName, Key, Value); 199 } 200 201 202 return result; 203 } 204 205 bool IniFile::GetSection(const TString SectionName, OrderedMap<TString, TString> &Data) { 206 bool result = false; 207 208 if (FMap.ContainsKey(SectionName) == true) { 209 IniSectionData* section; 210 211 if (FMap.GetValue(SectionName, section) == true && section != NULL) { 212 OrderedMap<TString, TString> data = section->GetData(); 213 Data.Append(data); 214 } 215 } 216 217 return result; 218 } 219 220 bool IniFile::ContainsSection(const TString SectionName) { 221 return FMap.ContainsKey(SectionName); 222 } 223 224 //-------------------------------------------------------------------------------------------------- 225 226 IniSectionData::IniSectionData() { 227 } 228 229 IniSectionData::IniSectionData(OrderedMap<TString, TString> Values) { 230 FMap = Values; 231 } 232 233 std::vector<TString> IniSectionData::GetKeys() { 234 return FMap.GetKeys(); 235 } 236 237 std::list<TString> IniSectionData::GetLines() { 238 std::list<TString> result; 239 std::vector<TString> keys = FMap.GetKeys(); 240 241 for (unsigned int index = 0; index < keys.size(); index++) { 242 TString name = keys[index]; 243 TString value; 244 245 if (FMap.GetValue(name, value) == true) { 246 TString line = name + _T('=') + value; 247 result.push_back(line); 248 } 249 } 250 251 return result; 252 } 253 254 OrderedMap<TString, TString> IniSectionData::GetData() { 255 OrderedMap<TString, TString> result = FMap; 256 return result; 257 } 258 259 bool IniSectionData::GetValue(const TString Key, TString& Value) { 260 return FMap.GetValue(Key, Value); 261 } 262 263 bool IniSectionData::SetValue(const TString Key, TString Value) { 264 return FMap.SetValue(Key, Value); 265 } 266 267 void IniSectionData::Append(OrderedMap<TString, TString> Values) { 268 FMap.Append(Values); 269 } 270 271 size_t IniSectionData::GetCount() { 272 return FMap.Count(); 273 }