You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
7.7 KiB
283 lines
7.7 KiB
15 years ago
|
#include <iostream>
|
||
|
#include <fstream>
|
||
|
#include "stf.hpp"
|
||
|
using namespace std;
|
||
|
using stfu::node;
|
||
|
|
||
|
/*! \author Nick Overdijk
|
||
|
* \version 1.2
|
||
|
* \date 2009-04-27
|
||
|
*
|
||
|
* STFU Example App
|
||
|
*/
|
||
|
|
||
|
void prettyprint(const string &title) {
|
||
|
cout
|
||
|
<< "\t\t-----" << title << "-----\t\t\n"
|
||
|
<< endl;
|
||
|
}
|
||
|
|
||
|
void read_examples(node &n) {
|
||
|
prettyprint("Reading Examples");
|
||
|
cout
|
||
|
<< "Reading a STF file in a node is trivial with the stream insertion operator, it returns whether it had success: true/false\n"
|
||
|
<< endl;
|
||
|
|
||
|
if ("test.stf" >> n) {
|
||
|
prettyprint("Outputting a node/tree");
|
||
|
cout << n;
|
||
|
|
||
|
cout
|
||
|
<< "\n\nnode::getChild() returns a node&, so we can easily output nested nodes:\n"
|
||
|
<< endl;
|
||
|
cout << n.getChild("child");
|
||
|
|
||
|
cout
|
||
|
<< "\n\nnode::getValue() returns a string&, so we can easily output values too:\n"
|
||
|
<< endl;
|
||
|
cout << n.getValue("imthefirst");
|
||
|
|
||
|
cout
|
||
|
<< "\n\nThe constness of getChild and getValue depend on the object."
|
||
|
<< endl;
|
||
|
} else {
|
||
|
cerr << "Couldn't read file!" << endl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void change_examples(node &n) {
|
||
|
cout
|
||
|
<< "\t\t-----Change examples------\t\t\n"
|
||
|
<< endl;
|
||
|
|
||
|
if ("test.stf" >> n) {
|
||
|
prettyprint("Edit a value");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
n.value("imthefirst") = "O YEAH!";
|
||
|
|
||
|
cout << "After: " << endl;
|
||
|
cout << n;
|
||
|
|
||
|
prettyprint("Edit a node");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
n.child("child") = n;
|
||
|
|
||
|
cout << "After: " << endl;
|
||
|
cout << n;
|
||
|
|
||
|
prettyprint("Edit the name of a value");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
n.renameValue("imthefirst", "roflolmao");
|
||
|
|
||
|
cout << "After: " << endl;
|
||
|
cout << n;
|
||
|
|
||
|
prettyprint("Edit the name of a child");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
n.renameChild("child", "NEW NAMEZ");
|
||
|
|
||
|
cout << "After: " << endl;
|
||
|
cout << n;
|
||
|
} else {
|
||
|
cerr << "Couldn't read file!" << endl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void create_examples(node &n) {
|
||
|
prettyprint("Creation examples");
|
||
|
node screenoptions;
|
||
|
node soundoptions;
|
||
|
|
||
|
if (!("screenoptions.stf" >> screenoptions && "soundoptions.stf" >> soundoptions)) {
|
||
|
cerr << "Couldn't read files!" << endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cout << "You can merge these two tree quite easily into one tree (aka \"Adding children\"):" << endl;
|
||
|
|
||
|
cout << "Before (screenoptions):" << endl;
|
||
|
cout << screenoptions << endl;
|
||
|
cout << "Before (soundoptions):" << endl;
|
||
|
cout << soundoptions << endl;
|
||
|
|
||
|
//child() creates the child when it doesn't exist
|
||
|
n.child("Screen options") = screenoptions;
|
||
|
//but you can do this too
|
||
|
n.addChild("Sound options", soundoptions);
|
||
|
|
||
|
cout << "After (both are now children of options):" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
prettyprint("Adding a value");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
//this way, NOT sure child() won't create a child (if it doesn't exist, it'll create it)
|
||
|
//also not sure value() won't alter a value (if the value[index] exists, it'll change that)
|
||
|
n.child("Screen options").value("Contrast") = "70.1";
|
||
|
//this way, 100% sure that getChild() won't create a child, and addValue() will always add a value
|
||
|
//get{Child|Value} throw an out_of_range when they can't find the {Child|Value}.
|
||
|
n.getChild("Screen options").addValue("Brightness") = "1.5";
|
||
|
|
||
|
cout << "After:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
prettyprint("Writing to a file (aka \"Saving to a file\")");
|
||
|
const char *filename = "ExampleProgramOutput.stf";
|
||
|
if (!(filename << n)) {
|
||
|
cerr << "Couldn't write to ";
|
||
|
} else {
|
||
|
cout << "Node succesfully saved to ";
|
||
|
}
|
||
|
cout << filename << endl << endl;
|
||
|
}
|
||
|
|
||
|
void remove_examples(node &n) {
|
||
|
prettyprint("Removal examples");
|
||
|
if (!("test.stf" >> n)) {
|
||
|
cerr << "Couldn't open file!" << endl;
|
||
|
}
|
||
|
|
||
|
prettyprint("Deleting a value");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
//remove{Child|Value} throws an out_of_range when the child/value isn't found
|
||
|
n.removeValue("imthefirst");
|
||
|
|
||
|
cout << "After:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
|
||
|
prettyprint("Deleting a child/node");
|
||
|
cout << "Before:" << endl;
|
||
|
cout << n;
|
||
|
|
||
|
n.removeChild("child");
|
||
|
|
||
|
cout << "After:" << endl;
|
||
|
cout << n;
|
||
|
}
|
||
|
|
||
|
void array_examples(node &n) {
|
||
|
prettyprint("Array Examples");
|
||
|
if (!("arrays.stf" >> n)) {
|
||
|
cerr << "Couldn't open arrays.stf!" << endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
prettyprint("Iterating over an array: try/catch method");
|
||
|
node &array = n.getChild("array");
|
||
|
try {
|
||
|
size_t i = 0;
|
||
|
while (true) {
|
||
|
//use getValue(), it throws an out_of_range when there are no more elements
|
||
|
cout << array.getValue(i) << endl;
|
||
|
i++;
|
||
|
}
|
||
|
} catch (out_of_range &e) {/*we're done! ;-)*/}
|
||
|
|
||
|
prettyprint("Iterating over an array: size() method");
|
||
|
size_t max = array.values.size();
|
||
|
for(size_t i = 0; i < max; i++){
|
||
|
cout << array.getValue(i) << endl;
|
||
|
}
|
||
|
|
||
|
prettyprint("Iterating over a 2D-array: size() method");
|
||
|
node &multiarray = n.getChild("2D array");
|
||
|
|
||
|
//rows are children
|
||
|
size_t rows = multiarray.children.size();
|
||
|
//each row can have a different amount of cols
|
||
|
size_t cols[rows];
|
||
|
|
||
|
for(size_t i = 0; i < rows; i++){
|
||
|
//same as with size() method above
|
||
|
cols[i] = multiarray.getChild(i).values.size();
|
||
|
//output to see it for yourself
|
||
|
cout << i << ',' << cols[i] << endl;
|
||
|
}
|
||
|
|
||
|
//so, we're done. Code could've been written in 100 ways, but this does it step by step to be clear.
|
||
|
for(size_t row = 0; row < rows; row++){
|
||
|
for(size_t col = 0; col < cols[row]; col++){
|
||
|
cout << multiarray.getChild(row).getValue(col) << ", ";
|
||
|
}
|
||
|
cout << "\b\b " << endl;
|
||
|
}
|
||
|
|
||
|
/*Arrays are simply unnamed nodes/values. Nothing more, nothing less.
|
||
|
You can change them like nodes/values, add them the same way, etc.
|
||
|
Most of the functions are overloaded so that you don't have to specify a name
|
||
|
These functions call their overloaded brethren with name = "" */
|
||
|
|
||
|
prettyprint("Creating an array");
|
||
|
|
||
|
cout << "Before:\n\n";
|
||
|
cout << n << endl;
|
||
|
|
||
|
node &newarray = n.addChild("my new array");
|
||
|
stringstream buf;
|
||
|
for(size_t i = 0; i < 10; i++){
|
||
|
buf << i;
|
||
|
newarray.addValue() = buf.str();
|
||
|
}
|
||
|
|
||
|
cout << "After:\n\n";
|
||
|
cout << n << endl;
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
prettyprint("Welcome to the stf example app");
|
||
|
|
||
|
ifstream license("LICENSE.txt");
|
||
|
if (license.good()) {
|
||
|
string line;
|
||
|
while (getline(license, line)) {
|
||
|
cout << line << endl;
|
||
|
}
|
||
|
license.close();
|
||
|
} else {
|
||
|
cerr << "Couldn't open/read LICENSE.txt" << endl;
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
cout << endl;
|
||
|
|
||
|
cout
|
||
|
<< "This application shows how easy it is to use STFU (Simple Tree File Utility).\n"
|
||
|
<< "STF is a \"new\" way to store leveled data, just as XML can do, for example.\n"
|
||
|
<< "The format looks like a C(++) struct, which we think is easier to read than XML.\n"
|
||
|
<< "Each {...} is a node, a node has other nodes and values. The file itself is the\n"
|
||
|
<< "(unnamed) root node.\n"
|
||
|
<< endl;
|
||
|
|
||
|
//create an empty node
|
||
|
node n;
|
||
|
read_examples(n);
|
||
|
n.clear();
|
||
|
|
||
|
change_examples(n);
|
||
|
n.clear();
|
||
|
|
||
|
create_examples(n);
|
||
|
n.clear();
|
||
|
|
||
|
remove_examples(n);
|
||
|
n.clear();
|
||
|
|
||
|
array_examples(n);
|
||
|
n.clear();
|
||
|
|
||
|
return 0;
|
||
|
}
|