Writes a "datafile" node (and all of its child nodes and properties) recursively to a file.
| 153 | // Writes a "datafile" node (and all of its child nodes and properties) recursively |
| 154 | // to a file. |
| 155 | inline static bool Write(const datafile& n, const std::string& sFileName, const std::string& sIndent = "\t", const char sListSep = ',') |
| 156 | { |
| 157 | // Cache indentation level |
| 158 | size_t nIndentCount = 0; |
| 159 | // Cache sperator string for convenience |
| 160 | std::string sSeperator = std::string(1, sListSep) + " "; |
| 161 | |
| 162 | // Fully specified lambda, because this lambda is recursive! |
| 163 | std::function<void(const datafile&, std::ofstream&)> write = [&](const datafile& n, std::ofstream& file) |
| 164 | { |
| 165 | // Lambda creates string given indentation preferences |
| 166 | auto indent = [&](const std::string& sString, const size_t nCount) |
| 167 | { |
| 168 | std::string sOut; |
| 169 | for (size_t n = 0; n < nCount; n++) sOut += sString; |
| 170 | return sOut; |
| 171 | }; |
| 172 | |
| 173 | // Iterate through each property of this node |
| 174 | for (auto const& property : n.m_vecObjects) |
| 175 | { |
| 176 | // Does property contain any sub objects? |
| 177 | if (property.second.m_vecObjects.empty()) |
| 178 | { |
| 179 | // No, so it's an assigned field and should just be written. If the property |
| 180 | // is flagged as comment, it has no assignment potential. First write the |
| 181 | // property name |
| 182 | file << indent(sIndent, nIndentCount) << property.first << (property.second.m_bIsComment ? "" : " = "); |
| 183 | |
| 184 | // Second, write the property value (or values, seperated by provided |
| 185 | // separation charater |
| 186 | size_t nItems = property.second.GetValueCount(); |
| 187 | for (size_t i = 0; i < property.second.GetValueCount(); i++) |
| 188 | { |
| 189 | // If the Value being written, in string form, contains the separation |
| 190 | // character, then the value must be written inside quotation marks. Note, |
| 191 | // that if the Value is the last of a list of Values for a property, it is |
| 192 | // not suffixed with the separator |
| 193 | size_t x = property.second.GetString(i).find_first_of(sListSep); |
| 194 | if (x != std::string::npos) |
| 195 | { |
| 196 | // Value contains separator, so wrap in quotes |
| 197 | file << "\"" << property.second.GetString(i) << "\"" << ((nItems > 1) ? sSeperator : ""); |
| 198 | } |
| 199 | else |
| 200 | { |
| 201 | // Value does not contain separator, so just write out |
| 202 | file << property.second.GetString(i) << ((nItems > 1) ? sSeperator : ""); |
| 203 | } |
| 204 | nItems--; |
| 205 | } |
| 206 | |
| 207 | // Property written, move to next line |
| 208 | file << "\n"; |
| 209 | } |
| 210 | else |
| 211 | { |
| 212 | // Yes, property has properties of its own, so it's a node |
nothing calls this directly
no test coverage detected