1 /*
2 * Dictionary.cpp
3 *
4 * Copyright (c) 2009 Jonathan Beck All Rights Reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <cstdlib>
22 #include <plist/Dictionary.h>
23
24 namespace PList
25 {
26
Dictionary(Node * parent)27 Dictionary::Dictionary(Node* parent) : Structure(PLIST_DICT, parent)
28 {
29 }
30
dictionary_fill(Dictionary * _this,std::map<std::string,Node * > & map,plist_t node)31 static void dictionary_fill(Dictionary *_this, std::map<std::string,Node*> &map, plist_t node)
32 {
33 plist_dict_iter it = NULL;
34 plist_dict_new_iter(node, &it);
35 plist_t subnode = NULL;
36 do {
37 char *key = NULL;
38 subnode = NULL;
39 plist_dict_next_item(node, it, &key, &subnode);
40 if (key && subnode)
41 map[std::string(key)] = Node::FromPlist(subnode, _this);
42 free(key);
43 } while (subnode);
44 free(it);
45 }
46
Dictionary(plist_t node,Node * parent)47 Dictionary::Dictionary(plist_t node, Node* parent) : Structure(parent)
48 {
49 _node = node;
50 dictionary_fill(this, _map, _node);
51 }
52
Dictionary(const PList::Dictionary & d)53 Dictionary::Dictionary(const PList::Dictionary& d)
54 {
55 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
56 {
57 plist_free(it->second->GetPlist());
58 delete it->second;
59 }
60 _map.clear();
61 _node = plist_copy(d.GetPlist());
62 dictionary_fill(this, _map, _node);
63 }
64
operator =(PList::Dictionary & d)65 Dictionary& Dictionary::operator=(PList::Dictionary& d)
66 {
67 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
68 {
69 plist_free(it->second->GetPlist());
70 delete it->second;
71 }
72 _map.clear();
73 _node = plist_copy(d.GetPlist());
74 dictionary_fill(this, _map, _node);
75 return *this;
76 }
77
~Dictionary()78 Dictionary::~Dictionary()
79 {
80 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
81 {
82 delete it->second;
83 }
84 _map.clear();
85 }
86
Clone() const87 Node* Dictionary::Clone() const
88 {
89 return new Dictionary(*this);
90 }
91
operator [](const std::string & key)92 Node* Dictionary::operator[](const std::string& key)
93 {
94 return _map[key];
95 }
96
Begin()97 Dictionary::iterator Dictionary::Begin()
98 {
99 return _map.begin();
100 }
101
End()102 Dictionary::iterator Dictionary::End()
103 {
104 return _map.end();
105 }
106
Begin() const107 Dictionary::const_iterator Dictionary::Begin() const
108 {
109 return _map.begin();
110 }
111
End() const112 Dictionary::const_iterator Dictionary::End() const
113 {
114 return _map.end();
115 }
116
Find(const std::string & key)117 Dictionary::iterator Dictionary::Find(const std::string& key)
118 {
119 return _map.find(key);
120 }
121
Find(const std::string & key) const122 Dictionary::const_iterator Dictionary::Find(const std::string& key) const
123 {
124 return _map.find(key);
125 }
126
Set(const std::string & key,const Node * node)127 Dictionary::iterator Dictionary::Set(const std::string& key, const Node* node)
128 {
129 if (node)
130 {
131 Node* clone = node->Clone();
132 UpdateNodeParent(clone);
133 plist_dict_set_item(_node, key.c_str(), clone->GetPlist());
134 delete _map[key];
135 _map[key] = clone;
136 return _map.find(key);
137 }
138 return iterator(this->_map.end());
139 }
140
Set(const std::string & key,const Node & node)141 Dictionary::iterator Dictionary::Set(const std::string& key, const Node& node)
142 {
143 return Set(key, &node);
144 }
145
Insert(const std::string & key,Node * node)146 Dictionary::iterator Dictionary::Insert(const std::string& key, Node* node)
147 {
148 return this->Set(key, node);
149 }
150
Remove(Node * node)151 void Dictionary::Remove(Node* node)
152 {
153 if (node)
154 {
155 char* key = NULL;
156 plist_dict_get_item_key(node->GetPlist(), &key);
157 plist_dict_remove_item(_node, key);
158 std::string skey = key;
159 free(key);
160 _map.erase(skey);
161 delete node;
162 }
163 }
164
Remove(const std::string & key)165 void Dictionary::Remove(const std::string& key)
166 {
167 plist_dict_remove_item(_node, key.c_str());
168 delete _map[key];
169 _map.erase(key);
170 }
171
GetNodeKey(Node * node)172 std::string Dictionary::GetNodeKey(Node* node)
173 {
174 for (iterator it = _map.begin(); it != _map.end(); ++it)
175 {
176 if (it->second == node)
177 return it->first;
178 }
179 return "";
180 }
181
182 } // namespace PList
183