summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Array.cpp52
-rw-r--r--src/Boolean.cpp6
-rw-r--r--src/Data.cpp6
-rw-r--r--src/Date.cpp6
-rw-r--r--src/Dictionary.cpp78
-rw-r--r--src/Integer.cpp6
-rw-r--r--src/Node.cpp69
-rw-r--r--src/Real.cpp6
-rw-r--r--src/String.cpp6
-rw-r--r--src/Structure.cpp10
-rw-r--r--src/Utils.cpp66
-rw-r--r--src/bplist.c1445
-rw-r--r--src/plist.c1212
-rw-r--r--src/plist.h30
-rw-r--r--src/xplist.c564
15 files changed, 1838 insertions, 1724 deletions
diff --git a/src/Array.cpp b/src/Array.cpp
index dbb1239..bdd26e1 100644
--- a/src/Array.cpp
+++ b/src/Array.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
@@ -37,7 +37,7 @@ Array::Array(plist_t node, Node* parent) : Structure(parent)
37 37
38 for (uint32_t i = 0; i < size; i++) 38 for (uint32_t i = 0; i < size; i++)
39 { 39 {
40 plist_t subnode = plist_array_get_item(_node, i); 40 plist_t subnode = plist_array_get_item(_node, i);
41 _array.push_back( Utils::FromPlist(subnode, this) ); 41 _array.push_back( Utils::FromPlist(subnode, this) );
42 } 42 }
43} 43}
@@ -50,7 +50,7 @@ Array::Array(PList::Array& a) : Structure()
50 50
51 for (uint32_t i = 0; i < size; i++) 51 for (uint32_t i = 0; i < size; i++)
52 { 52 {
53 plist_t subnode = plist_array_get_item(_node, i); 53 plist_t subnode = plist_array_get_item(_node, i);
54 _array.push_back( Utils::FromPlist(subnode, this) ); 54 _array.push_back( Utils::FromPlist(subnode, this) );
55 } 55 }
56} 56}
@@ -60,7 +60,7 @@ Array& Array::operator=(PList::Array& a)
60 plist_free(_node); 60 plist_free(_node);
61 for (unsigned int it = 0; it < _array.size(); it++) 61 for (unsigned int it = 0; it < _array.size(); it++)
62 { 62 {
63 delete _array.at(it); 63 delete _array.at(it);
64 } 64 }
65 _array.clear(); 65 _array.clear();
66 66
@@ -69,7 +69,7 @@ Array& Array::operator=(PList::Array& a)
69 69
70 for (uint32_t i = 0; i < size; i++) 70 for (uint32_t i = 0; i < size; i++)
71 { 71 {
72 plist_t subnode = plist_array_get_item(_node, i); 72 plist_t subnode = plist_array_get_item(_node, i);
73 _array.push_back( Utils::FromPlist(subnode, this) ); 73 _array.push_back( Utils::FromPlist(subnode, this) );
74 } 74 }
75 return *this; 75 return *this;
@@ -77,11 +77,11 @@ Array& Array::operator=(PList::Array& a)
77 77
78Array::~Array() 78Array::~Array()
79{ 79{
80 for (unsigned int it = 0; it < _array.size(); it++) 80 for (unsigned int it = 0; it < _array.size(); it++)
81 { 81 {
82 delete (_array.at(it)); 82 delete (_array.at(it));
83 } 83 }
84 _array.clear(); 84 _array.clear();
85} 85}
86 86
87Node* Array::Clone() 87Node* Array::Clone()
@@ -98,10 +98,10 @@ void Array::Append(Node* node)
98{ 98{
99 if (node) 99 if (node)
100 { 100 {
101 Node* clone = node->Clone(); 101 Node* clone = node->Clone();
102 clone->SetParent(this); 102 clone->SetParent(this);
103 plist_array_append_item(_node, clone->GetPlist()); 103 plist_array_append_item(_node, clone->GetPlist());
104 _array.push_back(clone); 104 _array.push_back(clone);
105 } 105 }
106} 106}
107 107
@@ -109,12 +109,12 @@ void Array::Insert(Node* node, unsigned int pos)
109{ 109{
110 if (node) 110 if (node)
111 { 111 {
112 Node* clone = node->Clone(); 112 Node* clone = node->Clone();
113 clone->SetParent(this); 113 clone->SetParent(this);
114 plist_array_insert_item(_node, clone->GetPlist(), pos); 114 plist_array_insert_item(_node, clone->GetPlist(), pos);
115 std::vector<Node*>::iterator it = _array.begin(); 115 std::vector<Node*>::iterator it = _array.begin();
116 it += pos; 116 it += pos;
117 _array.insert(it, clone); 117 _array.insert(it, clone);
118 } 118 }
119} 119}
120 120
@@ -122,12 +122,12 @@ void Array::Remove(Node* node)
122{ 122{
123 if (node) 123 if (node)
124 { 124 {
125 uint32_t pos = plist_array_get_item_index(node->GetPlist()); 125 uint32_t pos = plist_array_get_item_index(node->GetPlist());
126 plist_array_remove_item(_node, pos); 126 plist_array_remove_item(_node, pos);
127 std::vector<Node*>::iterator it = _array.begin(); 127 std::vector<Node*>::iterator it = _array.begin();
128 it += pos; 128 it += pos;
129 _array.erase(it); 129 _array.erase(it);
130 delete node; 130 delete node;
131 } 131 }
132} 132}
133 133
diff --git a/src/Boolean.cpp b/src/Boolean.cpp
index dfa96ca..e58472f 100644
--- a/src/Boolean.cpp
+++ b/src/Boolean.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/Data.cpp b/src/Data.cpp
index 02ce983..df5c1c7 100644
--- a/src/Data.cpp
+++ b/src/Data.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/Date.cpp b/src/Date.cpp
index cb817d9..2430184 100644
--- a/src/Date.cpp
+++ b/src/Date.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/Dictionary.cpp b/src/Dictionary.cpp
index 72307f1..fedce2e 100644
--- a/src/Dictionary.cpp
+++ b/src/Dictionary.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
@@ -41,11 +41,11 @@ Dictionary::Dictionary(plist_t node, Node* parent) : Structure(parent)
41 while (subnode) 41 while (subnode)
42 { 42 {
43 _map[std::string(key)] = Utils::FromPlist(subnode, this); 43 _map[std::string(key)] = Utils::FromPlist(subnode, this);
44 44
45 subnode = NULL; 45 subnode = NULL;
46 free(key); 46 free(key);
47 key = NULL; 47 key = NULL;
48 plist_dict_next_item(_node, it, &key, &subnode); 48 plist_dict_next_item(_node, it, &key, &subnode);
49 } 49 }
50 free(it); 50 free(it);
51} 51}
@@ -54,8 +54,8 @@ Dictionary::Dictionary(PList::Dictionary& d) : Structure()
54{ 54{
55 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) 55 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
56 { 56 {
57 plist_free(it->second->GetPlist()); 57 plist_free(it->second->GetPlist());
58 delete it->second; 58 delete it->second;
59 } 59 }
60 _map.clear(); 60 _map.clear();
61 61
@@ -69,11 +69,11 @@ Dictionary::Dictionary(PList::Dictionary& d) : Structure()
69 while (subnode) 69 while (subnode)
70 { 70 {
71 _map[std::string(key)] = Utils::FromPlist(subnode, this); 71 _map[std::string(key)] = Utils::FromPlist(subnode, this);
72 72
73 subnode = NULL; 73 subnode = NULL;
74 free(key); 74 free(key);
75 key = NULL; 75 key = NULL;
76 plist_dict_next_item(_node, it, NULL, &subnode); 76 plist_dict_next_item(_node, it, NULL, &subnode);
77 } 77 }
78 free(it); 78 free(it);
79} 79}
@@ -82,8 +82,8 @@ Dictionary& Dictionary::operator=(PList::Dictionary& d)
82{ 82{
83 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) 83 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
84 { 84 {
85 plist_free(it->second->GetPlist()); 85 plist_free(it->second->GetPlist());
86 delete it->second; 86 delete it->second;
87 } 87 }
88 _map.clear(); 88 _map.clear();
89 89
@@ -97,11 +97,11 @@ Dictionary& Dictionary::operator=(PList::Dictionary& d)
97 while (subnode) 97 while (subnode)
98 { 98 {
99 _map[std::string(key)] = Utils::FromPlist(subnode, this); 99 _map[std::string(key)] = Utils::FromPlist(subnode, this);
100 100
101 subnode = NULL; 101 subnode = NULL;
102 free(key); 102 free(key);
103 key = NULL; 103 key = NULL;
104 plist_dict_next_item(_node, it, NULL, &subnode); 104 plist_dict_next_item(_node, it, NULL, &subnode);
105 } 105 }
106 free(it); 106 free(it);
107 return *this; 107 return *this;
@@ -111,8 +111,8 @@ Dictionary::~Dictionary()
111{ 111{
112 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) 112 for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++)
113 { 113 {
114 plist_free(it->second->GetPlist()); 114 plist_free(it->second->GetPlist());
115 delete it->second; 115 delete it->second;
116 } 116 }
117 _map.clear(); 117 _map.clear();
118} 118}
@@ -146,12 +146,12 @@ Dictionary::iterator Dictionary::Insert(const std::string& key, Node* node)
146{ 146{
147 if (node) 147 if (node)
148 { 148 {
149 Node* clone = node->Clone(); 149 Node* clone = node->Clone();
150 clone->SetParent(this); 150 clone->SetParent(this);
151 plist_dict_insert_item(_node, key.c_str(), clone->GetPlist()); 151 plist_dict_insert_item(_node, key.c_str(), clone->GetPlist());
152 delete _map[key]; 152 delete _map[key];
153 _map[key] = clone; 153 _map[key] = clone;
154 return _map.find(key); 154 return _map.find(key);
155 } 155 }
156 return iterator(NULL); 156 return iterator(NULL);
157} 157}
@@ -160,21 +160,21 @@ void Dictionary::Remove(Node* node)
160{ 160{
161 if (node) 161 if (node)
162 { 162 {
163 char* key = NULL; 163 char* key = NULL;
164 plist_dict_get_item_key(node->GetPlist(), &key); 164 plist_dict_get_item_key(node->GetPlist(), &key);
165 plist_dict_remove_item(_node, key); 165 plist_dict_remove_item(_node, key);
166 std::string skey = key; 166 std::string skey = key;
167 free(key); 167 free(key);
168 _map.erase(skey); 168 _map.erase(skey);
169 delete node; 169 delete node;
170 } 170 }
171} 171}
172 172
173void Dictionary::Remove(const std::string& key) 173void Dictionary::Remove(const std::string& key)
174{ 174{
175 plist_dict_remove_item(_node, key.c_str()); 175 plist_dict_remove_item(_node, key.c_str());
176 delete _map[key]; 176 delete _map[key];
177 _map.erase(key); 177 _map.erase(key);
178} 178}
179 179
180}; 180};
diff --git a/src/Integer.cpp b/src/Integer.cpp
index 4c8a825..fed03f6 100644
--- a/src/Integer.cpp
+++ b/src/Integer.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/Node.cpp b/src/Node.cpp
index c6a5b51..8ed3c6a 100644
--- a/src/Node.cpp
+++ b/src/Node.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
@@ -36,36 +36,37 @@ Node::Node(plist_t node, Node* parent) : _node(node), _parent(parent)
36Node::Node(plist_type type, Node* parent) : _parent(parent) 36Node::Node(plist_type type, Node* parent) : _parent(parent)
37{ 37{
38 _node = NULL; 38 _node = NULL;
39 39
40 switch(type) { 40 switch (type)
41 case PLIST_BOOLEAN: 41 {
42 _node = plist_new_bool(0); 42 case PLIST_BOOLEAN:
43 break; 43 _node = plist_new_bool(0);
44 case PLIST_UINT: 44 break;
45 _node = plist_new_uint(0); 45 case PLIST_UINT:
46 break; 46 _node = plist_new_uint(0);
47 case PLIST_REAL: 47 break;
48 _node = plist_new_real(0.); 48 case PLIST_REAL:
49 break; 49 _node = plist_new_real(0.);
50 case PLIST_STRING: 50 break;
51 _node = plist_new_string(""); 51 case PLIST_STRING:
52 break; 52 _node = plist_new_string("");
53 case PLIST_DATA: 53 break;
54 _node = plist_new_data(NULL,0); 54 case PLIST_DATA:
55 break; 55 _node = plist_new_data(NULL,0);
56 case PLIST_DATE: 56 break;
57 _node = plist_new_date(0,0); 57 case PLIST_DATE:
58 break; 58 _node = plist_new_date(0,0);
59 case PLIST_ARRAY: 59 break;
60 _node = plist_new_array(); 60 case PLIST_ARRAY:
61 break; 61 _node = plist_new_array();
62 case PLIST_DICT: 62 break;
63 _node = plist_new_dict(); 63 case PLIST_DICT:
64 break; 64 _node = plist_new_dict();
65 case PLIST_KEY: 65 break;
66 case PLIST_NONE: 66 case PLIST_KEY:
67 default: 67 case PLIST_NONE:
68 break; 68 default:
69 break;
69 } 70 }
70} 71}
71 72
@@ -80,7 +81,7 @@ plist_type Node::GetType()
80{ 81{
81 if (_node) 82 if (_node)
82 { 83 {
83 return plist_get_node_type(_node); 84 return plist_get_node_type(_node);
84 } 85 }
85 return PLIST_NONE; 86 return PLIST_NONE;
86} 87}
diff --git a/src/Real.cpp b/src/Real.cpp
index 512c44e..768d07c 100644
--- a/src/Real.cpp
+++ b/src/Real.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/String.cpp b/src/String.cpp
index 3ae158e..bf65605 100644
--- a/src/String.cpp
+++ b/src/String.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
diff --git a/src/Structure.cpp b/src/Structure.cpp
index 5c7dc9a..872d396 100644
--- a/src/Structure.cpp
+++ b/src/Structure.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
@@ -41,11 +41,11 @@ uint32_t Structure::GetSize()
41 plist_type type = plist_get_node_type(_node); 41 plist_type type = plist_get_node_type(_node);
42 if (type == PLIST_ARRAY) 42 if (type == PLIST_ARRAY)
43 { 43 {
44 size = plist_array_get_size(_node); 44 size = plist_array_get_size(_node);
45 } 45 }
46 else if (type == PLIST_DICT) 46 else if (type == PLIST_DICT)
47 { 47 {
48 size = plist_dict_get_size(_node); 48 size = plist_dict_get_size(_node);
49 } 49 }
50 return size; 50 return size;
51} 51}
diff --git a/src/Utils.cpp b/src/Utils.cpp
index df003e7..cb6da5e 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -7,15 +7,15 @@
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version. 9 * version 2.1 of the License, or (at your option) any later version.
10 * 10 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details. 14 * Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20 20
21#include <stdlib.h> 21#include <stdlib.h>
@@ -38,36 +38,36 @@ Node* Utils::FromPlist(plist_t node, Node* parent)
38 if (node) 38 if (node)
39 { 39 {
40 plist_type type = plist_get_node_type(node); 40 plist_type type = plist_get_node_type(node);
41 switch(type) 41 switch (type)
42 { 42 {
43 case PLIST_DICT: 43 case PLIST_DICT:
44 ret = new Dictionary(node, parent); 44 ret = new Dictionary(node, parent);
45 break; 45 break;
46 case PLIST_ARRAY: 46 case PLIST_ARRAY:
47 ret = new Array(node, parent); 47 ret = new Array(node, parent);
48 break; 48 break;
49 case PLIST_BOOLEAN: 49 case PLIST_BOOLEAN:
50 ret = new Boolean(node, parent); 50 ret = new Boolean(node, parent);
51 break; 51 break;
52 case PLIST_UINT: 52 case PLIST_UINT:
53 ret = new Integer(node, parent); 53 ret = new Integer(node, parent);
54 break; 54 break;
55 case PLIST_REAL: 55 case PLIST_REAL:
56 ret = new Real(node, parent); 56 ret = new Real(node, parent);
57 break; 57 break;
58 case PLIST_STRING: 58 case PLIST_STRING:
59 ret = new String(node, parent); 59 ret = new String(node, parent);
60 break; 60 break;
61 case PLIST_DATE: 61 case PLIST_DATE:
62 ret = new Date(node, parent); 62 ret = new Date(node, parent);
63 break; 63 break;
64 case PLIST_DATA: 64 case PLIST_DATA:
65 ret = new Data(node, parent); 65 ret = new Data(node, parent);
66 break; 66 break;
67 default: 67 default:
68 plist_free(node); 68 plist_free(node);
69 break; 69 break;
70 } 70 }
71 } 71 }
72 return ret; 72 return ret;
73} 73}
diff --git a/src/bplist.c b/src/bplist.c
index 6e3007a..d37ed7a 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -8,15 +8,15 @@
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 21
22 22
@@ -44,46 +44,48 @@
44#define BPLIST_TRL_ROOTOBJ_IDX 10 44#define BPLIST_TRL_ROOTOBJ_IDX 10
45#define BPLIST_TRL_OFFTAB_IDX 18 45#define BPLIST_TRL_OFFTAB_IDX 18
46 46
47enum { 47enum
48 BPLIST_NULL = 0x00, 48{
49 BPLIST_FALSE = 0x08, 49 BPLIST_NULL = 0x00,
50 BPLIST_TRUE = 0x09, 50 BPLIST_FALSE = 0x08,
51 BPLIST_FILL = 0x0F, /* will be used for length grabbing */ 51 BPLIST_TRUE = 0x09,
52 BPLIST_UINT = 0x10, 52 BPLIST_FILL = 0x0F, /* will be used for length grabbing */
53 BPLIST_REAL = 0x20, 53 BPLIST_UINT = 0x10,
54 BPLIST_DATE = 0x30, 54 BPLIST_REAL = 0x20,
55 BPLIST_DATA = 0x40, 55 BPLIST_DATE = 0x30,
56 BPLIST_STRING = 0x50, 56 BPLIST_DATA = 0x40,
57 BPLIST_UNICODE = 0x60, 57 BPLIST_STRING = 0x50,
58 BPLIST_UID = 0x70, 58 BPLIST_UNICODE = 0x60,
59 BPLIST_ARRAY = 0xA0, 59 BPLIST_UID = 0x70,
60 BPLIST_SET = 0xC0, 60 BPLIST_ARRAY = 0xA0,
61 BPLIST_DICT = 0xD0, 61 BPLIST_SET = 0xC0,
62 BPLIST_MASK = 0xF0 62 BPLIST_DICT = 0xD0,
63 BPLIST_MASK = 0xF0
63}; 64};
64 65
65static void byte_convert(uint8_t * address, size_t size) 66static void byte_convert(uint8_t * address, size_t size)
66{ 67{
67#if G_BYTE_ORDER == G_LITTLE_ENDIAN 68#if G_BYTE_ORDER == G_LITTLE_ENDIAN
68 uint8_t i = 0, j = 0; 69 uint8_t i = 0, j = 0;
69 uint8_t tmp = 0; 70 uint8_t tmp = 0;
70 71
71 for (i = 0; i < (size / 2); i++) { 72 for (i = 0; i < (size / 2); i++)
72 tmp = address[i]; 73 {
73 j = ((size - 1) + 0) - i; 74 tmp = address[i];
74 address[i] = address[j]; 75 j = ((size - 1) + 0) - i;
75 address[j] = tmp; 76 address[i] = address[j];
76 } 77 address[j] = tmp;
78 }
77#endif 79#endif
78} 80}
79 81
80static uint32_t uint24_from_be(char *buff) 82static uint32_t uint24_from_be(char *buff)
81{ 83{
82 uint32_t ret = 0; 84 uint32_t ret = 0;
83 char *tmp = (char *) &ret; 85 char *tmp = (char *) &ret;
84 memcpy(tmp + 1, buff, 3 * sizeof(char)); 86 memcpy(tmp + 1, buff, 3 * sizeof(char));
85 byte_convert(tmp, sizeof(uint32_t)); 87 byte_convert(tmp, sizeof(uint32_t));
86 return ret; 88 return ret;
87} 89}
88 90
89#define UINT_TO_HOST(x, n) \ 91#define UINT_TO_HOST(x, n) \
@@ -106,787 +108,822 @@ static uint32_t uint24_from_be(char *buff)
106 108
107static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object) 109static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
108{ 110{
109 plist_data_t data = plist_new_plist_data(); 111 plist_data_t data = plist_new_plist_data();
110 112
111 size = 1 << size; // make length less misleading 113 size = 1 << size; // make length less misleading
112 switch (size) { 114 switch (size)
113 case sizeof(uint8_t): 115 {
114 case sizeof(uint16_t): 116 case sizeof(uint8_t):
115 case sizeof(uint32_t): 117 case sizeof(uint16_t):
116 case sizeof(uint64_t): 118 case sizeof(uint32_t):
117 memcpy(&data->intval, bnode, size); 119 case sizeof(uint64_t):
118 data->intval = UINT_TO_HOST(&data->intval, size); 120 memcpy(&data->intval, bnode, size);
119 break; 121 data->intval = UINT_TO_HOST(&data->intval, size);
120 default: 122 break;
121 free(data); 123 default:
122 return NULL; 124 free(data);
123 }; 125 return NULL;
124 126 };
125 *next_object = bnode + size; 127
126 data->type = PLIST_UINT; 128 *next_object = bnode + size;
127 data->length = sizeof(uint64_t); 129 data->type = PLIST_UINT;
128 130 data->length = sizeof(uint64_t);
129 return g_node_new(data); 131
132 return g_node_new(data);
130} 133}
131 134
132static plist_t parse_real_node(char *bnode, uint8_t size) 135static plist_t parse_real_node(char *bnode, uint8_t size)
133{ 136{
134 plist_data_t data = plist_new_plist_data(); 137 plist_data_t data = plist_new_plist_data();
135 float floatval = 0.0; 138 float floatval = 0.0;
136 139
137 size = 1 << size; // make length less misleading 140 size = 1 << size; // make length less misleading
138 switch (size) { 141 switch (size)
139 case sizeof(float): 142 {
140 floatval = *(float *) bnode; 143 case sizeof(float):
141 byte_convert((uint8_t *) & floatval, sizeof(float)); 144 floatval = *(float *) bnode;
142 data->realval = floatval; 145 byte_convert((uint8_t *) & floatval, sizeof(float));
143 break; 146 data->realval = floatval;
144 case sizeof(double): 147 break;
145 data->realval = *(double *) bnode; 148 case sizeof(double):
146 byte_convert((uint8_t *) & (data->realval), sizeof(double)); 149 data->realval = *(double *) bnode;
147 break; 150 byte_convert((uint8_t *) & (data->realval), sizeof(double));
148 default: 151 break;
149 free(data); 152 default:
150 return NULL; 153 free(data);
151 } 154 return NULL;
152 data->type = PLIST_REAL; 155 }
153 data->length = sizeof(double); 156 data->type = PLIST_REAL;
154 157 data->length = sizeof(double);
155 return g_node_new(data); 158
159 return g_node_new(data);
156} 160}
157 161
158static plist_t parse_date_node(char *bnode, uint8_t size) 162static plist_t parse_date_node(char *bnode, uint8_t size)
159{ 163{
160 plist_t node = parse_real_node(bnode, size); 164 plist_t node = parse_real_node(bnode, size);
161 plist_data_t data = plist_get_data(node); 165 plist_data_t data = plist_get_data(node);
162 166
163 double time_real = data->realval; 167 double time_real = data->realval;
164 data->timeval.tv_sec = (glong) time_real; 168 data->timeval.tv_sec = (glong) time_real;
165 data->timeval.tv_usec = (time_real - (glong) time_real) * G_USEC_PER_SEC; 169 data->timeval.tv_usec = (time_real - (glong) time_real) * G_USEC_PER_SEC;
166 data->type = PLIST_DATE; 170 data->type = PLIST_DATE;
167 data->length = sizeof(GTimeVal); 171 data->length = sizeof(GTimeVal);
168 172
169 return node; 173 return node;
170} 174}
171 175
172static plist_t parse_string_node(char *bnode, uint64_t size) 176static plist_t parse_string_node(char *bnode, uint64_t size)
173{ 177{
174 plist_data_t data = plist_new_plist_data(); 178 plist_data_t data = plist_new_plist_data();
175 179
176 data->type = PLIST_STRING; 180 data->type = PLIST_STRING;
177 data->strval = (char *) malloc(sizeof(char) * (size + 1)); 181 data->strval = (char *) malloc(sizeof(char) * (size + 1));
178 memcpy(data->strval, bnode, size); 182 memcpy(data->strval, bnode, size);
179 data->strval[size] = '\0'; 183 data->strval[size] = '\0';
180 data->length = strlen(data->strval); 184 data->length = strlen(data->strval);
181 185
182 return g_node_new(data); 186 return g_node_new(data);
183} 187}
184 188
185static plist_t parse_unicode_node(char *bnode, uint64_t size) 189static plist_t parse_unicode_node(char *bnode, uint64_t size)
186{ 190{
187 plist_data_t data = plist_new_plist_data(); 191 plist_data_t data = plist_new_plist_data();
188 uint64_t i = 0; 192 uint64_t i = 0;
189 gunichar2 *unicodestr = NULL; 193 gunichar2 *unicodestr = NULL;
190 gchar *tmpstr = NULL; 194 gchar *tmpstr = NULL;
191 int type = 0; 195 int type = 0;
192 glong items_read = 0; 196 glong items_read = 0;
193 glong items_written = 0; 197 glong items_written = 0;
194 GError *error = NULL; 198 GError *error = NULL;
195 199
196 data->type = PLIST_STRING; 200 data->type = PLIST_STRING;
197 unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size); 201 unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size);
198 memcpy(unicodestr, bnode, sizeof(gunichar2) * size); 202 memcpy(unicodestr, bnode, sizeof(gunichar2) * size);
199 for (i = 0; i < size; i++) 203 for (i = 0; i < size; i++)
200 byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2)); 204 byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2));
201 205
202 tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error); 206 tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error);
203 free(unicodestr); 207 free(unicodestr);
204 208
205 data->type = PLIST_STRING; 209 data->type = PLIST_STRING;
206 data->strval = (char *) malloc(sizeof(char) * (items_written + 1)); 210 data->strval = (char *) malloc(sizeof(char) * (items_written + 1));
207 memcpy(data->strval, tmpstr, items_written); 211 memcpy(data->strval, tmpstr, items_written);
208 data->strval[items_written] = '\0'; 212 data->strval[items_written] = '\0';
209 data->length = strlen(data->strval); 213 data->length = strlen(data->strval);
210 g_free(tmpstr); 214 g_free(tmpstr);
211 return g_node_new(data); 215 return g_node_new(data);
212} 216}
213 217
214static plist_t parse_data_node(char *bnode, uint64_t size) 218static plist_t parse_data_node(char *bnode, uint64_t size)
215{ 219{
216 plist_data_t data = plist_new_plist_data(); 220 plist_data_t data = plist_new_plist_data();
217 221
218 data->type = PLIST_DATA; 222 data->type = PLIST_DATA;
219 data->length = size; 223 data->length = size;
220 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size); 224 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size);
221 memcpy(data->buff, bnode, sizeof(uint8_t) * size); 225 memcpy(data->buff, bnode, sizeof(uint8_t) * size);
222 226
223 return g_node_new(data); 227 return g_node_new(data);
224} 228}
225 229
226static plist_t parse_dict_node(char *bnode, uint64_t size, uint32_t ref_size) 230static plist_t parse_dict_node(char *bnode, uint64_t size, uint32_t ref_size)
227{ 231{
228 plist_data_t data = plist_new_plist_data(); 232 plist_data_t data = plist_new_plist_data();
229 233
230 data->type = PLIST_DICT; 234 data->type = PLIST_DICT;
231 data->length = size; 235 data->length = size;
232 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size * 2); 236 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size * 2);
233 memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size * 2); 237 memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size * 2);
234 238
235 return g_node_new(data); 239 return g_node_new(data);
236} 240}
237 241
238static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size) 242static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size)
239{ 243{
240 plist_data_t data = plist_new_plist_data(); 244 plist_data_t data = plist_new_plist_data();
241 245
242 data->type = PLIST_ARRAY; 246 data->type = PLIST_ARRAY;
243 data->length = size; 247 data->length = size;
244 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size); 248 data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size);
245 memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size); 249 memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size);
246 250
247 return g_node_new(data); 251 return g_node_new(data);
248} 252}
249 253
250 254
251 255
252static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object) 256static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object)
253{ 257{
254 uint16_t type = 0; 258 uint16_t type = 0;
255 uint64_t size = 0; 259 uint64_t size = 0;
256 260
257 if (!object) 261 if (!object)
258 return NULL; 262 return NULL;
259 263
260 type = (*object) & 0xF0; 264 type = (*object) & 0xF0;
261 size = (*object) & 0x0F; 265 size = (*object) & 0x0F;
262 object++; 266 object++;
263 267
264 switch (type) { 268 switch (type)
265 269 {
266 case BPLIST_NULL: 270
267 switch (size) { 271 case BPLIST_NULL:
268 272 switch (size)
269 case BPLIST_TRUE: 273 {
270 { 274
271 plist_data_t data = plist_new_plist_data(); 275 case BPLIST_TRUE:
272 data->type = PLIST_BOOLEAN; 276 {
273 data->boolval = TRUE; 277 plist_data_t data = plist_new_plist_data();
274 data->length = 1; 278 data->type = PLIST_BOOLEAN;
275 return g_node_new(data); 279 data->boolval = TRUE;
276 } 280 data->length = 1;
277 281 return g_node_new(data);
278 case BPLIST_FALSE: 282 }
279 { 283
280 plist_data_t data = plist_new_plist_data(); 284 case BPLIST_FALSE:
281 data->type = PLIST_BOOLEAN; 285 {
282 data->boolval = FALSE; 286 plist_data_t data = plist_new_plist_data();
283 data->length = 1; 287 data->type = PLIST_BOOLEAN;
284 return g_node_new(data); 288 data->boolval = FALSE;
285 } 289 data->length = 1;
286 290 return g_node_new(data);
287 case BPLIST_NULL: 291 }
288 default: 292
289 return NULL; 293 case BPLIST_NULL:
290 } 294 default:
291 295 return NULL;
292 case BPLIST_UINT: 296 }
293 return parse_uint_node(object, size, next_object); 297
294 298 case BPLIST_UINT:
295 case BPLIST_REAL: 299 return parse_uint_node(object, size, next_object);
296 return parse_real_node(object, size); 300
297 301 case BPLIST_REAL:
298 case BPLIST_DATE: 302 return parse_real_node(object, size);
299 if (3 != size) 303
300 return NULL; 304 case BPLIST_DATE:
301 else 305 if (3 != size)
302 return parse_date_node(object, size); 306 return NULL;
303 307 else
304 case BPLIST_DATA: 308 return parse_date_node(object, size);
305 if (0x0F == size) { 309
306 plist_t size_node = parse_bin_node(object, dict_size, &object); 310 case BPLIST_DATA:
307 if (plist_get_node_type(size_node) != PLIST_UINT) 311 if (0x0F == size)
308 return NULL; 312 {
309 plist_get_uint_val(size_node, &size); 313 plist_t size_node = parse_bin_node(object, dict_size, &object);
310 plist_free(size_node); 314 if (plist_get_node_type(size_node) != PLIST_UINT)
311 } 315 return NULL;
312 return parse_data_node(object, size); 316 plist_get_uint_val(size_node, &size);
313 317 plist_free(size_node);
314 case BPLIST_STRING: 318 }
315 if (0x0F == size) { 319 return parse_data_node(object, size);
316 plist_t size_node = parse_bin_node(object, dict_size, &object); 320
317 if (plist_get_node_type(size_node) != PLIST_UINT) 321 case BPLIST_STRING:
318 return NULL; 322 if (0x0F == size)
319 plist_get_uint_val(size_node, &size); 323 {
320 plist_free(size_node); 324 plist_t size_node = parse_bin_node(object, dict_size, &object);
321 } 325 if (plist_get_node_type(size_node) != PLIST_UINT)
322 return parse_string_node(object, size); 326 return NULL;
323 327 plist_get_uint_val(size_node, &size);
324 case BPLIST_UNICODE: 328 plist_free(size_node);
325 if (0x0F == size) { 329 }
326 plist_t size_node = parse_bin_node(object, dict_size, &object); 330 return parse_string_node(object, size);
327 if (plist_get_node_type(size_node) != PLIST_UINT) 331
328 return NULL; 332 case BPLIST_UNICODE:
329 plist_get_uint_val(size_node, &size); 333 if (0x0F == size)
330 plist_free(size_node); 334 {
331 } 335 plist_t size_node = parse_bin_node(object, dict_size, &object);
332 return parse_unicode_node(object, size); 336 if (plist_get_node_type(size_node) != PLIST_UINT)
333 337 return NULL;
334 case BPLIST_UID: 338 plist_get_uint_val(size_node, &size);
335 case BPLIST_ARRAY: 339 plist_free(size_node);
336 if (0x0F == size) { 340 }
337 plist_t size_node = parse_bin_node(object, dict_size, &object); 341 return parse_unicode_node(object, size);
338 if (plist_get_node_type(size_node) != PLIST_UINT) 342
339 return NULL; 343 case BPLIST_UID:
340 plist_get_uint_val(size_node, &size); 344 case BPLIST_ARRAY:
341 plist_free(size_node); 345 if (0x0F == size)
342 } 346 {
343 return parse_array_node(object, size, dict_size); 347 plist_t size_node = parse_bin_node(object, dict_size, &object);
344 348 if (plist_get_node_type(size_node) != PLIST_UINT)
345 case BPLIST_SET: 349 return NULL;
346 case BPLIST_DICT: 350 plist_get_uint_val(size_node, &size);
347 if (0x0F == size) { 351 plist_free(size_node);
348 plist_t size_node = parse_bin_node(object, dict_size, &object); 352 }
349 if (plist_get_node_type(size_node) != PLIST_UINT) 353 return parse_array_node(object, size, dict_size);
350 return NULL; 354
351 plist_get_uint_val(size_node, &size); 355 case BPLIST_SET:
352 plist_free(size_node); 356 case BPLIST_DICT:
353 } 357 if (0x0F == size)
354 return parse_dict_node(object, size, dict_size); 358 {
355 default: 359 plist_t size_node = parse_bin_node(object, dict_size, &object);
356 return NULL; 360 if (plist_get_node_type(size_node) != PLIST_UINT)
357 } 361 return NULL;
358 return NULL; 362 plist_get_uint_val(size_node, &size);
363 plist_free(size_node);
364 }
365 return parse_dict_node(object, size, dict_size);
366 default:
367 return NULL;
368 }
369 return NULL;
359} 370}
360 371
361static gpointer copy_plist_data(gconstpointer src, gpointer data) 372static gpointer copy_plist_data(gconstpointer src, gpointer data)
362{ 373{
363 plist_data_t srcdata = (plist_data_t) src; 374 plist_data_t srcdata = (plist_data_t) src;
364 plist_data_t dstdata = plist_new_plist_data(); 375 plist_data_t dstdata = plist_new_plist_data();
365 376
366 dstdata->type = srcdata->type; 377 dstdata->type = srcdata->type;
367 dstdata->length = srcdata->length; 378 dstdata->length = srcdata->length;
368 switch (dstdata->type) { 379 switch (dstdata->type)
369 case PLIST_BOOLEAN: 380 {
370 dstdata->boolval = srcdata->boolval; 381 case PLIST_BOOLEAN:
371 break; 382 dstdata->boolval = srcdata->boolval;
372 case PLIST_UINT: 383 break;
373 dstdata->intval = srcdata->intval; 384 case PLIST_UINT:
374 break; 385 dstdata->intval = srcdata->intval;
375 case PLIST_DATE: 386 break;
376 dstdata->timeval.tv_sec = srcdata->timeval.tv_sec; 387 case PLIST_DATE:
377 dstdata->timeval.tv_usec = srcdata->timeval.tv_usec; 388 dstdata->timeval.tv_sec = srcdata->timeval.tv_sec;
378 break; 389 dstdata->timeval.tv_usec = srcdata->timeval.tv_usec;
379 case PLIST_REAL: 390 break;
380 dstdata->realval = srcdata->realval; 391 case PLIST_REAL:
381 break; 392 dstdata->realval = srcdata->realval;
382 case PLIST_KEY: 393 break;
383 case PLIST_STRING: 394 case PLIST_KEY:
384 dstdata->strval = strdup(srcdata->strval); 395 case PLIST_STRING:
385 break; 396 dstdata->strval = strdup(srcdata->strval);
386 case PLIST_DATA: 397 break;
387 case PLIST_ARRAY: 398 case PLIST_DATA:
388 dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length); 399 case PLIST_ARRAY:
389 memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length); 400 dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length);
390 break; 401 memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length);
391 case PLIST_DICT: 402 break;
392 dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length * 2); 403 case PLIST_DICT:
393 memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length * 2); 404 dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length * 2);
394 break; 405 memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length * 2);
395 default: 406 break;
396 break; 407 default:
397 } 408 break;
398 409 }
399 return dstdata; 410
411 return dstdata;
400} 412}
401 413
402void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) 414void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
403{ 415{
404 char *trailer = NULL; 416 char *trailer = NULL;
405 417
406 uint8_t offset_size = 0; 418 uint8_t offset_size = 0;
407 uint8_t dict_param_size = 0; 419 uint8_t dict_param_size = 0;
408 uint64_t num_objects = 0; 420 uint64_t num_objects = 0;
409 uint64_t root_object = 0; 421 uint64_t root_object = 0;
410 uint64_t offset_table_index = 0; 422 uint64_t offset_table_index = 0;
411 423
412 plist_t *nodeslist = NULL; 424 plist_t *nodeslist = NULL;
413 uint64_t i = 0; 425 uint64_t i = 0;
414 uint64_t current_offset = 0; 426 uint64_t current_offset = 0;
415 char *offset_table = NULL; 427 char *offset_table = NULL;
416 uint32_t j = 0, str_i = 0, str_j = 0; 428 uint32_t j = 0, str_i = 0, str_j = 0;
417 uint32_t index1 = 0, index2 = 0; 429 uint32_t index1 = 0, index2 = 0;
418 430
419 431
420 //first check we have enough data 432 //first check we have enough data
421 if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) 433 if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE))
422 return; 434 return;
423 //check that plist_bin in actually a plist 435 //check that plist_bin in actually a plist
424 if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) 436 if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0)
425 return; 437 return;
426 //check for known version 438 //check for known version
427 if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) 439 if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0)
428 return; 440 return;
429 441
430 //now parse trailer 442 //now parse trailer
431 trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE)); 443 trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE));
432 444
433 offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX]; 445 offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX];
434 dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX]; 446 dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX];
435 num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); 447 num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX);
436 root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); 448 root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX);
437 offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); 449 offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX);
438 450
439 if (num_objects == 0) 451 if (num_objects == 0)
440 return; 452 return;
441 453
442 //allocate serialized array of nodes 454 //allocate serialized array of nodes
443 nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects); 455 nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects);
444 456
445 if (!nodeslist) 457 if (!nodeslist)
446 return; 458 return;
447 459
448 //parse serialized nodes 460 //parse serialized nodes
449 offset_table = (char *) (plist_bin + offset_table_index); 461 offset_table = (char *) (plist_bin + offset_table_index);
450 for (i = 0; i < num_objects; i++) { 462 for (i = 0; i < num_objects; i++)
451 char *obj = NULL; 463 {
452 current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size); 464 char *obj = NULL;
453 465 current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size);
454 obj = (char *) (plist_bin + current_offset); 466
455 nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj); 467 obj = (char *) (plist_bin + current_offset);
456 } 468 nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj);
457 469 }
458 //setup children for structured types 470
459 for (i = 0; i < num_objects; i++) { 471 //setup children for structured types
460 472 for (i = 0; i < num_objects; i++)
461 plist_data_t data = plist_get_data(nodeslist[i]); 473 {
462 474
463 switch (data->type) { 475 plist_data_t data = plist_get_data(nodeslist[i]);
464 case PLIST_DICT: 476
465 for (j = 0; j < data->length; j++) { 477 switch (data->type)
466 str_i = j * dict_param_size; 478 {
467 str_j = (j + data->length) * dict_param_size; 479 case PLIST_DICT:
468 480 for (j = 0; j < data->length; j++)
469 index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size); 481 {
470 index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size); 482 str_i = j * dict_param_size;
471 483 str_j = (j + data->length) * dict_param_size;
472 //first one is actually a key 484
473 plist_get_data(nodeslist[index1])->type = PLIST_KEY; 485 index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size);
474 486 index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size);
475 if (index1 < num_objects) { 487
476 if (G_NODE_IS_ROOT(nodeslist[index1])) 488 //first one is actually a key
477 g_node_append(nodeslist[i], nodeslist[index1]); 489 plist_get_data(nodeslist[index1])->type = PLIST_KEY;
478 else 490
479 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); 491 if (index1 < num_objects)
480 } 492 {
481 493 if (G_NODE_IS_ROOT(nodeslist[index1]))
482 if (index2 < num_objects) { 494 g_node_append(nodeslist[i], nodeslist[index1]);
483 if (G_NODE_IS_ROOT(nodeslist[index2])) 495 else
484 g_node_append(nodeslist[i], nodeslist[index2]); 496 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
485 else 497 }
486 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL)); 498
487 } 499 if (index2 < num_objects)
488 } 500 {
489 501 if (G_NODE_IS_ROOT(nodeslist[index2]))
490 free(data->buff); 502 g_node_append(nodeslist[i], nodeslist[index2]);
491 break; 503 else
492 504 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL));
493 case PLIST_ARRAY: 505 }
494 for (j = 0; j < data->length; j++) { 506 }
495 str_j = j * dict_param_size; 507
496 index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size); 508 free(data->buff);
497 509 break;
498 if (index1 < num_objects) { 510
499 if (G_NODE_IS_ROOT(nodeslist[index1])) 511 case PLIST_ARRAY:
500 g_node_append(nodeslist[i], nodeslist[index1]); 512 for (j = 0; j < data->length; j++)
501 else 513 {
502 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); 514 str_j = j * dict_param_size;
503 } 515 index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size);
504 } 516
505 free(data->buff); 517 if (index1 < num_objects)
506 break; 518 {
507 default: 519 if (G_NODE_IS_ROOT(nodeslist[index1]))
508 break; 520 g_node_append(nodeslist[i], nodeslist[index1]);
509 } 521 else
510 } 522 g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL));
511 523 }
512 *plist = nodeslist[root_object]; 524 }
513 free(nodeslist); 525 free(data->buff);
526 break;
527 default:
528 break;
529 }
530 }
531
532 *plist = nodeslist[root_object];
533 free(nodeslist);
514} 534}
515 535
516static guint plist_data_hash(gconstpointer key) 536static guint plist_data_hash(gconstpointer key)
517{ 537{
518 plist_data_t data = plist_get_data((plist_t) key); 538 plist_data_t data = plist_get_data((plist_t) key);
519 539
520 guint hash = data->type; 540 guint hash = data->type;
521 guint i = 0; 541 guint i = 0;
522 542
523 char *buff = NULL; 543 char *buff = NULL;
524 guint size = 0; 544 guint size = 0;
525 545
526 switch (data->type) { 546 switch (data->type)
527 case PLIST_BOOLEAN: 547 {
528 case PLIST_UINT: 548 case PLIST_BOOLEAN:
529 case PLIST_REAL: 549 case PLIST_UINT:
530 buff = (char *) &data->intval; //works also for real as we use an union 550 case PLIST_REAL:
531 size = 8; 551 buff = (char *) &data->intval; //works also for real as we use an union
532 break; 552 size = 8;
533 case PLIST_KEY: 553 break;
534 case PLIST_STRING: 554 case PLIST_KEY:
535 buff = data->strval; 555 case PLIST_STRING:
536 size = strlen(buff); 556 buff = data->strval;
537 break; 557 size = strlen(buff);
538 case PLIST_DATA: 558 break;
539 case PLIST_ARRAY: 559 case PLIST_DATA:
540 case PLIST_DICT: 560 case PLIST_ARRAY:
541 //for these types only hash pointer 561 case PLIST_DICT:
542 buff = (char *) &key; 562 //for these types only hash pointer
543 size = sizeof(gconstpointer); 563 buff = (char *) &key;
544 break; 564 size = sizeof(gconstpointer);
545 case PLIST_DATE: 565 break;
546 buff = (char *) &(data->timeval); 566 case PLIST_DATE:
547 size = data->length; 567 buff = (char *) &(data->timeval);
548 break; 568 size = data->length;
549 default: 569 break;
550 break; 570 default:
551 } 571 break;
552 572 }
553 //now perform hash 573
554 for (i = 0; i < size; buff++, i++) 574 //now perform hash
555 hash = hash << 7 ^ (*buff); 575 for (i = 0; i < size; buff++, i++)
556 576 hash = hash << 7 ^ (*buff);
557 return hash; 577
578 return hash;
558} 579}
559 580
560 581
561 582
562struct serialize_s { 583struct serialize_s
563 GPtrArray *objects; 584{
564 GHashTable *ref_table; 585 GPtrArray *objects;
586 GHashTable *ref_table;
565}; 587};
566 588
567static void serialize_plist(GNode * node, gpointer data) 589static void serialize_plist(GNode * node, gpointer data)
568{ 590{
569 uint64_t *index_val = NULL; 591 uint64_t *index_val = NULL;
570 struct serialize_s *ser = (struct serialize_s *) data; 592 struct serialize_s *ser = (struct serialize_s *) data;
571 uint64_t current_index = ser->objects->len; 593 uint64_t current_index = ser->objects->len;
572 594
573 //first check that node is not yet in objects 595 //first check that node is not yet in objects
574 gpointer val = g_hash_table_lookup(ser->ref_table, node); 596 gpointer val = g_hash_table_lookup(ser->ref_table, node);
575 if (val) { 597 if (val)
576 //data is already in table 598 {
577 return; 599 //data is already in table
578 } 600 return;
579 //insert new ref 601 }
580 index_val = (uint64_t *) malloc(sizeof(uint64_t)); 602 //insert new ref
581 *index_val = current_index; 603 index_val = (uint64_t *) malloc(sizeof(uint64_t));
582 g_hash_table_insert(ser->ref_table, node, index_val); 604 *index_val = current_index;
583 605 g_hash_table_insert(ser->ref_table, node, index_val);
584 //now append current node to object array 606
585 g_ptr_array_add(ser->objects, node); 607 //now append current node to object array
586 608 g_ptr_array_add(ser->objects, node);
587 //now recurse on children 609
588 g_node_children_foreach(node, G_TRAVERSE_ALL, serialize_plist, data); 610 //now recurse on children
589 return; 611 g_node_children_foreach(node, G_TRAVERSE_ALL, serialize_plist, data);
612 return;
590} 613}
591 614
592static gboolean free_index(gpointer key, gpointer value, gpointer user_data) 615static gboolean free_index(gpointer key, gpointer value, gpointer user_data)
593{ 616{
594 free((uint64_t *) value); 617 free((uint64_t *) value);
595 return TRUE; 618 return TRUE;
596} 619}
597 620
598#define Log2(x) (x == 8 ? 3 : (x == 4 ? 2 : (x == 2 ? 1 : 0))) 621#define Log2(x) (x == 8 ? 3 : (x == 4 ? 2 : (x == 2 ? 1 : 0)))
599 622
600static void write_int(GByteArray * bplist, uint64_t val) 623static void write_int(GByteArray * bplist, uint64_t val)
601{ 624{
602 uint64_t size = get_needed_bytes(val); 625 uint64_t size = get_needed_bytes(val);
603 uint8_t *buff = NULL; 626 uint8_t *buff = NULL;
604 //do not write 3bytes int node 627 //do not write 3bytes int node
605 if (size == 3) 628 if (size == 3)
606 size++; 629 size++;
607 buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 630 buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
608 buff[0] = BPLIST_UINT | Log2(size); 631 buff[0] = BPLIST_UINT | Log2(size);
609 memcpy(buff + 1, &val, size); 632 memcpy(buff + 1, &val, size);
610 byte_convert(buff + 1, size); 633 byte_convert(buff + 1, size);
611 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 634 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
612 free(buff); 635 free(buff);
613} 636}
614 637
615static void write_real(GByteArray * bplist, double val) 638static void write_real(GByteArray * bplist, double val)
616{ 639{
617 uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space 640 uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space
618 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 641 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
619 buff[0] = BPLIST_REAL | Log2(size); 642 buff[0] = BPLIST_REAL | Log2(size);
620 if (size == sizeof(double)) { 643 if (size == sizeof(double))
621 memcpy(buff + 1, &val, size); 644 {
622 } else if (size == sizeof(float)) { 645 memcpy(buff + 1, &val, size);
623 float tmpval = (float) val; 646 }
624 memcpy(buff + 1, &tmpval, size); 647 else if (size == sizeof(float))
625 } 648 {
626 byte_convert(buff + 1, size); 649 float tmpval = (float) val;
627 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 650 memcpy(buff + 1, &tmpval, size);
628 free(buff); 651 }
652 byte_convert(buff + 1, size);
653 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
654 free(buff);
629} 655}
630 656
631static void write_date(GByteArray * bplist, double val) 657static void write_date(GByteArray * bplist, double val)
632{ 658{
633 uint64_t size = 8; //dates always use 8 bytes 659 uint64_t size = 8; //dates always use 8 bytes
634 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 660 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
635 buff[0] = BPLIST_DATE | Log2(size); 661 buff[0] = BPLIST_DATE | Log2(size);
636 memcpy(buff + 1, &val, size); 662 memcpy(buff + 1, &val, size);
637 byte_convert(buff + 1, size); 663 byte_convert(buff + 1, size);
638 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 664 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
639 free(buff); 665 free(buff);
640} 666}
641 667
642static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size) 668static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size)
643{ 669{
644 uint8_t *buff = NULL; 670 uint8_t *buff = NULL;
645 uint8_t marker = mark | (size < 15 ? size : 0xf); 671 uint8_t marker = mark | (size < 15 ? size : 0xf);
646 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 672 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
647 if (size >= 15) { 673 if (size >= 15)
648 GByteArray *int_buff = g_byte_array_new(); 674 {
649 write_int(int_buff, size); 675 GByteArray *int_buff = g_byte_array_new();
650 g_byte_array_append(bplist, int_buff->data, int_buff->len); 676 write_int(int_buff, size);
651 g_byte_array_free(int_buff, TRUE); 677 g_byte_array_append(bplist, int_buff->data, int_buff->len);
652 } 678 g_byte_array_free(int_buff, TRUE);
653 buff = (uint8_t *) malloc(size); 679 }
654 memcpy(buff, val, size); 680 buff = (uint8_t *) malloc(size);
655 g_byte_array_append(bplist, buff, size); 681 memcpy(buff, val, size);
656 free(buff); 682 g_byte_array_append(bplist, buff, size);
683 free(buff);
657} 684}
658 685
659static void write_data(GByteArray * bplist, uint8_t * val, uint64_t size) 686static void write_data(GByteArray * bplist, uint8_t * val, uint64_t size)
660{ 687{
661 write_raw_data(bplist, BPLIST_DATA, val, size); 688 write_raw_data(bplist, BPLIST_DATA, val, size);
662} 689}
663 690
664static void write_string(GByteArray * bplist, char *val) 691static void write_string(GByteArray * bplist, char *val)
665{ 692{
666 uint64_t size = strlen(val); 693 uint64_t size = strlen(val);
667 write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size); 694 write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size);
668} 695}
669 696
670static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size) 697static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size)
671{ 698{
672 uint64_t i = 0; 699 uint64_t i = 0;
673 uint64_t size2 = size * sizeof(gunichar2); 700 uint64_t size2 = size * sizeof(gunichar2);
674 uint8_t *buff = (uint8_t *) malloc(size2); 701 uint8_t *buff = (uint8_t *) malloc(size2);
675 memcpy(buff, val, size2); 702 memcpy(buff, val, size2);
676 for (i = 0; i < size; i++) 703 for (i = 0; i < size; i++)
677 byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2)); 704 byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2));
678 write_raw_data(bplist, BPLIST_STRING, buff, size2); 705 write_raw_data(bplist, BPLIST_STRING, buff, size2);
679} 706}
680 707
681static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) 708static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
682{ 709{
683 uint64_t idx = 0; 710 uint64_t idx = 0;
684 uint8_t *buff = NULL; 711 uint8_t *buff = NULL;
685 712
686 GNode *cur = NULL; 713 GNode *cur = NULL;
687 uint64_t i = 0; 714 uint64_t i = 0;
688 715
689 uint64_t size = g_node_n_children(node); 716 uint64_t size = g_node_n_children(node);
690 uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf); 717 uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf);
691 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 718 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
692 if (size >= 15) { 719 if (size >= 15)
693 GByteArray *int_buff = g_byte_array_new(); 720 {
694 write_int(int_buff, size); 721 GByteArray *int_buff = g_byte_array_new();
695 g_byte_array_append(bplist, int_buff->data, int_buff->len); 722 write_int(int_buff, size);
696 g_byte_array_free(int_buff, TRUE); 723 g_byte_array_append(bplist, int_buff->data, int_buff->len);
697 } 724 g_byte_array_free(int_buff, TRUE);
698 725 }
699 buff = (uint8_t *) malloc(size * dict_param_size); 726
700 727 buff = (uint8_t *) malloc(size * dict_param_size);
701 for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) { 728
702 idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); 729 for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++)
703 memcpy(buff + i * dict_param_size, &idx, dict_param_size); 730 {
704 byte_convert(buff + i * dict_param_size, dict_param_size); 731 idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur));
705 } 732 memcpy(buff + i * dict_param_size, &idx, dict_param_size);
706 733 byte_convert(buff + i * dict_param_size, dict_param_size);
707 //now append to bplist 734 }
708 g_byte_array_append(bplist, buff, size * dict_param_size); 735
709 free(buff); 736 //now append to bplist
737 g_byte_array_append(bplist, buff, size * dict_param_size);
738 free(buff);
710 739
711} 740}
712 741
713static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) 742static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
714{ 743{
715 uint64_t idx1 = 0; 744 uint64_t idx1 = 0;
716 uint64_t idx2 = 0; 745 uint64_t idx2 = 0;
717 uint8_t *buff = NULL; 746 uint8_t *buff = NULL;
718 747
719 GNode *cur = NULL; 748 GNode *cur = NULL;
720 uint64_t i = 0; 749 uint64_t i = 0;
721 750
722 uint64_t size = g_node_n_children(node) / 2; 751 uint64_t size = g_node_n_children(node) / 2;
723 uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf); 752 uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf);
724 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 753 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
725 if (size >= 15) { 754 if (size >= 15)
726 GByteArray *int_buff = g_byte_array_new(); 755 {
727 write_int(int_buff, size); 756 GByteArray *int_buff = g_byte_array_new();
728 g_byte_array_append(bplist, int_buff->data, int_buff->len); 757 write_int(int_buff, size);
729 g_byte_array_free(int_buff, TRUE); 758 g_byte_array_append(bplist, int_buff->data, int_buff->len);
730 } 759 g_byte_array_free(int_buff, TRUE);
731 760 }
732 buff = (uint8_t *) malloc(size * 2 * dict_param_size); 761
733 762 buff = (uint8_t *) malloc(size * 2 * dict_param_size);
734 for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) { 763
735 idx1 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); 764 for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++)
736 memcpy(buff + i * dict_param_size, &idx1, dict_param_size); 765 {
737 byte_convert(buff + i * dict_param_size, dict_param_size); 766 idx1 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur));
738 767 memcpy(buff + i * dict_param_size, &idx1, dict_param_size);
739 idx2 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur->next)); 768 byte_convert(buff + i * dict_param_size, dict_param_size);
740 memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size); 769
741 byte_convert(buff + (i + size) * dict_param_size, dict_param_size); 770 idx2 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur->next));
742 } 771 memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size);
743 772 byte_convert(buff + (i + size) * dict_param_size, dict_param_size);
744 //now append to bplist 773 }
745 g_byte_array_append(bplist, buff, size * 2 * dict_param_size); 774
746 free(buff); 775 //now append to bplist
776 g_byte_array_append(bplist, buff, size * 2 * dict_param_size);
777 free(buff);
747 778
748} 779}
749 780
750void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) 781void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
751{ 782{
752 GPtrArray *objects = NULL; 783 GPtrArray *objects = NULL;
753 GHashTable *ref_table = NULL; 784 GHashTable *ref_table = NULL;
754 struct serialize_s ser_s; 785 struct serialize_s ser_s;
755 uint8_t offset_size = 0; 786 uint8_t offset_size = 0;
756 uint8_t dict_param_size = 0; 787 uint8_t dict_param_size = 0;
757 uint64_t num_objects = 0; 788 uint64_t num_objects = 0;
758 uint64_t root_object = 0; 789 uint64_t root_object = 0;
759 uint64_t offset_table_index = 0; 790 uint64_t offset_table_index = 0;
760 GByteArray *bplist_buff = NULL; 791 GByteArray *bplist_buff = NULL;
761 uint64_t i = 0; 792 uint64_t i = 0;
762 uint8_t *buff = NULL; 793 uint8_t *buff = NULL;
763 uint64_t *offsets = NULL; 794 uint64_t *offsets = NULL;
764 uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 }; 795 uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 };
765 uint8_t trailer[BPLIST_TRL_SIZE]; 796 uint8_t trailer[BPLIST_TRL_SIZE];
766 //for string 797 //for string
767 glong len = 0; 798 glong len = 0;
768 int type = 0; 799 int type = 0;
769 glong items_read = 0; 800 glong items_read = 0;
770 glong items_written = 0; 801 glong items_written = 0;
771 GError *error = NULL; 802 GError *error = NULL;
772 gunichar2 *unicodestr = NULL; 803 gunichar2 *unicodestr = NULL;
773 804
774 //check for valid input 805 //check for valid input
775 if (!plist || !plist_bin || *plist_bin || !length) 806 if (!plist || !plist_bin || *plist_bin || !length)
776 return; 807 return;
777 808
778 //list of objects 809 //list of objects
779 objects = g_ptr_array_new(); 810 objects = g_ptr_array_new();
780 //hashtable to write only once same nodes 811 //hashtable to write only once same nodes
781 ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); 812 ref_table = g_hash_table_new(plist_data_hash, plist_data_compare);
782 813
783 //serialize plist 814 //serialize plist
784 ser_s.objects = objects; 815 ser_s.objects = objects;
785 ser_s.ref_table = ref_table; 816 ser_s.ref_table = ref_table;
786 serialize_plist(plist, &ser_s); 817 serialize_plist(plist, &ser_s);
787 818
788 //now stream to output buffer 819 //now stream to output buffer
789 offset_size = 0; //unknown yet 820 offset_size = 0; //unknown yet
790 dict_param_size = get_needed_bytes(objects->len); 821 dict_param_size = get_needed_bytes(objects->len);
791 num_objects = objects->len; 822 num_objects = objects->len;
792 root_object = 0; //root is first in list 823 root_object = 0; //root is first in list
793 offset_table_index = 0; //unknown yet 824 offset_table_index = 0; //unknown yet
794 825
795 //setup a dynamic bytes array to store bplist in 826 //setup a dynamic bytes array to store bplist in
796 bplist_buff = g_byte_array_new(); 827 bplist_buff = g_byte_array_new();
797 828
798 //set magic number and version 829 //set magic number and version
799 g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); 830 g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE);
800 g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); 831 g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE);
801 832
802 //write objects and table 833 //write objects and table
803 offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t)); 834 offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t));
804 for (i = 0; i < num_objects; i++) { 835 for (i = 0; i < num_objects; i++)
805 836 {
806 plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); 837
807 offsets[i] = bplist_buff->len; 838 plist_data_t data = plist_get_data(g_ptr_array_index(objects, i));
808 839 offsets[i] = bplist_buff->len;
809 switch (data->type) { 840
810 case PLIST_BOOLEAN: 841 switch (data->type)
811 buff = (uint8_t *) malloc(sizeof(uint8_t)); 842 {
812 buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; 843 case PLIST_BOOLEAN:
813 g_byte_array_append(bplist_buff, buff, sizeof(uint8_t)); 844 buff = (uint8_t *) malloc(sizeof(uint8_t));
814 free(buff); 845 buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE;
815 break; 846 g_byte_array_append(bplist_buff, buff, sizeof(uint8_t));
816 847 free(buff);
817 case PLIST_UINT: 848 break;
818 write_int(bplist_buff, data->intval); 849
819 break; 850 case PLIST_UINT:
820 851 write_int(bplist_buff, data->intval);
821 case PLIST_REAL: 852 break;
822 write_real(bplist_buff, data->realval); 853
823 break; 854 case PLIST_REAL:
824 855 write_real(bplist_buff, data->realval);
825 case PLIST_KEY: 856 break;
826 case PLIST_STRING: 857
827 len = strlen(data->strval); 858 case PLIST_KEY:
828 type = xmlDetectCharEncoding(data->strval, len); 859 case PLIST_STRING:
829 if (XML_CHAR_ENCODING_UTF8 == type) { 860 len = strlen(data->strval);
830 unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); 861 type = xmlDetectCharEncoding(data->strval, len);
831 write_unicode(bplist_buff, unicodestr, items_written); 862 if (XML_CHAR_ENCODING_UTF8 == type)
832 g_free(unicodestr); 863 {
833 } else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { 864 unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error);
834 write_string(bplist_buff, data->strval); 865 write_unicode(bplist_buff, unicodestr, items_written);
835 } 866 g_free(unicodestr);
836 break; 867 }
837 case PLIST_DATA: 868 else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
838 write_data(bplist_buff, data->buff, data->length); 869 {
839 case PLIST_ARRAY: 870 write_string(bplist_buff, data->strval);
840 write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); 871 }
841 break; 872 break;
842 case PLIST_DICT: 873 case PLIST_DATA:
843 write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); 874 write_data(bplist_buff, data->buff, data->length);
844 break; 875 case PLIST_ARRAY:
845 case PLIST_DATE: 876 write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size);
846 write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC); 877 break;
847 break; 878 case PLIST_DICT:
848 default: 879 write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size);
849 break; 880 break;
850 } 881 case PLIST_DATE:
851 } 882 write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC);
852 883 break;
853 //free intermediate objects 884 default:
854 g_hash_table_foreach_remove(ref_table, free_index, NULL); 885 break;
855 g_ptr_array_free(objects, TRUE); 886 }
856 g_hash_table_destroy(ref_table); 887 }
857 888
858 //write offsets 889 //free intermediate objects
859 offset_size = get_needed_bytes(bplist_buff->len); 890 g_hash_table_foreach_remove(ref_table, free_index, NULL);
860 offset_table_index = bplist_buff->len; 891 g_ptr_array_free(objects, TRUE);
861 for (i = 0; i < num_objects; i++) { 892 g_hash_table_destroy(ref_table);
862 uint8_t *offsetbuff = (uint8_t *) malloc(offset_size); 893
863 memcpy(offsetbuff, offsets + i, offset_size); 894 //write offsets
864 byte_convert(offsetbuff, offset_size); 895 offset_size = get_needed_bytes(bplist_buff->len);
865 g_byte_array_append(bplist_buff, offsetbuff, offset_size); 896 offset_table_index = bplist_buff->len;
866 free(offsetbuff); 897 for (i = 0; i < num_objects; i++)
867 } 898 {
868 899 uint8_t *offsetbuff = (uint8_t *) malloc(offset_size);
869 //experimental pad to reflect apple's files 900 memcpy(offsetbuff, offsets + i, offset_size);
870 g_byte_array_append(bplist_buff, pad, 6); 901 byte_convert(offsetbuff, offset_size);
871 902 g_byte_array_append(bplist_buff, offsetbuff, offset_size);
872 //setup trailer 903 free(offsetbuff);
873 num_objects = GUINT64_FROM_BE(num_objects); 904 }
874 root_object = GUINT64_FROM_BE(root_object); 905
875 offset_table_index = GUINT64_FROM_BE(offset_table_index); 906 //experimental pad to reflect apple's files
876 907 g_byte_array_append(bplist_buff, pad, 6);
877 memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); 908
878 memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); 909 //setup trailer
879 memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); 910 num_objects = GUINT64_FROM_BE(num_objects);
880 memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t)); 911 root_object = GUINT64_FROM_BE(root_object);
881 memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t)); 912 offset_table_index = GUINT64_FROM_BE(offset_table_index);
882 913
883 g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE); 914 memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t));
884 915 memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t));
885 //duplicate buffer 916 memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t));
886 *plist_bin = (char *) malloc(bplist_buff->len); 917 memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t));
887 memcpy(*plist_bin, bplist_buff->data, bplist_buff->len); 918 memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t));
888 *length = bplist_buff->len; 919
889 920 g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE);
890 g_byte_array_free(bplist_buff, TRUE); 921
891 free(offsets); 922 //duplicate buffer
923 *plist_bin = (char *) malloc(bplist_buff->len);
924 memcpy(*plist_bin, bplist_buff->data, bplist_buff->len);
925 *length = bplist_buff->len;
926
927 g_byte_array_free(bplist_buff, TRUE);
928 free(offsets);
892} 929}
diff --git a/src/plist.c b/src/plist.c
index 30be007..9628e38 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -28,719 +28,762 @@
28 28
29plist_t plist_new_node(plist_data_t data) 29plist_t plist_new_node(plist_data_t data)
30{ 30{
31 return (plist_t) g_node_new(data); 31 return (plist_t) g_node_new(data);
32} 32}
33 33
34plist_data_t plist_get_data(const plist_t node) 34plist_data_t plist_get_data(const plist_t node)
35{ 35{
36 if (!node) 36 if (!node)
37 return NULL; 37 return NULL;
38 return ((GNode *) node)->data; 38 return ((GNode *) node)->data;
39} 39}
40 40
41plist_data_t plist_new_plist_data(void) 41plist_data_t plist_new_plist_data(void)
42{ 42{
43 plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1); 43 plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1);
44 return data; 44 return data;
45} 45}
46 46
47static void plist_free_data(plist_data_t data) 47static void plist_free_data(plist_data_t data)
48{ 48{
49 if (data) { 49 if (data)
50 switch (data->type) { 50 {
51 case PLIST_KEY: 51 switch (data->type)
52 case PLIST_STRING: 52 {
53 free(data->strval); 53 case PLIST_KEY:
54 break; 54 case PLIST_STRING:
55 case PLIST_DATA: 55 free(data->strval);
56 free(data->buff); 56 break;
57 break; 57 case PLIST_DATA:
58 default: 58 free(data->buff);
59 break; 59 break;
60 } 60 default:
61 free(data); 61 break;
62 } 62 }
63 free(data);
64 }
63} 65}
64 66
65static void plist_free_node(GNode * node, gpointer none) 67static void plist_free_node(GNode * node, gpointer none)
66{ 68{
67 plist_data_t data = NULL; 69 plist_data_t data = NULL;
68 g_node_unlink(node); 70 g_node_unlink(node);
69 data = plist_get_data(node); 71 data = plist_get_data(node);
70 plist_free_data(data); 72 plist_free_data(data);
71 node->data = NULL; 73 node->data = NULL;
72 g_node_children_foreach(node, G_TRAVERSE_ALL, plist_free_node, NULL); 74 g_node_children_foreach(node, G_TRAVERSE_ALL, plist_free_node, NULL);
73} 75}
74 76
75plist_t plist_new_dict(void) 77plist_t plist_new_dict(void)
76{ 78{
77 plist_data_t data = plist_new_plist_data(); 79 plist_data_t data = plist_new_plist_data();
78 data->type = PLIST_DICT; 80 data->type = PLIST_DICT;
79 return plist_new_node(data); 81 return plist_new_node(data);
80} 82}
81 83
82plist_t plist_new_array(void) 84plist_t plist_new_array(void)
83{ 85{
84 plist_data_t data = plist_new_plist_data(); 86 plist_data_t data = plist_new_plist_data();
85 data->type = PLIST_ARRAY; 87 data->type = PLIST_ARRAY;
86 return plist_new_node(data); 88 return plist_new_node(data);
87} 89}
88 90
89//These nodes should not be handled by users 91//These nodes should not be handled by users
90static plist_t plist_new_key(const char *val) 92static plist_t plist_new_key(const char *val)
91{ 93{
92 plist_data_t data = plist_new_plist_data(); 94 plist_data_t data = plist_new_plist_data();
93 data->type = PLIST_KEY; 95 data->type = PLIST_KEY;
94 data->strval = strdup(val); 96 data->strval = strdup(val);
95 data->length = strlen(val); 97 data->length = strlen(val);
96 return plist_new_node(data); 98 return plist_new_node(data);
97} 99}
98 100
99plist_t plist_new_string(const char *val) 101plist_t plist_new_string(const char *val)
100{ 102{
101 plist_data_t data = plist_new_plist_data(); 103 plist_data_t data = plist_new_plist_data();
102 data->type = PLIST_STRING; 104 data->type = PLIST_STRING;
103 data->strval = strdup(val); 105 data->strval = strdup(val);
104 data->length = strlen(val); 106 data->length = strlen(val);
105 return plist_new_node(data); 107 return plist_new_node(data);
106} 108}
107 109
108plist_t plist_new_bool(uint8_t val) 110plist_t plist_new_bool(uint8_t val)
109{ 111{
110 plist_data_t data = plist_new_plist_data(); 112 plist_data_t data = plist_new_plist_data();
111 data->type = PLIST_BOOLEAN; 113 data->type = PLIST_BOOLEAN;
112 data->boolval = val; 114 data->boolval = val;
113 data->length = sizeof(uint8_t); 115 data->length = sizeof(uint8_t);
114 return plist_new_node(data); 116 return plist_new_node(data);
115} 117}
116 118
117plist_t plist_new_uint(uint64_t val) 119plist_t plist_new_uint(uint64_t val)
118{ 120{
119 plist_data_t data = plist_new_plist_data(); 121 plist_data_t data = plist_new_plist_data();
120 data->type = PLIST_UINT; 122 data->type = PLIST_UINT;
121 data->intval = val; 123 data->intval = val;
122 data->length = sizeof(uint64_t); 124 data->length = sizeof(uint64_t);
123 return plist_new_node(data); 125 return plist_new_node(data);
124} 126}
125 127
126plist_t plist_new_real(double val) 128plist_t plist_new_real(double val)
127{ 129{
128 plist_data_t data = plist_new_plist_data(); 130 plist_data_t data = plist_new_plist_data();
129 data->type = PLIST_REAL; 131 data->type = PLIST_REAL;
130 data->realval = val; 132 data->realval = val;
131 data->length = sizeof(double); 133 data->length = sizeof(double);
132 return plist_new_node(data); 134 return plist_new_node(data);
133} 135}
134 136
135plist_t plist_new_data(const char *val, uint64_t length) 137plist_t plist_new_data(const char *val, uint64_t length)
136{ 138{
137 plist_data_t data = plist_new_plist_data(); 139 plist_data_t data = plist_new_plist_data();
138 data->type = PLIST_DATA; 140 data->type = PLIST_DATA;
139 data->buff = (uint8_t *) malloc(length); 141 data->buff = (uint8_t *) malloc(length);
140 memcpy(data->buff, val, length); 142 memcpy(data->buff, val, length);
141 data->length = length; 143 data->length = length;
142 return plist_new_node(data); 144 return plist_new_node(data);
143} 145}
144 146
145plist_t plist_new_date(int32_t sec, int32_t usec) 147plist_t plist_new_date(int32_t sec, int32_t usec)
146{ 148{
147 plist_data_t data = plist_new_plist_data(); 149 plist_data_t data = plist_new_plist_data();
148 data->type = PLIST_DATE; 150 data->type = PLIST_DATE;
149 data->timeval.tv_sec = sec; 151 data->timeval.tv_sec = sec;
150 data->timeval.tv_usec = usec; 152 data->timeval.tv_usec = usec;
151 data->length = sizeof(GTimeVal); 153 data->length = sizeof(GTimeVal);
152 return plist_new_node(data); 154 return plist_new_node(data);
153} 155}
154 156
155void plist_free(plist_t plist) 157void plist_free(plist_t plist)
156{ 158{
157 if (plist) { 159 if (plist)
158 plist_free_node(plist, NULL); 160 {
159 g_node_destroy(plist); 161 plist_free_node(plist, NULL);
160 } 162 g_node_destroy(plist);
163 }
161} 164}
162 165
163static void plist_copy_node(GNode * node, gpointer parent_node_ptr) 166static void plist_copy_node(GNode * node, gpointer parent_node_ptr)
164{ 167{
165 plist_type node_type = PLIST_NONE; 168 plist_type node_type = PLIST_NONE;
166 plist_t newnode = NULL; 169 plist_t newnode = NULL;
167 plist_data_t data = plist_get_data(node); 170 plist_data_t data = plist_get_data(node);
168 plist_data_t newdata = plist_new_plist_data(); 171 plist_data_t newdata = plist_new_plist_data();
169 172
170 assert(data); // plist should always have data 173 assert(data); // plist should always have data
171 174
172 memcpy(newdata, data, sizeof(struct plist_data_s)); 175 memcpy(newdata, data, sizeof(struct plist_data_s));
173 176
174 node_type = plist_get_node_type(node); 177 node_type = plist_get_node_type(node);
175 if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY) { 178 if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY)
176 switch (node_type) { 179 {
177 case PLIST_DATA: 180 switch (node_type)
178 newdata->buff = (uint8_t *) malloc(data->length); 181 {
179 memcpy(newdata->buff, data->buff, data->length); 182 case PLIST_DATA:
180 case PLIST_KEY: 183 newdata->buff = (uint8_t *) malloc(data->length);
181 case PLIST_STRING: 184 memcpy(newdata->buff, data->buff, data->length);
182 newdata->strval = strdup((char *) data->strval); 185 case PLIST_KEY:
183 default: 186 case PLIST_STRING:
184 break; 187 newdata->strval = strdup((char *) data->strval);
185 } 188 default:
186 } 189 break;
187 newnode = plist_new_node(newdata); 190 }
188 191 }
189 if (*(plist_t*)parent_node_ptr) { 192 newnode = plist_new_node(newdata);
190 g_node_append(*(plist_t*)parent_node_ptr, newnode); 193
191 } 194 if (*(plist_t*)parent_node_ptr)
192 else { 195 {
193 *(plist_t*)parent_node_ptr = newnode; 196 g_node_append(*(plist_t*)parent_node_ptr, newnode);
194 } 197 }
195 198 else
196 g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, &newnode); 199 {
200 *(plist_t*)parent_node_ptr = newnode;
201 }
202
203 g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, &newnode);
197} 204}
198 205
199plist_t plist_copy(plist_t node) 206plist_t plist_copy(plist_t node)
200{ 207{
201 plist_t copied = NULL; 208 plist_t copied = NULL;
202 plist_copy_node(node, &copied); 209 plist_copy_node(node, &copied);
203 return copied; 210 return copied;
204} 211}
205 212
206uint32_t plist_array_get_size(plist_t node) 213uint32_t plist_array_get_size(plist_t node)
207{ 214{
208 uint32_t ret = 0; 215 uint32_t ret = 0;
209 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 216 if (node && PLIST_ARRAY == plist_get_node_type(node))
210 ret = g_node_n_children(node); 217 {
211 } 218 ret = g_node_n_children(node);
212 return ret; 219 }
220 return ret;
213} 221}
214 222
215plist_t plist_array_get_item(plist_t node, uint32_t n) 223plist_t plist_array_get_item(plist_t node, uint32_t n)
216{ 224{
217 plist_t ret = NULL; 225 plist_t ret = NULL;
218 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 226 if (node && PLIST_ARRAY == plist_get_node_type(node))
219 ret = (plist_t)g_node_nth_child(node, n); 227 {
220 } 228 ret = (plist_t)g_node_nth_child(node, n);
221 return ret; 229 }
230 return ret;
222} 231}
223 232
224uint32_t plist_array_get_item_index(plist_t node) 233uint32_t plist_array_get_item_index(plist_t node)
225{ 234{
226 plist_t father = plist_get_parent(node); 235 plist_t father = plist_get_parent(node);
227 if (PLIST_ARRAY == plist_get_node_type(father)) { 236 if (PLIST_ARRAY == plist_get_node_type(father))
228 return g_node_child_position(father, node); 237 {
229 } 238 return g_node_child_position(father, node);
239 }
230 return 0; 240 return 0;
231} 241}
232 242
233void plist_array_set_item(plist_t node, plist_t item, uint32_t n) 243void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
234{ 244{
235 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 245 if (node && PLIST_ARRAY == plist_get_node_type(node))
236 plist_t old_item = plist_array_get_item(node, n); 246 {
237 if (old_item) { 247 plist_t old_item = plist_array_get_item(node, n);
238 plist_free_node(old_item, NULL); 248 if (old_item)
239 old_item = NULL; 249 {
240 plist_copy_node(item, &old_item); 250 plist_free_node(old_item, NULL);
241 } 251 old_item = NULL;
242 } 252 plist_copy_node(item, &old_item);
243 return; 253 }
254 }
255 return;
244} 256}
245 257
246void plist_array_append_item(plist_t node, plist_t item) 258void plist_array_append_item(plist_t node, plist_t item)
247{ 259{
248 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 260 if (node && PLIST_ARRAY == plist_get_node_type(node))
249 g_node_append(node, item); 261 {
250 } 262 g_node_append(node, item);
251 return; 263 }
264 return;
252} 265}
253 266
254void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) 267void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
255{ 268{
256 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 269 if (node && PLIST_ARRAY == plist_get_node_type(node))
257 g_node_insert(node, n, item); 270 {
258 } 271 g_node_insert(node, n, item);
259 return; 272 }
273 return;
260} 274}
261 275
262void plist_array_remove_item(plist_t node, uint32_t n) 276void plist_array_remove_item(plist_t node, uint32_t n)
263{ 277{
264 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 278 if (node && PLIST_ARRAY == plist_get_node_type(node))
265 plist_t old_item = plist_array_get_item(node, n); 279 {
266 if (old_item) { 280 plist_t old_item = plist_array_get_item(node, n);
267 plist_free(old_item); 281 if (old_item)
268 } 282 {
269 } 283 plist_free(old_item);
270 return; 284 }
285 }
286 return;
271} 287}
272 288
273uint32_t plist_dict_get_size(plist_t node) 289uint32_t plist_dict_get_size(plist_t node)
274{ 290{
275 uint32_t ret = 0; 291 uint32_t ret = 0;
276 if (node && PLIST_DICT == plist_get_node_type(node)) { 292 if (node && PLIST_DICT == plist_get_node_type(node))
277 ret = g_node_n_children(node) / 2; 293 {
278 } 294 ret = g_node_n_children(node) / 2;
279 return ret; 295 }
296 return ret;
280} 297}
281 298
282void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) 299void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
283{ 300{
284 if (iter && *iter == NULL) { 301 if (iter && *iter == NULL)
285 *iter = malloc(sizeof(uint32_t)); 302 {
286 *((uint32_t*)(*iter)) = 0; 303 *iter = malloc(sizeof(uint32_t));
287 } 304 *((uint32_t*)(*iter)) = 0;
288 return; 305 }
306 return;
289} 307}
290 308
291void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) 309void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
292{ 310{
293 uint32_t* iter_int = (uint32_t*) iter; 311 uint32_t* iter_int = (uint32_t*) iter;
294 312
295 if (key) { 313 if (key)
296 *key = NULL; 314 {
297 } 315 *key = NULL;
298 if (val) { 316 }
299 *val = NULL; 317 if (val)
300 } 318 {
319 *val = NULL;
320 }
301 321
302 if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < g_node_n_children(node)) { 322 if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < g_node_n_children(node))
323 {
303 324
304 if (key) { 325 if (key)
305 plist_get_key_val((plist_t)g_node_nth_child(node, *iter_int), key); 326 {
306 } 327 plist_get_key_val((plist_t)g_node_nth_child(node, *iter_int), key);
328 }
307 329
308 if (val) { 330 if (val)
309 *val = (plist_t) g_node_nth_child(node, *iter_int + 1); 331 {
310 } 332 *val = (plist_t) g_node_nth_child(node, *iter_int + 1);
333 }
311 334
312 *iter_int += 2; 335 *iter_int += 2;
313 } 336 }
314 return; 337 return;
315} 338}
316 339
317void plist_dict_get_item_key(plist_t node, char **key) 340void plist_dict_get_item_key(plist_t node, char **key)
318{ 341{
319 plist_t father = plist_get_parent(node); 342 plist_t father = plist_get_parent(node);
320 if (PLIST_DICT == plist_get_node_type(father)) { 343 if (PLIST_DICT == plist_get_node_type(father))
321 plist_get_key_val( (plist_t) g_node_prev_sibling(node), key); 344 {
322 } 345 plist_get_key_val( (plist_t) g_node_prev_sibling(node), key);
346 }
323} 347}
324 348
325plist_t plist_dict_get_item(plist_t node, const char* key) 349plist_t plist_dict_get_item(plist_t node, const char* key)
326{ 350{
327 plist_t ret = NULL; 351 plist_t ret = NULL;
328 352
329 if (node && PLIST_DICT == plist_get_node_type(node)) { 353 if (node && PLIST_DICT == plist_get_node_type(node))
354 {
330 355
331 plist_t current = NULL; 356 plist_t current = NULL;
332 for (current = (plist_t)g_node_first_child(node); 357 for (current = (plist_t)g_node_first_child(node);
333 current; 358 current;
334 current = (plist_t)g_node_next_sibling(g_node_next_sibling(current))) { 359 current = (plist_t)g_node_next_sibling(g_node_next_sibling(current)))
360 {
335 361
336 plist_data_t data = plist_get_data(current); 362 plist_data_t data = plist_get_data(current);
337 assert( PLIST_KEY == plist_get_node_type(current) ); 363 assert( PLIST_KEY == plist_get_node_type(current) );
338 364
339 if (data && !strcmp(key, data->strval)) { 365 if (data && !strcmp(key, data->strval))
340 ret = (plist_t)g_node_next_sibling(current); 366 {
341 break; 367 ret = (plist_t)g_node_next_sibling(current);
342 } 368 break;
343 } 369 }
344 } 370 }
345 return ret; 371 }
372 return ret;
346} 373}
347 374
348void plist_dict_set_item(plist_t node, const char* key, plist_t item) 375void plist_dict_set_item(plist_t node, const char* key, plist_t item)
349{ 376{
350 if (node && PLIST_DICT == plist_get_node_type(node)) { 377 if (node && PLIST_DICT == plist_get_node_type(node))
351 plist_t old_item = plist_dict_get_item(node, key); 378 {
352 if (old_item) { 379 plist_t old_item = plist_dict_get_item(node, key);
353 plist_free_node(old_item, NULL); 380 if (old_item)
354 old_item = NULL; 381 {
355 plist_copy_node(item, &old_item); 382 plist_free_node(old_item, NULL);
356 } 383 old_item = NULL;
357 } 384 plist_copy_node(item, &old_item);
358 return; 385 }
386 }
387 return;
359} 388}
360 389
361void plist_dict_insert_item(plist_t node, const char* key, plist_t item) 390void plist_dict_insert_item(plist_t node, const char* key, plist_t item)
362{ 391{
363 if (node && PLIST_DICT == plist_get_node_type(node)) { 392 if (node && PLIST_DICT == plist_get_node_type(node))
364 g_node_append(node, plist_new_key(key)); 393 {
365 g_node_append(node, item); 394 g_node_append(node, plist_new_key(key));
366 } 395 g_node_append(node, item);
367 return; 396 }
397 return;
368} 398}
369 399
370void plist_dict_remove_item(plist_t node, const char* key) 400void plist_dict_remove_item(plist_t node, const char* key)
371{ 401{
372 if (node && PLIST_DICT == plist_get_node_type(node)) { 402 if (node && PLIST_DICT == plist_get_node_type(node))
373 plist_t old_item = plist_dict_get_item(node, key); 403 {
374 if (old_item) { 404 plist_t old_item = plist_dict_get_item(node, key);
375 plist_t key_node = g_node_prev_sibling(old_item); 405 if (old_item)
376 plist_free(key_node); 406 {
377 plist_free(old_item); 407 plist_t key_node = g_node_prev_sibling(old_item);
378 } 408 plist_free(key_node);
379 } 409 plist_free(old_item);
380 return; 410 }
411 }
412 return;
381} 413}
382 414
383static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length) 415static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length)
384{ 416{
385 char res = FALSE; 417 char res = FALSE;
386 switch (type) { 418 switch (type)
387 case PLIST_BOOLEAN: 419 {
388 res = data->boolval == *((char *) value) ? TRUE : FALSE; 420 case PLIST_BOOLEAN:
389 break; 421 res = data->boolval == *((char *) value) ? TRUE : FALSE;
390 case PLIST_UINT: 422 break;
391 res = data->intval == *((uint64_t *) value) ? TRUE : FALSE; 423 case PLIST_UINT:
392 break; 424 res = data->intval == *((uint64_t *) value) ? TRUE : FALSE;
393 case PLIST_REAL: 425 break;
394 res = data->realval == *((double *) value) ? TRUE : FALSE; 426 case PLIST_REAL:
395 break; 427 res = data->realval == *((double *) value) ? TRUE : FALSE;
396 case PLIST_KEY: 428 break;
397 case PLIST_STRING: 429 case PLIST_KEY:
398 res = !strcmp(data->strval, ((char *) value)); 430 case PLIST_STRING:
399 break; 431 res = !strcmp(data->strval, ((char *) value));
400 case PLIST_DATA: 432 break;
401 res = !memcmp(data->buff, (char *) value, length); 433 case PLIST_DATA:
402 break; 434 res = !memcmp(data->buff, (char *) value, length);
403 case PLIST_DATE: 435 break;
404 res = !memcmp(&(data->timeval), value, sizeof(GTimeVal)); 436 case PLIST_DATE:
405 break; 437 res = !memcmp(&(data->timeval), value, sizeof(GTimeVal));
406 case PLIST_ARRAY: 438 break;
407 case PLIST_DICT: 439 case PLIST_ARRAY:
408 default: 440 case PLIST_DICT:
409 break; 441 default:
410 } 442 break;
411 return res; 443 }
444 return res;
412} 445}
413 446
414plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) 447plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
415{ 448{
416 plist_t current = plist; 449 plist_t current = plist;
417 plist_type type = PLIST_NONE; 450 plist_type type = PLIST_NONE;
418 uint32_t i = 0; 451 uint32_t i = 0;
419 452
420 for (i = 0; i < length && current; i++) { 453 for (i = 0; i < length && current; i++)
421 type = plist_get_node_type(current); 454 {
422 455 type = plist_get_node_type(current);
423 if (type == PLIST_ARRAY) { 456
424 uint32_t index = va_arg(v, uint32_t); 457 if (type == PLIST_ARRAY)
425 current = plist_array_get_item(current, index); 458 {
426 } 459 uint32_t index = va_arg(v, uint32_t);
427 else if (type == PLIST_DICT) { 460 current = plist_array_get_item(current, index);
428 const char* key = va_arg(v, const char*); 461 }
429 current = plist_dict_get_item(current, key); 462 else if (type == PLIST_DICT)
430 } 463 {
431 } 464 const char* key = va_arg(v, const char*);
432 return current; 465 current = plist_dict_get_item(current, key);
466 }
467 }
468 return current;
433} 469}
434 470
435plist_t plist_access_path(plist_t plist, uint32_t length, ...) 471plist_t plist_access_path(plist_t plist, uint32_t length, ...)
436{ 472{
437 plist_t ret = NULL; 473 plist_t ret = NULL;
438 va_list v; 474 va_list v;
439 475
440 va_start(v, length); 476 va_start(v, length);
441 ret = plist_access_pathv(plist, length, v); 477 ret = plist_access_pathv(plist, length, v);
442 va_end(v); 478 va_end(v);
443 return ret; 479 return ret;
444} 480}
445 481
446static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) 482static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length)
447{ 483{
448 plist_data_t data = NULL; 484 plist_data_t data = NULL;
449 485
450 if (!node) 486 if (!node)
451 return; 487 return;
452 488
453 data = plist_get_data(node); 489 data = plist_get_data(node);
454 490
455 *type = data->type; 491 *type = data->type;
456 *length = data->length; 492 *length = data->length;
457 493
458 switch (*type) { 494 switch (*type)
459 case PLIST_BOOLEAN: 495 {
460 *((char *) value) = data->boolval; 496 case PLIST_BOOLEAN:
461 break; 497 *((char *) value) = data->boolval;
462 case PLIST_UINT: 498 break;
463 *((uint64_t *) value) = data->intval; 499 case PLIST_UINT:
464 break; 500 *((uint64_t *) value) = data->intval;
465 case PLIST_REAL: 501 break;
466 *((double *) value) = data->realval; 502 case PLIST_REAL:
467 break; 503 *((double *) value) = data->realval;
468 case PLIST_KEY: 504 break;
469 case PLIST_STRING: 505 case PLIST_KEY:
470 *((char **) value) = strdup(data->strval); 506 case PLIST_STRING:
471 break; 507 *((char **) value) = strdup(data->strval);
472 case PLIST_DATA: 508 break;
473 *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); 509 case PLIST_DATA:
474 memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); 510 *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t));
475 break; 511 memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t));
476 case PLIST_DATE: 512 break;
477 //exception : here we use memory on the stack since it is just a temporary buffer 513 case PLIST_DATE:
478 ((GTimeVal *) value)->tv_sec = data->timeval.tv_sec; 514 //exception : here we use memory on the stack since it is just a temporary buffer
479 ((GTimeVal *) value)->tv_usec = data->timeval.tv_usec; 515 ((GTimeVal *) value)->tv_sec = data->timeval.tv_sec;
480 break; 516 ((GTimeVal *) value)->tv_usec = data->timeval.tv_usec;
481 case PLIST_ARRAY: 517 break;
482 case PLIST_DICT: 518 case PLIST_ARRAY:
483 default: 519 case PLIST_DICT:
484 break; 520 default:
485 } 521 break;
522 }
486} 523}
487 524
488plist_t plist_get_parent(plist_t node) 525plist_t plist_get_parent(plist_t node)
489{ 526{
490 return node ? (plist_t) ((GNode *) node)->parent : NULL; 527 return node ? (plist_t) ((GNode *) node)->parent : NULL;
491} 528}
492 529
493plist_type plist_get_node_type(plist_t node) 530plist_type plist_get_node_type(plist_t node)
494{ 531{
495 if (node) { 532 if (node)
496 plist_data_t data = plist_get_data(node); 533 {
497 if (data) 534 plist_data_t data = plist_get_data(node);
498 return data->type; 535 if (data)
499 } 536 return data->type;
500 return PLIST_NONE; 537 }
538 return PLIST_NONE;
501} 539}
502 540
503void plist_get_key_val(plist_t node, char **val) 541void plist_get_key_val(plist_t node, char **val)
504{ 542{
505 plist_type type = plist_get_node_type(node); 543 plist_type type = plist_get_node_type(node);
506 uint64_t length = 0; 544 uint64_t length = 0;
507 if (PLIST_KEY == type) 545 if (PLIST_KEY == type)
508 plist_get_type_and_value(node, &type, (void *) val, &length); 546 plist_get_type_and_value(node, &type, (void *) val, &length);
509 assert(length == strlen(*val)); 547 assert(length == strlen(*val));
510} 548}
511 549
512void plist_get_string_val(plist_t node, char **val) 550void plist_get_string_val(plist_t node, char **val)
513{ 551{
514 plist_type type = plist_get_node_type(node); 552 plist_type type = plist_get_node_type(node);
515 uint64_t length = 0; 553 uint64_t length = 0;
516 if (PLIST_STRING == type) 554 if (PLIST_STRING == type)
517 plist_get_type_and_value(node, &type, (void *) val, &length); 555 plist_get_type_and_value(node, &type, (void *) val, &length);
518 assert(length == strlen(*val)); 556 assert(length == strlen(*val));
519} 557}
520 558
521void plist_get_bool_val(plist_t node, uint8_t * val) 559void plist_get_bool_val(plist_t node, uint8_t * val)
522{ 560{
523 plist_type type = plist_get_node_type(node); 561 plist_type type = plist_get_node_type(node);
524 uint64_t length = 0; 562 uint64_t length = 0;
525 if (PLIST_BOOLEAN == type) 563 if (PLIST_BOOLEAN == type)
526 plist_get_type_and_value(node, &type, (void *) val, &length); 564 plist_get_type_and_value(node, &type, (void *) val, &length);
527 assert(length == sizeof(uint8_t)); 565 assert(length == sizeof(uint8_t));
528} 566}
529 567
530void plist_get_uint_val(plist_t node, uint64_t * val) 568void plist_get_uint_val(plist_t node, uint64_t * val)
531{ 569{
532 plist_type type = plist_get_node_type(node); 570 plist_type type = plist_get_node_type(node);
533 uint64_t length = 0; 571 uint64_t length = 0;
534 if (PLIST_UINT == type) 572 if (PLIST_UINT == type)
535 plist_get_type_and_value(node, &type, (void *) val, &length); 573 plist_get_type_and_value(node, &type, (void *) val, &length);
536 assert(length == sizeof(uint64_t)); 574 assert(length == sizeof(uint64_t));
537} 575}
538 576
539void plist_get_real_val(plist_t node, double *val) 577void plist_get_real_val(plist_t node, double *val)
540{ 578{
541 plist_type type = plist_get_node_type(node); 579 plist_type type = plist_get_node_type(node);
542 uint64_t length = 0; 580 uint64_t length = 0;
543 if (PLIST_REAL == type) 581 if (PLIST_REAL == type)
544 plist_get_type_and_value(node, &type, (void *) val, &length); 582 plist_get_type_and_value(node, &type, (void *) val, &length);
545 assert(length == sizeof(double)); 583 assert(length == sizeof(double));
546} 584}
547 585
548void plist_get_data_val(plist_t node, char **val, uint64_t * length) 586void plist_get_data_val(plist_t node, char **val, uint64_t * length)
549{ 587{
550 plist_type type = plist_get_node_type(node); 588 plist_type type = plist_get_node_type(node);
551 if (PLIST_DATA == type) 589 if (PLIST_DATA == type)
552 plist_get_type_and_value(node, &type, (void *) val, length); 590 plist_get_type_and_value(node, &type, (void *) val, length);
553} 591}
554 592
555void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) 593void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
556{ 594{
557 plist_type type = plist_get_node_type(node); 595 plist_type type = plist_get_node_type(node);
558 uint64_t length = 0; 596 uint64_t length = 0;
559 GTimeVal val = { 0, 0 }; 597 GTimeVal val = { 0, 0 };
560 if (PLIST_DATE == type) 598 if (PLIST_DATE == type)
561 plist_get_type_and_value(node, &type, (void *) &val, &length); 599 plist_get_type_and_value(node, &type, (void *) &val, &length);
562 assert(length == sizeof(GTimeVal)); 600 assert(length == sizeof(GTimeVal));
563 *sec = val.tv_sec; 601 *sec = val.tv_sec;
564 *usec = val.tv_usec; 602 *usec = val.tv_usec;
565} 603}
566 604
567gboolean plist_data_compare(gconstpointer a, gconstpointer b) 605gboolean plist_data_compare(gconstpointer a, gconstpointer b)
568{ 606{
569 plist_data_t val_a = NULL; 607 plist_data_t val_a = NULL;
570 plist_data_t val_b = NULL; 608 plist_data_t val_b = NULL;
571 609
572 if (!a || !b) 610 if (!a || !b)
573 return FALSE; 611 return FALSE;
574 612
575 if (!((GNode *) a)->data || !((GNode *) b)->data) 613 if (!((GNode *) a)->data || !((GNode *) b)->data)
576 return FALSE; 614 return FALSE;
577 615
578 val_a = plist_get_data((plist_t) a); 616 val_a = plist_get_data((plist_t) a);
579 val_b = plist_get_data((plist_t) b); 617 val_b = plist_get_data((plist_t) b);
580 618
581 if (val_a->type != val_b->type) 619 if (val_a->type != val_b->type)
582 return FALSE; 620 return FALSE;
583 621
584 switch (val_a->type) { 622 switch (val_a->type)
585 case PLIST_BOOLEAN: 623 {
586 case PLIST_UINT: 624 case PLIST_BOOLEAN:
587 case PLIST_REAL: 625 case PLIST_UINT:
588 if (val_a->intval == val_b->intval) //it is an union so this is sufficient 626 case PLIST_REAL:
589 return TRUE; 627 if (val_a->intval == val_b->intval) //it is an union so this is sufficient
590 else 628 return TRUE;
591 return FALSE; 629 else
592 630 return FALSE;
593 case PLIST_KEY: 631
594 case PLIST_STRING: 632 case PLIST_KEY:
595 if (!strcmp(val_a->strval, val_b->strval)) 633 case PLIST_STRING:
596 return TRUE; 634 if (!strcmp(val_a->strval, val_b->strval))
597 else 635 return TRUE;
598 return FALSE; 636 else
599 637 return FALSE;
600 case PLIST_DATA: 638
601 if (!memcmp(val_a->buff, val_b->buff, val_a->length)) 639 case PLIST_DATA:
602 return TRUE; 640 if (!memcmp(val_a->buff, val_b->buff, val_a->length))
603 else 641 return TRUE;
604 return FALSE; 642 else
605 case PLIST_ARRAY: 643 return FALSE;
606 case PLIST_DICT: 644 case PLIST_ARRAY:
607 //compare pointer 645 case PLIST_DICT:
608 if (a == b) 646 //compare pointer
609 return TRUE; 647 if (a == b)
610 else 648 return TRUE;
611 return FALSE; 649 else
612 break; 650 return FALSE;
613 case PLIST_DATE: 651 break;
614 if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal))) 652 case PLIST_DATE:
615 return TRUE; 653 if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal)))
616 else 654 return TRUE;
617 return FALSE; 655 else
618 default: 656 return FALSE;
619 break; 657 default:
620 } 658 break;
621 return FALSE; 659 }
660 return FALSE;
622} 661}
623 662
624char plist_compare_node_value(plist_t node_l, plist_t node_r) 663char plist_compare_node_value(plist_t node_l, plist_t node_r)
625{ 664{
626 return plist_data_compare(node_l, node_r); 665 return plist_data_compare(node_l, node_r);
627} 666}
628 667
629static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) 668static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length)
630{ 669{
631 //free previous allocated buffer 670 //free previous allocated buffer
632 plist_data_t data = plist_get_data(node); 671 plist_data_t data = plist_get_data(node);
633 assert(data); // a node should always have data attached 672 assert(data); // a node should always have data attached
634 673
635 switch (data->type) { 674 switch (data->type)
636 case PLIST_KEY: 675 {
637 case PLIST_STRING: 676 case PLIST_KEY:
638 free(data->strval); 677 case PLIST_STRING:
639 data->strval = NULL; 678 free(data->strval);
640 break; 679 data->strval = NULL;
641 case PLIST_DATA: 680 break;
642 free(data->buff); 681 case PLIST_DATA:
643 data->buff = NULL; 682 free(data->buff);
644 break; 683 data->buff = NULL;
645 default: 684 break;
646 break; 685 default:
647 } 686 break;
648 687 }
649 //now handle value 688
650 689 //now handle value
651 data->type = type; 690
652 data->length = length; 691 data->type = type;
653 692 data->length = length;
654 switch (type) { 693
655 case PLIST_BOOLEAN: 694 switch (type)
656 data->boolval = *((char *) value); 695 {
657 break; 696 case PLIST_BOOLEAN:
658 case PLIST_UINT: 697 data->boolval = *((char *) value);
659 data->intval = *((uint64_t *) value); 698 break;
660 break; 699 case PLIST_UINT:
661 case PLIST_REAL: 700 data->intval = *((uint64_t *) value);
662 data->realval = *((double *) value); 701 break;
663 break; 702 case PLIST_REAL:
664 case PLIST_KEY: 703 data->realval = *((double *) value);
665 case PLIST_STRING: 704 break;
666 data->strval = strdup((char *) value); 705 case PLIST_KEY:
667 break; 706 case PLIST_STRING:
668 case PLIST_DATA: 707 data->strval = strdup((char *) value);
669 data->buff = (uint8_t *) malloc(length); 708 break;
670 memcpy(data->buff, value, length); 709 case PLIST_DATA:
671 break; 710 data->buff = (uint8_t *) malloc(length);
672 case PLIST_DATE: 711 memcpy(data->buff, value, length);
673 data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; 712 break;
674 data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; 713 case PLIST_DATE:
675 break; 714 data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec;
676 case PLIST_ARRAY: 715 data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec;
677 case PLIST_DICT: 716 break;
678 default: 717 case PLIST_ARRAY:
679 break; 718 case PLIST_DICT:
680 } 719 default:
720 break;
721 }
681} 722}
682 723
683void plist_set_type(plist_t node, plist_type type) 724void plist_set_type(plist_t node, plist_type type)
684{ 725{
685 if ( g_node_n_children(node) == 0 ) { 726 if ( g_node_n_children(node) == 0 )
686 plist_data_t data = plist_get_data(node); 727 {
687 plist_free_data( data ); 728 plist_data_t data = plist_get_data(node);
688 data = plist_new_plist_data(); 729 plist_free_data( data );
689 data->type = type; 730 data = plist_new_plist_data();
690 switch(type){ 731 data->type = type;
691 case PLIST_BOOLEAN: 732 switch (type)
692 data->length = sizeof(uint8_t); 733 {
693 break; 734 case PLIST_BOOLEAN:
694 case PLIST_UINT: 735 data->length = sizeof(uint8_t);
695 data->length = sizeof(uint64_t); 736 break;
696 break; 737 case PLIST_UINT:
697 case PLIST_REAL: 738 data->length = sizeof(uint64_t);
698 data->length = sizeof(double); 739 break;
699 break; 740 case PLIST_REAL:
700 case PLIST_DATE: 741 data->length = sizeof(double);
701 data->length = sizeof(GTimeVal); 742 break;
702 break; 743 case PLIST_DATE:
703 default: 744 data->length = sizeof(GTimeVal);
704 data->length = 0; 745 break;
705 break; 746 default:
706 } 747 data->length = 0;
707 } 748 break;
749 }
750 }
708} 751}
709 752
710void plist_set_key_val(plist_t node, const char *val) 753void plist_set_key_val(plist_t node, const char *val)
711{ 754{
712 plist_set_element_val(node, PLIST_KEY, val, strlen(val)); 755 plist_set_element_val(node, PLIST_KEY, val, strlen(val));
713} 756}
714 757
715void plist_set_string_val(plist_t node, const char *val) 758void plist_set_string_val(plist_t node, const char *val)
716{ 759{
717 plist_set_element_val(node, PLIST_STRING, val, strlen(val)); 760 plist_set_element_val(node, PLIST_STRING, val, strlen(val));
718} 761}
719 762
720void plist_set_bool_val(plist_t node, uint8_t val) 763void plist_set_bool_val(plist_t node, uint8_t val)
721{ 764{
722 plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); 765 plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t));
723} 766}
724 767
725void plist_set_uint_val(plist_t node, uint64_t val) 768void plist_set_uint_val(plist_t node, uint64_t val)
726{ 769{
727 plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t)); 770 plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t));
728} 771}
729 772
730void plist_set_real_val(plist_t node, double val) 773void plist_set_real_val(plist_t node, double val)
731{ 774{
732 plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); 775 plist_set_element_val(node, PLIST_REAL, &val, sizeof(double));
733} 776}
734 777
735void plist_set_data_val(plist_t node, const char *val, uint64_t length) 778void plist_set_data_val(plist_t node, const char *val, uint64_t length)
736{ 779{
737 plist_set_element_val(node, PLIST_DATA, val, length); 780 plist_set_element_val(node, PLIST_DATA, val, length);
738} 781}
739 782
740void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) 783void plist_set_date_val(plist_t node, int32_t sec, int32_t usec)
741{ 784{
742 GTimeVal val = { sec, usec }; 785 GTimeVal val = { sec, usec };
743 plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal)); 786 plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal));
744} 787}
745 788
746//DEPRECATED API BELOW 789//DEPRECATED API BELOW
@@ -748,176 +791,187 @@ void plist_set_date_val(plist_t node, int32_t sec, int32_t usec)
748 791
749static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length) 792static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length)
750{ 793{
751 //only structured types can have children 794 //only structured types can have children
752 plist_type node_type = plist_get_node_type(node); 795 plist_type node_type = plist_get_node_type(node);
753 if (node_type == PLIST_DICT || node_type == PLIST_ARRAY) { 796 if (node_type == PLIST_DICT || node_type == PLIST_ARRAY)
754 //only structured types are allowed to have nulll value 797 {
755 if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY))) { 798 //only structured types are allowed to have nulll value
756 799 if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY)))
757 plist_t subnode = NULL; 800 {
758 801
759 //now handle value 802 plist_t subnode = NULL;
760 plist_data_t data = plist_new_plist_data(); 803
761 data->type = type; 804 //now handle value
762 data->length = length; 805 plist_data_t data = plist_new_plist_data();
763 806 data->type = type;
764 switch (type) { 807 data->length = length;
765 case PLIST_BOOLEAN: 808
766 data->boolval = *((char *) value); 809 switch (type)
767 break; 810 {
768 case PLIST_UINT: 811 case PLIST_BOOLEAN:
769 data->intval = *((uint64_t *) value); 812 data->boolval = *((char *) value);
770 break; 813 break;
771 case PLIST_REAL: 814 case PLIST_UINT:
772 data->realval = *((double *) value); 815 data->intval = *((uint64_t *) value);
773 break; 816 break;
774 case PLIST_KEY: 817 case PLIST_REAL:
775 case PLIST_STRING: 818 data->realval = *((double *) value);
776 data->strval = strdup((char *) value); 819 break;
777 break; 820 case PLIST_KEY:
778 case PLIST_DATA: 821 case PLIST_STRING:
779 data->buff = (uint8_t *) malloc(length); 822 data->strval = strdup((char *) value);
780 memcpy(data->buff, value, length); 823 break;
781 break; 824 case PLIST_DATA:
782 case PLIST_DATE: 825 data->buff = (uint8_t *) malloc(length);
783 data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; 826 memcpy(data->buff, value, length);
784 data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; 827 break;
785 break; 828 case PLIST_DATE:
786 case PLIST_ARRAY: 829 data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec;
787 case PLIST_DICT: 830 data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec;
788 default: 831 break;
789 break; 832 case PLIST_ARRAY:
790 } 833 case PLIST_DICT:
791 834 default:
792 subnode = plist_new_node(data); 835 break;
793 if (node) 836 }
794 g_node_append(node, subnode); 837
795 return subnode; 838 subnode = plist_new_node(data);
796 } else 839 if (node)
797 return NULL; 840 g_node_append(node, subnode);
798 } 841 return subnode;
799 return NULL; 842 }
843 else
844 return NULL;
845 }
846 return NULL;
800} 847}
801 848
802 849
803plist_t plist_get_first_child(plist_t node) 850plist_t plist_get_first_child(plist_t node)
804{ 851{
805 return (plist_t) g_node_first_child((GNode *) node); 852 return (plist_t) g_node_first_child((GNode *) node);
806} 853}
807 854
808plist_t plist_get_next_sibling(plist_t node) 855plist_t plist_get_next_sibling(plist_t node)
809{ 856{
810 return (plist_t) g_node_next_sibling((GNode *) node); 857 return (plist_t) g_node_next_sibling((GNode *) node);
811} 858}
812 859
813plist_t plist_get_prev_sibling(plist_t node) 860plist_t plist_get_prev_sibling(plist_t node)
814{ 861{
815 return (plist_t) g_node_prev_sibling((GNode *) node); 862 return (plist_t) g_node_prev_sibling((GNode *) node);
816} 863}
817 864
818plist_t plist_get_array_nth_el(plist_t node, uint32_t n) 865plist_t plist_get_array_nth_el(plist_t node, uint32_t n)
819{ 866{
820 plist_t ret = NULL; 867 plist_t ret = NULL;
821 if (node && PLIST_ARRAY == plist_get_node_type(node)) { 868 if (node && PLIST_ARRAY == plist_get_node_type(node))
822 uint32_t i = 0; 869 {
823 plist_t temp = plist_get_first_child(node); 870 uint32_t i = 0;
871 plist_t temp = plist_get_first_child(node);
824 872
825 while (i <= n && temp) { 873 while (i <= n && temp)
826 if (i == n) 874 {
827 ret = temp; 875 if (i == n)
828 temp = plist_get_next_sibling(temp); 876 ret = temp;
829 i++; 877 temp = plist_get_next_sibling(temp);
830 } 878 i++;
831 } 879 }
832 return ret; 880 }
881 return ret;
833} 882}
834 883
835plist_t plist_get_dict_el_from_key(plist_t node, const char *key) 884plist_t plist_get_dict_el_from_key(plist_t node, const char *key)
836{ 885{
837 plist_t ret = NULL; 886 plist_t ret = NULL;
838 if (node && PLIST_DICT == plist_get_node_type(node)) { 887 if (node && PLIST_DICT == plist_get_node_type(node))
888 {
839 889
840 plist_t key_node = plist_find_node_by_key(node, key); 890 plist_t key_node = plist_find_node_by_key(node, key);
841 ret = plist_get_next_sibling(key_node); 891 ret = plist_get_next_sibling(key_node);
842 } 892 }
843 return ret; 893 return ret;
844} 894}
845 895
846void plist_add_sub_node(plist_t node, plist_t subnode) 896void plist_add_sub_node(plist_t node, plist_t subnode)
847{ 897{
848 if (node && subnode) { 898 if (node && subnode)
849 plist_type type = plist_get_node_type(node); 899 {
850 if (type == PLIST_DICT || type == PLIST_ARRAY) 900 plist_type type = plist_get_node_type(node);
851 g_node_append(node, subnode); 901 if (type == PLIST_DICT || type == PLIST_ARRAY)
852 } 902 g_node_append(node, subnode);
903 }
853} 904}
854 905
855void plist_add_sub_key_el(plist_t node, const char *val) 906void plist_add_sub_key_el(plist_t node, const char *val)
856{ 907{
857 plist_add_sub_element(node, PLIST_KEY, val, strlen(val)); 908 plist_add_sub_element(node, PLIST_KEY, val, strlen(val));
858} 909}
859 910
860void plist_add_sub_string_el(plist_t node, const char *val) 911void plist_add_sub_string_el(plist_t node, const char *val)
861{ 912{
862 plist_add_sub_element(node, PLIST_STRING, val, strlen(val)); 913 plist_add_sub_element(node, PLIST_STRING, val, strlen(val));
863} 914}
864 915
865void plist_add_sub_bool_el(plist_t node, uint8_t val) 916void plist_add_sub_bool_el(plist_t node, uint8_t val)
866{ 917{
867 plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); 918 plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t));
868} 919}
869 920
870void plist_add_sub_uint_el(plist_t node, uint64_t val) 921void plist_add_sub_uint_el(plist_t node, uint64_t val)
871{ 922{
872 plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t)); 923 plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t));
873} 924}
874 925
875void plist_add_sub_real_el(plist_t node, double val) 926void plist_add_sub_real_el(plist_t node, double val)
876{ 927{
877 plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double)); 928 plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double));
878} 929}
879 930
880void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length) 931void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length)
881{ 932{
882 plist_add_sub_element(node, PLIST_DATA, val, length); 933 plist_add_sub_element(node, PLIST_DATA, val, length);
883} 934}
884 935
885void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) 936void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec)
886{ 937{
887 GTimeVal val = { sec, usec }; 938 GTimeVal val = { sec, usec };
888 plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); 939 plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal));
889} 940}
890 941
891static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) 942static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length)
892{ 943{
893 plist_t current = NULL; 944 plist_t current = NULL;
894 945
895 if (!plist) 946 if (!plist)
896 return NULL; 947 return NULL;
897 948
898 for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { 949 for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current))
950 {
899 951
900 plist_data_t data = plist_get_data(current); 952 plist_data_t data = plist_get_data(current);
901 953
902 if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { 954 if (data->type == type && data->length == length && compare_node_value(type, data, value, length))
903 return current; 955 {
904 } 956 return current;
905 if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { 957 }
906 plist_t sub = plist_find_node(current, type, value, length); 958 if (data->type == PLIST_DICT || data->type == PLIST_ARRAY)
907 if (sub) 959 {
908 return sub; 960 plist_t sub = plist_find_node(current, type, value, length);
909 } 961 if (sub)
910 } 962 return sub;
911 return NULL; 963 }
964 }
965 return NULL;
912} 966}
913 967
914plist_t plist_find_node_by_key(plist_t plist, const char *value) 968plist_t plist_find_node_by_key(plist_t plist, const char *value)
915{ 969{
916 return plist_find_node(plist, PLIST_KEY, value, strlen(value)); 970 return plist_find_node(plist, PLIST_KEY, value, strlen(value));
917} 971}
918 972
919plist_t plist_find_node_by_string(plist_t plist, const char *value) 973plist_t plist_find_node_by_string(plist_t plist, const char *value)
920{ 974{
921 return plist_find_node(plist, PLIST_STRING, value, strlen(value)); 975 return plist_find_node(plist, PLIST_STRING, value, strlen(value));
922} 976}
923 977
diff --git a/src/plist.h b/src/plist.h
index b642d74..b9f12d5 100644
--- a/src/plist.h
+++ b/src/plist.h
@@ -8,15 +8,15 @@
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 21
22#ifndef PLIST_H 22#ifndef PLIST_H
@@ -35,17 +35,19 @@
35#endif 35#endif
36 36
37 37
38struct plist_data_s { 38struct plist_data_s
39 union { 39{
40 char boolval; 40 union
41 uint64_t intval; 41 {
42 double realval; 42 char boolval;
43 char *strval; 43 uint64_t intval;
44 uint8_t *buff; 44 double realval;
45 GTimeVal timeval; 45 char *strval;
46 }; 46 uint8_t *buff;
47 uint64_t length; 47 GTimeVal timeval;
48 plist_type type; 48 };
49 uint64_t length;
50 plist_type type;
49}; 51};
50 52
51typedef struct plist_data_s *plist_data_t; 53typedef struct plist_data_s *plist_data_t;
diff --git a/src/xplist.c b/src/xplist.c
index 490367e..15c9497 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -8,15 +8,15 @@
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 21
22 22
@@ -50,7 +50,7 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
50 50
51 51
52/** Formats a block of text to be a given indentation and width. 52/** Formats a block of text to be a given indentation and width.
53 * 53 *
54 * The total width of the return string will be depth + cols. 54 * The total width of the return string will be depth + cols.
55 * 55 *
56 * @param buf The string to format. 56 * @param buf The string to format.
@@ -61,303 +61,323 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
61 */ 61 */
62static gchar *format_string(const char *buf, int cols, int depth) 62static gchar *format_string(const char *buf, int cols, int depth)
63{ 63{
64 int colw = depth + cols + 1; 64 int colw = depth + cols + 1;
65 int len = strlen(buf); 65 int len = strlen(buf);
66 int nlines = len / cols + 1; 66 int nlines = len / cols + 1;
67 gchar *new_buf = (gchar *) g_malloc0(nlines * colw + depth + 1); 67 gchar *new_buf = (gchar *) g_malloc0(nlines * colw + depth + 1);
68 int i = 0; 68 int i = 0;
69 int j = 0; 69 int j = 0;
70 70
71 assert(cols >= 0); 71 assert(cols >= 0);
72 assert(depth >= 0); 72 assert(depth >= 0);
73 73
74 // Inserts new lines and tabs at appropriate locations 74 // Inserts new lines and tabs at appropriate locations
75 for (i = 0; i < nlines; i++) { 75 for (i = 0; i < nlines; i++)
76 new_buf[i * colw] = '\n'; 76 {
77 for (j = 0; j < depth; j++) 77 new_buf[i * colw] = '\n';
78 new_buf[i * colw + 1 + j] = '\t'; 78 for (j = 0; j < depth; j++)
79 memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, (i + 1) * cols <= len ? cols : len - i * cols); 79 new_buf[i * colw + 1 + j] = '\t';
80 } 80 memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, (i + 1) * cols <= len ? cols : len - i * cols);
81 new_buf[len + (1 + depth) * nlines] = '\n'; 81 }
82 82 new_buf[len + (1 + depth) * nlines] = '\n';
83 // Inserts final row of indentation and termination character 83
84 for (j = 0; j < depth; j++) 84 // Inserts final row of indentation and termination character
85 new_buf[len + (1 + depth) * nlines + 1 + j] = '\t'; 85 for (j = 0; j < depth; j++)
86 new_buf[len + (1 + depth) * nlines + depth + 1] = '\0'; 86 new_buf[len + (1 + depth) * nlines + 1 + j] = '\t';
87 87 new_buf[len + (1 + depth) * nlines + depth + 1] = '\0';
88 return new_buf; 88
89 return new_buf;
89} 90}
90 91
91 92
92 93
93struct xml_node { 94struct xml_node
94 xmlNodePtr xml; 95{
95 uint32_t depth; 96 xmlNodePtr xml;
97 uint32_t depth;
96}; 98};
97 99
98/** Creates a new plist XML document. 100/** Creates a new plist XML document.
99 * 101 *
100 * @return The plist XML document. 102 * @return The plist XML document.
101 */ 103 */
102static xmlDocPtr new_xml_plist(void) 104static xmlDocPtr new_xml_plist(void)
103{ 105{
104 char *plist = strdup(plist_base); 106 char *plist = strdup(plist_base);
105 xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist)); 107 xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist));
106 108
107 if (!plist_xml) 109 if (!plist_xml)
108 return NULL; 110 return NULL;
109 111
110 free(plist); 112 free(plist);
111 113
112 return plist_xml; 114 return plist_xml;
113} 115}
114 116
115static void node_to_xml(GNode * node, gpointer xml_struct) 117static void node_to_xml(GNode * node, gpointer xml_struct)
116{ 118{
117 struct xml_node *xstruct = NULL; 119 struct xml_node *xstruct = NULL;
118 plist_data_t node_data = NULL; 120 plist_data_t node_data = NULL;
119 121
120 xmlNodePtr child_node = NULL; 122 xmlNodePtr child_node = NULL;
121 char isStruct = FALSE; 123 char isStruct = FALSE;
122 124
123 const xmlChar *tag = NULL; 125 const xmlChar *tag = NULL;
124 gchar *val = NULL; 126 gchar *val = NULL;
125 127
126 //for base64 128 //for base64
127 gchar *valtmp = NULL; 129 gchar *valtmp = NULL;
128 130
129 uint32_t i = 0; 131 uint32_t i = 0;
130 132
131 if (!node) 133 if (!node)
132 return; 134 return;
133 135
134 xstruct = (struct xml_node *) xml_struct; 136 xstruct = (struct xml_node *) xml_struct;
135 node_data = plist_get_data(node); 137 node_data = plist_get_data(node);
136 138
137 switch (node_data->type) { 139 switch (node_data->type)
138 case PLIST_BOOLEAN: 140 {
139 { 141 case PLIST_BOOLEAN:
140 if (node_data->boolval) 142 {
141 tag = XPLIST_TRUE; 143 if (node_data->boolval)
142 else 144 tag = XPLIST_TRUE;
143 tag = XPLIST_FALSE; 145 else
144 } 146 tag = XPLIST_FALSE;
145 break; 147 }
146 148 break;
147 case PLIST_UINT: 149
148 tag = XPLIST_INT; 150 case PLIST_UINT:
149 val = g_strdup_printf("%llu", node_data->intval); 151 tag = XPLIST_INT;
150 break; 152 val = g_strdup_printf("%llu", node_data->intval);
151 153 break;
152 case PLIST_REAL: 154
153 tag = XPLIST_REAL; 155 case PLIST_REAL:
154 val = g_strdup_printf("%f", node_data->realval); 156 tag = XPLIST_REAL;
155 break; 157 val = g_strdup_printf("%f", node_data->realval);
156 158 break;
157 case PLIST_STRING: 159
158 tag = XPLIST_STRING; 160 case PLIST_STRING:
159 val = g_strdup(node_data->strval); 161 tag = XPLIST_STRING;
160 break; 162 val = g_strdup(node_data->strval);
161 163 break;
162 case PLIST_KEY: 164
163 tag = XPLIST_KEY; 165 case PLIST_KEY:
164 val = g_strdup((gchar *) node_data->strval); 166 tag = XPLIST_KEY;
165 break; 167 val = g_strdup((gchar *) node_data->strval);
166 168 break;
167 case PLIST_DATA: 169
168 tag = XPLIST_DATA; 170 case PLIST_DATA:
169 if (node_data->length) { 171 tag = XPLIST_DATA;
170 valtmp = g_base64_encode(node_data->buff, node_data->length); 172 if (node_data->length)
171 val = format_string(valtmp, 60, xstruct->depth); 173 {
172 g_free(valtmp); 174 valtmp = g_base64_encode(node_data->buff, node_data->length);
173 } 175 val = format_string(valtmp, 60, xstruct->depth);
174 break; 176 g_free(valtmp);
175 case PLIST_ARRAY: 177 }
176 tag = XPLIST_ARRAY; 178 break;
177 isStruct = TRUE; 179 case PLIST_ARRAY:
178 break; 180 tag = XPLIST_ARRAY;
179 case PLIST_DICT: 181 isStruct = TRUE;
180 tag = XPLIST_DICT; 182 break;
181 isStruct = TRUE; 183 case PLIST_DICT:
182 break; 184 tag = XPLIST_DICT;
183 case PLIST_DATE: 185 isStruct = TRUE;
184 tag = XPLIST_DATE; 186 break;
185 val = g_time_val_to_iso8601(&node_data->timeval); 187 case PLIST_DATE:
186 break; 188 tag = XPLIST_DATE;
187 default: 189 val = g_time_val_to_iso8601(&node_data->timeval);
188 break; 190 break;
189 } 191 default:
190 192 break;
191 for (i = 0; i < xstruct->depth; i++) { 193 }
192 xmlNodeAddContent(xstruct->xml, BAD_CAST("\t")); 194
193 } 195 for (i = 0; i < xstruct->depth; i++)
194 child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val)); 196 {
195 xmlNodeAddContent(xstruct->xml, BAD_CAST("\n")); 197 xmlNodeAddContent(xstruct->xml, BAD_CAST("\t"));
196 g_free(val); 198 }
197 199 child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val));
198 //add return for structured types 200 xmlNodeAddContent(xstruct->xml, BAD_CAST("\n"));
199 if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) 201 g_free(val);
200 xmlNodeAddContent(child_node, BAD_CAST("\n")); 202
201 203 //add return for structured types
202 if (isStruct) { 204 if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
203 struct xml_node child = { child_node, xstruct->depth + 1 }; 205 xmlNodeAddContent(child_node, BAD_CAST("\n"));
204 g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); 206
205 } 207 if (isStruct)
206 //fix indent for structured types 208 {
207 if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) { 209 struct xml_node child = { child_node, xstruct->depth + 1 };
208 210 g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child);
209 for (i = 0; i < xstruct->depth; i++) { 211 }
210 xmlNodeAddContent(child_node, BAD_CAST("\t")); 212 //fix indent for structured types
211 } 213 if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
212 } 214 {
213 215
214 return; 216 for (i = 0; i < xstruct->depth; i++)
217 {
218 xmlNodeAddContent(child_node, BAD_CAST("\t"));
219 }
220 }
221
222 return;
215} 223}
216 224
217static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) 225static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
218{ 226{
219 xmlNodePtr node = NULL; 227 xmlNodePtr node = NULL;
220 plist_data_t data = NULL; 228 plist_data_t data = NULL;
221 plist_t subnode = NULL; 229 plist_t subnode = NULL;
222 230
223 //for string 231 //for string
224 glong len = 0; 232 glong len = 0;
225 int type = 0; 233 int type = 0;
226 234
227 if (!xml_node) 235 if (!xml_node)
228 return; 236 return;
229 237
230 for (node = xml_node->children; node; node = node->next) { 238 for (node = xml_node->children; node; node = node->next)
231 239 {
232 while (node && !xmlStrcmp(node->name, XPLIST_TEXT)) 240
233 node = node->next; 241 while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
234 if (!node) 242 node = node->next;
235 break; 243 if (!node)
236 244 break;
237 data = plist_new_plist_data(); 245
238 subnode = plist_new_node(data); 246 data = plist_new_plist_data();
239 if (*plist_node) 247 subnode = plist_new_node(data);
240 g_node_append(*plist_node, subnode); 248 if (*plist_node)
241 else 249 g_node_append(*plist_node, subnode);
242 *plist_node = subnode; 250 else
243 251 *plist_node = subnode;
244 if (!xmlStrcmp(node->name, XPLIST_TRUE)) { 252
245 data->boolval = TRUE; 253 if (!xmlStrcmp(node->name, XPLIST_TRUE))
246 data->type = PLIST_BOOLEAN; 254 {
247 data->length = 1; 255 data->boolval = TRUE;
248 continue; 256 data->type = PLIST_BOOLEAN;
249 } 257 data->length = 1;
250 258 continue;
251 if (!xmlStrcmp(node->name, XPLIST_FALSE)) { 259 }
252 data->boolval = FALSE; 260
253 data->type = PLIST_BOOLEAN; 261 if (!xmlStrcmp(node->name, XPLIST_FALSE))
254 data->length = 1; 262 {
255 continue; 263 data->boolval = FALSE;
256 } 264 data->type = PLIST_BOOLEAN;
257 265 data->length = 1;
258 if (!xmlStrcmp(node->name, XPLIST_INT)) { 266 continue;
259 xmlChar *strval = xmlNodeGetContent(node); 267 }
260 data->intval = g_ascii_strtoull((char *) strval, NULL, 0); 268
261 data->type = PLIST_UINT; 269 if (!xmlStrcmp(node->name, XPLIST_INT))
262 data->length = 8; 270 {
263 xmlFree(strval); 271 xmlChar *strval = xmlNodeGetContent(node);
264 continue; 272 data->intval = g_ascii_strtoull((char *) strval, NULL, 0);
265 } 273 data->type = PLIST_UINT;
266 274 data->length = 8;
267 if (!xmlStrcmp(node->name, XPLIST_REAL)) { 275 xmlFree(strval);
268 xmlChar *strval = xmlNodeGetContent(node); 276 continue;
269 data->realval = atof((char *) strval); 277 }
270 data->type = PLIST_REAL; 278
271 data->length = 8; 279 if (!xmlStrcmp(node->name, XPLIST_REAL))
272 xmlFree(strval); 280 {
273 continue; 281 xmlChar *strval = xmlNodeGetContent(node);
274 } 282 data->realval = atof((char *) strval);
275 283 data->type = PLIST_REAL;
276 if (!xmlStrcmp(node->name, XPLIST_DATE)) { 284 data->length = 8;
277 xmlChar *strval = xmlNodeGetContent(node); 285 xmlFree(strval);
278 g_time_val_from_iso8601((char *) strval, &data->timeval); 286 continue;
279 data->type = PLIST_DATE; 287 }
280 data->length = sizeof(GTimeVal); 288
281 xmlFree(strval); 289 if (!xmlStrcmp(node->name, XPLIST_DATE))
282 continue; 290 {
283 } 291 xmlChar *strval = xmlNodeGetContent(node);
284 292 g_time_val_from_iso8601((char *) strval, &data->timeval);
285 if (!xmlStrcmp(node->name, XPLIST_STRING)) { 293 data->type = PLIST_DATE;
286 xmlChar *strval = xmlNodeGetContent(node); 294 data->length = sizeof(GTimeVal);
287 len = strlen((char *) strval); 295 xmlFree(strval);
288 type = xmlDetectCharEncoding(strval, len); 296 continue;
289 297 }
290 if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { 298
291 data->strval = strdup((char *) strval); 299 if (!xmlStrcmp(node->name, XPLIST_STRING))
292 data->type = PLIST_STRING; 300 {
293 data->length = strlen(data->strval); 301 xmlChar *strval = xmlNodeGetContent(node);
294 } 302 len = strlen((char *) strval);
295 xmlFree(strval); 303 type = xmlDetectCharEncoding(strval, len);
296 continue; 304
297 } 305 if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
298 306 {
299 if (!xmlStrcmp(node->name, XPLIST_KEY)) { 307 data->strval = strdup((char *) strval);
300 xmlChar *strval = xmlNodeGetContent(node); 308 data->type = PLIST_STRING;
301 data->strval = strdup((char *) strval); 309 data->length = strlen(data->strval);
302 data->type = PLIST_KEY; 310 }
303 data->length = strlen(data->strval); 311 xmlFree(strval);
304 xmlFree(strval); 312 continue;
305 continue; 313 }
306 } 314
307 315 if (!xmlStrcmp(node->name, XPLIST_KEY))
308 if (!xmlStrcmp(node->name, XPLIST_DATA)) { 316 {
309 xmlChar *strval = xmlNodeGetContent(node); 317 xmlChar *strval = xmlNodeGetContent(node);
310 gsize size = 0; 318 data->strval = strdup((char *) strval);
311 guchar *dec = g_base64_decode((char *) strval, &size); 319 data->type = PLIST_KEY;
312 data->buff = (uint8_t *) malloc(size * sizeof(uint8_t)); 320 data->length = strlen(data->strval);
313 memcpy(data->buff, dec, size * sizeof(uint8_t)); 321 xmlFree(strval);
314 g_free(dec); 322 continue;
315 data->length = size; 323 }
316 data->type = PLIST_DATA; 324
317 xmlFree(strval); 325 if (!xmlStrcmp(node->name, XPLIST_DATA))
318 continue; 326 {
319 } 327 xmlChar *strval = xmlNodeGetContent(node);
320 328 gsize size = 0;
321 if (!xmlStrcmp(node->name, XPLIST_ARRAY)) { 329 guchar *dec = g_base64_decode((char *) strval, &size);
322 data->type = PLIST_ARRAY; 330 data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
323 xml_to_node(node, &subnode); 331 memcpy(data->buff, dec, size * sizeof(uint8_t));
324 continue; 332 g_free(dec);
325 } 333 data->length = size;
326 334 data->type = PLIST_DATA;
327 if (!xmlStrcmp(node->name, XPLIST_DICT)) { 335 xmlFree(strval);
328 data->type = PLIST_DICT; 336 continue;
329 xml_to_node(node, &subnode); 337 }
330 continue; 338
331 } 339 if (!xmlStrcmp(node->name, XPLIST_ARRAY))
332 } 340 {
341 data->type = PLIST_ARRAY;
342 xml_to_node(node, &subnode);
343 continue;
344 }
345
346 if (!xmlStrcmp(node->name, XPLIST_DICT))
347 {
348 data->type = PLIST_DICT;
349 xml_to_node(node, &subnode);
350 continue;
351 }
352 }
333} 353}
334 354
335void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) 355void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
336{ 356{
337 xmlDocPtr plist_doc = NULL; 357 xmlDocPtr plist_doc = NULL;
338 xmlNodePtr root_node = NULL; 358 xmlNodePtr root_node = NULL;
339 struct xml_node root = { NULL, 0 }; 359 struct xml_node root = { NULL, 0 };
340 int size = 0; 360 int size = 0;
341 361
342 if (!plist || !plist_xml || *plist_xml) 362 if (!plist || !plist_xml || *plist_xml)
343 return; 363 return;
344 plist_doc = new_xml_plist(); 364 plist_doc = new_xml_plist();
345 root_node = xmlDocGetRootElement(plist_doc); 365 root_node = xmlDocGetRootElement(plist_doc);
346 root.xml = root_node; 366 root.xml = root_node;
347 367
348 node_to_xml(plist, &root); 368 node_to_xml(plist, &root);
349 369
350 xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); 370 xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size);
351 if (size >= 0) 371 if (size >= 0)
352 *length = size; 372 *length = size;
353 xmlFreeDoc(plist_doc); 373 xmlFreeDoc(plist_doc);
354} 374}
355 375
356void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist) 376void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist)
357{ 377{
358 xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length); 378 xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length);
359 xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); 379 xmlNodePtr root_node = xmlDocGetRootElement(plist_doc);
360 380
361 xml_to_node(root_node, plist); 381 xml_to_node(root_node, plist);
362 xmlFreeDoc(plist_doc); 382 xmlFreeDoc(plist_doc);
363} 383}