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