5fa641e4b0eee6fd49d90633ec0ec38dc8f07ec5
[platform/upstream/syncevolution.git] / src / core / SafeConfigNode.cpp
1 /*
2  * Copyright (C) 2008 Patrick Ohly
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16  * 02111-1307  USA
17  */
18
19 #include "SafeConfigNode.h"
20 #include "EvolutionSyncClient.h"
21
22 #include <boost/foreach.hpp>
23
24 SafeConfigNode::SafeConfigNode(const boost::shared_ptr<ConfigNode> &node) :
25     m_node(node),
26     m_readOnlyNode(node)
27 {
28 }
29
30 SafeConfigNode::SafeConfigNode(const boost::shared_ptr<const ConfigNode> &node) :
31     m_readOnlyNode(node)
32 {
33 }
34
35 string SafeConfigNode::readProperty(const string &property) const
36 {
37     return unescape(m_readOnlyNode->readProperty(escape(property)));
38 }
39
40 void SafeConfigNode::setProperty(const string &property,
41                                  const string &value,
42                                  const string &comment,
43                                  const string *defValue)
44 {
45     m_node->setProperty(escape(property),
46                         escape(value),
47                         comment,
48                         defValue);
49 }
50
51 void SafeConfigNode::readProperties(map<string, string> &props) const
52 {
53     map<string, string> original;
54     m_readOnlyNode->readProperties(original);
55
56     BOOST_FOREACH(const StringPair &prop, original) {
57         string key = unescape(prop.first);
58         string value = unescape(prop.second);
59
60         props[key] = value;
61     }
62 }
63
64 void SafeConfigNode::removeProperty(const string &property)
65 {
66     m_node->removeProperty(escape(property));
67 }
68
69 void SafeConfigNode::flush()
70 {
71     if (!m_node.get()) {
72         EvolutionSyncClient::throwError(getName() + ": read-only, flushing not allowed");
73     }
74     m_node->flush();
75 }
76
77 string SafeConfigNode::escape(const string &str)
78 {
79     string res;
80     char buffer[4];
81     res.reserve(str.size() * 3);
82
83     BOOST_FOREACH(char c, str) {
84         if(isalnum(c) ||
85            c == '-' ||
86            c == '_') {
87             res += c;
88         } else {
89             sprintf(buffer, "!%02x",
90                     (unsigned int)(unsigned char)c);
91             res += buffer;
92         }
93     }
94
95     return res;
96 }
97
98 string SafeConfigNode::unescape(const string &str)
99 {
100     string res;
101     size_t curr;
102
103     res.reserve(str.size());
104
105     curr = 0;
106     while (curr < str.size()) {
107         if (str[curr] == '!') {
108             string hex = str.substr(curr + 1, 2);
109             res += (char)strtol(hex.c_str(), NULL, 16);
110             curr += 3;
111         } else {
112             res += str[curr];
113             curr++;
114         }
115     }
116
117     return res;
118 }