OmniEvents
PersistNode.cc
Go to the documentation of this file.
1// Package : omniEvents
2// PersistNode.cc Created : 2004/04/29
3// Author : Alex Tingle
4//
5// Copyright (C) 2004 Alex Tingle.
6//
7// This file is part of the omniEvents application.
8//
9// omniEvents is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// omniEvents is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22//
23
24#include "PersistNode.h"
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <climits>
29
30namespace OmniEvents {
31
32
34{
35 while( readnode(is) ){}
36}
37
39{
40 for(map<string,PersistNode*>::iterator i=_child.begin(); i!=_child.end(); ++i)
41 delete i->second;
42}
43
44void PersistNode::output(ostream& os,string name) const
45{
46 if(!name.empty()) // Don't output root node.
47 {
48 os<<name<<'\n';
49 for(map<string,string>::const_iterator i=_attr.begin();
50 i!=_attr.end();
51 ++i)
52 {
53 os<<" "<<i->first<<"="<<i->second<<'\n';
54 }
55 os<<" ;;\n";
56 name+="/";
57 }
58 for(map<string,PersistNode*>::const_iterator i=_child.begin();
59 i!=_child.end();
60 ++i)
61 {
62 i->second->output(os,name+i->first);
63 }
64}
65
66
67inline bool PersistNode::readnode(istream& is)
68{
69 PersistNode* node =NULL;
70 string tok;
71 while(true)
72 {
73 if(!readtoken(is,tok) || tok==";;")
74 return bool(node);
75 else if(node)
76 node->addattr(tok);
77 else if(tok[0]=='-')
78 delnode(tok.substr(1));
79 else
80 node=addnode(tok);
81 }
82}
83
84inline bool PersistNode::readtoken(istream& is, string& tok)
85{
86 while(is)
87 {
88 is>>tok;
89 if(tok.empty())
90 break;
91 if(tok[0]!='#')
92 return true;
93 is.ignore(INT_MAX,'\n');
94 }
95 return false;
96}
97
99{
100 string::size_type pos =name.find('/');
101 // get reference to Next node in the path.
102 PersistNode*& newchild =_child[name.substr(0,pos)];
103
104 if(pos==string::npos) // leaf: add new leaf.
105 {
106 if(newchild)
107 delete newchild; // overwrite old leaf (and its children)
108 newchild=new PersistNode();
109 return newchild;
110 }
111 else // branch: just add the branch if it's missing, and then recurse.
112 {
113 if(!newchild)
114 newchild=new PersistNode();
115 return newchild->addnode(name.substr(pos+1));
116 }
117}
118
119void PersistNode::delnode(const string& name)
120{
121 string::size_type pos =name.find('/');
122 // get reference to Next node in the path.
123 map<string,PersistNode*>::iterator childpos =_child.find(name.substr(0,pos));
124 if(childpos!=_child.end())
125 {
126 if(pos==string::npos) // leaf: delete leaf.
127 {
128 delete childpos->second;
129 _child.erase(childpos);
130 }
131 else // branch: recurse
132 {
133 childpos->second->delnode(name.substr(pos+1));
134 }
135 }
136}
137
138void PersistNode::addattr(const string& keyvalue)
139{
140 string::size_type pos =keyvalue.find('=');
141 _attr[keyvalue.substr(0,pos)]=(pos==string::npos?"":keyvalue.substr(pos+1));
142}
143
144void PersistNode::addattr(const string& key, long value)
145{
146 char buf[64];
147 sprintf(buf,"%i",value);
148 _attr[key]=string(buf);
149}
150
151bool PersistNode::hasAttr(const string& key) const
152{
153 return( _attr.find(key)!=_attr.end() );
154}
155string PersistNode::attrString(const string& key, const string& fallback) const
156{
157 map<string,string>::const_iterator pos=_attr.find(key);
158 if(pos==_attr.end())
159 return fallback;
160 else
161 return pos->second;
162}
163long PersistNode::attrLong(const string& key, long fallback) const
164{
165 map<string,string>::const_iterator pos=_attr.find(key);
166 if(pos==_attr.end())
167 return fallback;
168 else
169 return atol(pos->second.c_str());
170}
171PersistNode* PersistNode::child(const string& key) const
172{
173 map<string,PersistNode*>::const_iterator pos=_child.find(key);
174 if(pos==_child.end())
175 return NULL;
176 else
177 return pos->second;
178}
179
180}; // end namespace OmniEvents
void output(ostream &os, string name) const
bool readtoken(istream &is, string &tok)
map< string, PersistNode * > _child
Definition PersistNode.h:71
bool hasAttr(const string &key) const
map< string, string > _attr
Definition PersistNode.h:72
~PersistNode()
Free node and all its children.
string attrString(const string &key, const string &fallback="") const
void delnode(const string &name)
PersistNode * addnode(const string &name)
bool readnode(istream &is)
long attrLong(const string &key, long fallback=0) const
PersistNode()
Create an empty node.
Definition PersistNode.h:51
PersistNode * child(const string &key) const
void addattr(const string &keyvalue)