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