summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/plist/Array.h40
-rw-r--r--include/plist/Boolean.h30
-rw-r--r--include/plist/Data.h30
-rw-r--r--include/plist/Date.h30
-rw-r--r--include/plist/Dictionary.h48
-rw-r--r--include/plist/Integer.h30
-rw-r--r--include/plist/Node.h38
-rw-r--r--include/plist/Real.h30
-rw-r--r--include/plist/String.h30
-rw-r--r--include/plist/Structure.h32
-rw-r--r--include/plist/Utils.h26
-rw-r--r--include/plist/plist++.h6
-rw-r--r--include/plist/plist.h1388
-rw-r--r--plutil/plutil.c225
-rw-r--r--plutil/plutil.h13
-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
-rw-r--r--test/plist_cmp.c200
-rw-r--r--test/plist_test.c196
32 files changed, 3049 insertions, 2905 deletions
diff --git a/include/plist/Array.h b/include/plist/Array.h
index 8fd07cd..b81e6b1 100644
--- a/include/plist/Array.h
+++ b/include/plist/Array.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__ARRAY_H 22#ifndef PLIST__ARRAY_H
@@ -30,23 +30,23 @@ namespace PList
30 30
31class Array : public Structure 31class Array : public Structure
32{ 32{
33 public : 33public :
34 Array(Node* parent = NULL); 34 Array(Node* parent = NULL);
35 Array(plist_t node, Node* parent = NULL); 35 Array(plist_t node, Node* parent = NULL);
36 Array(Array& a); 36 Array(Array& a);
37 Array& operator=(Array& a); 37 Array& operator=(Array& a);
38 virtual ~Array(); 38 virtual ~Array();
39 39
40 Node* Clone(); 40 Node* Clone();
41 41
42 Node* operator[](unsigned int index); 42 Node* operator[](unsigned int index);
43 void Append(Node* node); 43 void Append(Node* node);
44 void Insert(Node* node, unsigned int pos); 44 void Insert(Node* node, unsigned int pos);
45 void Remove(Node* node); 45 void Remove(Node* node);
46 void Remove(unsigned int pos); 46 void Remove(unsigned int pos);
47 47
48 private : 48private :
49 std::vector<Node*> _array; 49 std::vector<Node*> _array;
50}; 50};
51 51
52}; 52};
diff --git a/include/plist/Boolean.h b/include/plist/Boolean.h
index 149f8da..731eb9e 100644
--- a/include/plist/Boolean.h
+++ b/include/plist/Boolean.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__BOOLEAN_H 22#ifndef PLIST__BOOLEAN_H
@@ -29,18 +29,18 @@ namespace PList
29 29
30class Boolean : public Node 30class Boolean : public Node
31{ 31{
32 public : 32public :
33 Boolean(Node* parent = NULL); 33 Boolean(Node* parent = NULL);
34 Boolean(plist_t node, Node* parent = NULL); 34 Boolean(plist_t node, Node* parent = NULL);
35 Boolean(Boolean& b); 35 Boolean(Boolean& b);
36 Boolean& operator=(Boolean& b); 36 Boolean& operator=(Boolean& b);
37 Boolean(bool b); 37 Boolean(bool b);
38 virtual ~Boolean(); 38 virtual ~Boolean();
39 39
40 Node* Clone(); 40 Node* Clone();
41 41
42 void SetValue(bool b); 42 void SetValue(bool b);
43 bool GetValue(); 43 bool GetValue();
44}; 44};
45 45
46}; 46};
diff --git a/include/plist/Data.h b/include/plist/Data.h
index 59a0096..f8ae715 100644
--- a/include/plist/Data.h
+++ b/include/plist/Data.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__DATA_H 22#ifndef PLIST__DATA_H
@@ -30,18 +30,18 @@ namespace PList
30 30
31class Data : public Node 31class Data : public Node
32{ 32{
33 public : 33public :
34 Data(Node* parent = NULL); 34 Data(Node* parent = NULL);
35 Data(plist_t node, Node* parent = NULL); 35 Data(plist_t node, Node* parent = NULL);
36 Data(Data& d); 36 Data(Data& d);
37 Data& operator=(Data& d); 37 Data& operator=(Data& d);
38 Data(const std::vector<char>& buff); 38 Data(const std::vector<char>& buff);
39 virtual ~Data(); 39 virtual ~Data();
40 40
41 Node* Clone(); 41 Node* Clone();
42 42
43 void SetValue(const std::vector<char>& buff); 43 void SetValue(const std::vector<char>& buff);
44 std::vector<char> GetValue(); 44 std::vector<char> GetValue();
45}; 45};
46 46
47}; 47};
diff --git a/include/plist/Date.h b/include/plist/Date.h
index 9c092ea..dc12233 100644
--- a/include/plist/Date.h
+++ b/include/plist/Date.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__DATE_H 22#ifndef PLIST__DATE_H
@@ -34,18 +34,18 @@ namespace PList
34 34
35class Date : public Node 35class Date : public Node
36{ 36{
37 public : 37public :
38 Date(Node* parent = NULL); 38 Date(Node* parent = NULL);
39 Date(plist_t node, Node* parent = NULL); 39 Date(plist_t node, Node* parent = NULL);
40 Date(Date& d); 40 Date(Date& d);
41 Date& operator=(Date& d); 41 Date& operator=(Date& d);
42 Date(timeval t); 42 Date(timeval t);
43 virtual ~Date(); 43 virtual ~Date();
44 44
45 Node* Clone(); 45 Node* Clone();
46 46
47 void SetValue(timeval t); 47 void SetValue(timeval t);
48 timeval GetValue(); 48 timeval GetValue();
49}; 49};
50 50
51}; 51};
diff --git a/include/plist/Dictionary.h b/include/plist/Dictionary.h
index 38604c8..e43d29e 100644
--- a/include/plist/Dictionary.h
+++ b/include/plist/Dictionary.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__DICTIONARY_H 22#ifndef PLIST__DICTIONARY_H
@@ -31,27 +31,27 @@ namespace PList
31 31
32class Dictionary : public Structure 32class Dictionary : public Structure
33{ 33{
34 public : 34public :
35 Dictionary(Node* parent = NULL); 35 Dictionary(Node* parent = NULL);
36 Dictionary(plist_t node, Node* parent = NULL); 36 Dictionary(plist_t node, Node* parent = NULL);
37 Dictionary(Dictionary& d); 37 Dictionary(Dictionary& d);
38 Dictionary& operator=(Dictionary& d); 38 Dictionary& operator=(Dictionary& d);
39 virtual ~Dictionary(); 39 virtual ~Dictionary();
40 40
41 Node* Clone(); 41 Node* Clone();
42 42
43 typedef std::map<std::string,Node*>::iterator iterator; 43 typedef std::map<std::string,Node*>::iterator iterator;
44 44
45 Node* operator[](const std::string& key); 45 Node* operator[](const std::string& key);
46 iterator Begin(); 46 iterator Begin();
47 iterator End(); 47 iterator End();
48 iterator Find(const std::string& key); 48 iterator Find(const std::string& key);
49 iterator Insert(const std::string& key, Node* node); 49 iterator Insert(const std::string& key, Node* node);
50 void Remove(Node* node); 50 void Remove(Node* node);
51 void Remove(const std::string& key); 51 void Remove(const std::string& key);
52 52
53 private : 53private :
54 std::map<std::string,Node*> _map; 54 std::map<std::string,Node*> _map;
55 55
56 56
57}; 57};
diff --git a/include/plist/Integer.h b/include/plist/Integer.h
index fefcea1..7cdf0df 100644
--- a/include/plist/Integer.h
+++ b/include/plist/Integer.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__INTEGER_H 22#ifndef PLIST__INTEGER_H
@@ -29,18 +29,18 @@ namespace PList
29 29
30class Integer : public Node 30class Integer : public Node
31{ 31{
32 public : 32public :
33 Integer(Node* parent = NULL); 33 Integer(Node* parent = NULL);
34 Integer(plist_t node, Node* parent = NULL); 34 Integer(plist_t node, Node* parent = NULL);
35 Integer(Integer& i); 35 Integer(Integer& i);
36 Integer& operator=(Integer& i); 36 Integer& operator=(Integer& i);
37 Integer(uint64_t i); 37 Integer(uint64_t i);
38 virtual ~Integer(); 38 virtual ~Integer();
39 39
40 Node* Clone(); 40 Node* Clone();
41 41
42 void SetValue(uint64_t i); 42 void SetValue(uint64_t i);
43 uint64_t GetValue(); 43 uint64_t GetValue();
44}; 44};
45 45
46}; 46};
diff --git a/include/plist/Node.h b/include/plist/Node.h
index 6e5411a..7ea6ed9 100644
--- a/include/plist/Node.h
+++ b/include/plist/Node.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__NODE_H 22#ifndef PLIST__NODE_H
@@ -29,22 +29,22 @@ namespace PList
29 29
30class Node 30class Node
31{ 31{
32 public : 32public :
33 virtual ~Node(); 33 virtual ~Node();
34 34
35 virtual Node* Clone() = 0; 35 virtual Node* Clone() = 0;
36 Node * GetParent(); 36 Node * GetParent();
37 void SetParent(Node* parent); 37 void SetParent(Node* parent);
38 38
39 plist_type GetType(); 39 plist_type GetType();
40 plist_t GetPlist(); 40 plist_t GetPlist();
41 41
42 protected: 42protected:
43 Node(Node* parent = NULL); 43 Node(Node* parent = NULL);
44 Node(plist_t node, Node* parent = NULL); 44 Node(plist_t node, Node* parent = NULL);
45 Node(plist_type type, Node* parent = NULL); 45 Node(plist_type type, Node* parent = NULL);
46 plist_t _node; 46 plist_t _node;
47 Node* _parent; 47 Node* _parent;
48}; 48};
49 49
50}; 50};
diff --git a/include/plist/Real.h b/include/plist/Real.h
index 755842e..7d6f8e2 100644
--- a/include/plist/Real.h
+++ b/include/plist/Real.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__REAL_H 22#ifndef PLIST__REAL_H
@@ -29,18 +29,18 @@ namespace PList
29 29
30class Real : public Node 30class Real : public Node
31{ 31{
32 public : 32public :
33 Real(Node* parent = NULL); 33 Real(Node* parent = NULL);
34 Real(plist_t node, Node* parent = NULL); 34 Real(plist_t node, Node* parent = NULL);
35 Real(Real& d); 35 Real(Real& d);
36 Real& operator=(Real& d); 36 Real& operator=(Real& d);
37 Real(double d); 37 Real(double d);
38 virtual ~Real(); 38 virtual ~Real();
39 39
40 Node* Clone(); 40 Node* Clone();
41 41
42 void SetValue(double d); 42 void SetValue(double d);
43 double GetValue(); 43 double GetValue();
44}; 44};
45 45
46}; 46};
diff --git a/include/plist/String.h b/include/plist/String.h
index 58b8619..bd8680d 100644
--- a/include/plist/String.h
+++ b/include/plist/String.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__STRING_H 22#ifndef PLIST__STRING_H
@@ -30,18 +30,18 @@ namespace PList
30 30
31class String : public Node 31class String : public Node
32{ 32{
33 public : 33public :
34 String(Node* parent = NULL); 34 String(Node* parent = NULL);
35 String(plist_t node, Node* parent = NULL); 35 String(plist_t node, Node* parent = NULL);
36 String(String& s); 36 String(String& s);
37 String& operator=(String& s); 37 String& operator=(String& s);
38 String(const std::string& s); 38 String(const std::string& s);
39 virtual ~String(); 39 virtual ~String();
40 40
41 Node* Clone(); 41 Node* Clone();
42 42
43 void SetValue(const std::string& s); 43 void SetValue(const std::string& s);
44 std::string GetValue(); 44 std::string GetValue();
45}; 45};
46 46
47}; 47};
diff --git a/include/plist/Structure.h b/include/plist/Structure.h
index 239a8b8..66d9293 100644
--- a/include/plist/Structure.h
+++ b/include/plist/Structure.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__STRUCTURE_H 22#ifndef PLIST__STRUCTURE_H
@@ -31,23 +31,23 @@ namespace PList
31 31
32class Structure : public Node 32class Structure : public Node
33{ 33{
34 public : 34public :
35 virtual ~Structure(); 35 virtual ~Structure();
36
37 uint32_t GetSize();
36 38
37 uint32_t GetSize(); 39 std::string ToXml();
40 std::vector<char> ToBin();
38 41
39 std::string ToXml(); 42 virtual void Remove(Node* node) = 0;
40 std::vector<char> ToBin();
41 43
42 virtual void Remove(Node* node) = 0; 44protected:
43 45 Structure(Node* parent = NULL);
44 protected: 46 Structure(plist_type type, Node* parent = NULL);
45 Structure(Node* parent = NULL);
46 Structure(plist_type type, Node* parent = NULL);
47 47
48 private: 48private:
49 Structure(Structure& s); 49 Structure(Structure& s);
50 Structure& operator=(const Structure& s); 50 Structure& operator=(const Structure& s);
51}; 51};
52 52
53}; 53};
diff --git a/include/plist/Utils.h b/include/plist/Utils.h
index 4cf6003..52503a0 100644
--- a/include/plist/Utils.h
+++ b/include/plist/Utils.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__UTILS_H 22#ifndef PLIST__UTILS_H
@@ -27,17 +27,17 @@
27 27
28namespace PList 28namespace PList
29{ 29{
30 class Utils 30class Utils
31 { 31{
32 public: 32public:
33 static Node* FromPlist(plist_t node, Node* parent = NULL); 33 static Node* FromPlist(plist_t node, Node* parent = NULL);
34 static Structure* FromXml(const std::string& xml); 34 static Structure* FromXml(const std::string& xml);
35 static Structure* FromBin(const std::vector<char>& bin); 35 static Structure* FromBin(const std::vector<char>& bin);
36 36
37 private: 37private:
38 Utils(); 38 Utils();
39 ~Utils(); 39 ~Utils();
40 }; 40};
41}; 41};
42 42
43#endif // PLIST__UTILS_H 43#endif // PLIST__UTILS_H
diff --git a/include/plist/plist++.h b/include/plist/plist++.h
index 7d59e68..79181c5 100644
--- a/include/plist/plist++.h
+++ b/include/plist/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 LIBPLISTXX_H 22#ifndef LIBPLISTXX_H
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 699a0d6..d3f0836 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -8,22 +8,23 @@
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 LIBPLIST_H 22#ifndef LIBPLIST_H
23#define LIBPLIST_H 23#define LIBPLIST_H
24 24
25#ifdef __cplusplus 25#ifdef __cplusplus
26extern "C" { 26extern "C"
27{
27#endif 28#endif
28 29
29#ifdef _MSC_VER 30#ifdef _MSC_VER
@@ -37,705 +38,706 @@ extern "C" {
37 typedef unsigned __int32 uint32_t; 38 typedef unsigned __int32 uint32_t;
38 typedef unsigned __int64 uint64_t; 39 typedef unsigned __int64 uint64_t;
39 40
40 #ifdef plist_EXPORTS 41#ifdef plist_EXPORTS
41 #define PLIST_API __declspec( dllexport ) 42#define PLIST_API __declspec( dllexport )
42 #else 43#else
43 #define PLIST_API __declspec( dllimport ) 44#define PLIST_API __declspec( dllimport )
44 #endif 45#endif
45#else 46#else
46 #include <stdint.h> 47#include <stdint.h>
47 #define PLIST_API 48#define PLIST_API
48#endif 49#endif
49 50
50#include <sys/types.h> 51#include <sys/types.h>
51#include <stdarg.h> 52#include <stdarg.h>
52 53
53/** 54 /**
54 * \mainpage libplist : A library to handle Apple Property Lists 55 * \mainpage libplist : A library to handle Apple Property Lists
55 * \defgroup PublicAPI Public libplist API 56 * \defgroup PublicAPI Public libplist API
56 */ 57 */
57/*@{*/ 58 /*@{*/
58 59
59 60
60/** 61 /**
61 * The basic plist abstract data type. 62 * The basic plist abstract data type.
62 */ 63 */
63 typedef void *plist_t; 64 typedef void *plist_t;
64 65
65/** 66 /**
66 * The plist dictionary iterator. 67 * The plist dictionary iterator.
67 */ 68 */
68 typedef void *plist_dict_iter; 69 typedef void *plist_dict_iter;
69 70
70/** 71 /**
71 * The enumeration of plist node types. 72 * The enumeration of plist node types.
72 */ 73 */
73 typedef enum { 74 typedef enum
74 PLIST_BOOLEAN, /**< Boolean, scalar type */ 75 {
75 PLIST_UINT, /**< Unsigned integer, scalar type */ 76 PLIST_BOOLEAN, /**< Boolean, scalar type */
76 PLIST_REAL, /**< Real, scalar type */ 77 PLIST_UINT, /**< Unsigned integer, scalar type */
77 PLIST_STRING, /**< ASCII string, scalar type */ 78 PLIST_REAL, /**< Real, scalar type */
78 PLIST_ARRAY, /**< Ordered array, structured type */ 79 PLIST_STRING, /**< ASCII string, scalar type */
79 PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ 80 PLIST_ARRAY, /**< Ordered array, structured type */
80 PLIST_DATE, /**< Date, scalar type */ 81 PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */
81 PLIST_DATA, /**< Binary data, scalar type */ 82 PLIST_DATE, /**< Date, scalar type */
82 PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ 83 PLIST_DATA, /**< Binary data, scalar type */
83 PLIST_NONE /**< No type */ 84 PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */
84 } plist_type; 85 PLIST_NONE /**< No type */
85 86 } plist_type;
86 87
87/******************************************** 88
88 * * 89 /********************************************
89 * Creation & Destruction * 90 * *
90 * * 91 * Creation & Destruction *
91 ********************************************/ 92 * *
92 93 ********************************************/
93/** 94
94 * Create a new root plist_t type #PLIST_DICT 95 /**
95 * 96 * Create a new root plist_t type #PLIST_DICT
96 * @return the created plist 97 *
97 * @sa #plist_type 98 * @return the created plist
98 */ 99 * @sa #plist_type
99 PLIST_API plist_t plist_new_dict(void); 100 */
100 101 PLIST_API plist_t plist_new_dict(void);
101/** 102
102 * Create a new root plist_t type #PLIST_ARRAY 103 /**
103 * 104 * Create a new root plist_t type #PLIST_ARRAY
104 * @return the created plist 105 *
105 * @sa #plist_type 106 * @return the created plist
106 */ 107 * @sa #plist_type
107 PLIST_API plist_t plist_new_array(void); 108 */
108 109 PLIST_API plist_t plist_new_array(void);
109/** 110
110 * Create a new plist_t type #PLIST_STRING 111 /**
111 * 112 * Create a new plist_t type #PLIST_STRING
112 * @param val the sting value, encoded in UTF8. 113 *
113 * @return the created item 114 * @param val the sting value, encoded in UTF8.
114 * @sa #plist_type 115 * @return the created item
115 */ 116 * @sa #plist_type
116 PLIST_API plist_t plist_new_string(const char *val); 117 */
117 118 PLIST_API plist_t plist_new_string(const char *val);
118/** 119
119 * Create a new plist_t type #PLIST_BOOLEAN 120 /**
120 * 121 * Create a new plist_t type #PLIST_BOOLEAN
121 * @param val the boolean value, 0 is false, other values are true. 122 *
122 * @return the created item 123 * @param val the boolean value, 0 is false, other values are true.
123 * @sa #plist_type 124 * @return the created item
124 */ 125 * @sa #plist_type
125 PLIST_API plist_t plist_new_bool(uint8_t val); 126 */
126 127 PLIST_API plist_t plist_new_bool(uint8_t val);
127/** 128
128 * Create a new plist_t type #PLIST_UINT 129 /**
129 * 130 * Create a new plist_t type #PLIST_UINT
130 * @param val the unsigned integer value 131 *
131 * @return the created item 132 * @param val the unsigned integer value
132 * @sa #plist_type 133 * @return the created item
133 */ 134 * @sa #plist_type
134 PLIST_API plist_t plist_new_uint(uint64_t val); 135 */
135 136 PLIST_API plist_t plist_new_uint(uint64_t val);
136/** 137
137 * Create a new plist_t type #PLIST_REAL 138 /**
138 * 139 * Create a new plist_t type #PLIST_REAL
139 * @param val the real value 140 *
140 * @return the created item 141 * @param val the real value
141 * @sa #plist_type 142 * @return the created item
142 */ 143 * @sa #plist_type
143 PLIST_API plist_t plist_new_real(double val); 144 */
144 145 PLIST_API plist_t plist_new_real(double val);
145/** 146
146 * Create a new plist_t type #PLIST_DATA 147 /**
147 * 148 * Create a new plist_t type #PLIST_DATA
148 * @param val the binary buffer 149 *
149 * @param length the length of the buffer 150 * @param val the binary buffer
150 * @return the created item 151 * @param length the length of the buffer
151 * @sa #plist_type 152 * @return the created item
152 */ 153 * @sa #plist_type
153 PLIST_API plist_t plist_new_data(const char *val, uint64_t length); 154 */
154 155 PLIST_API plist_t plist_new_data(const char *val, uint64_t length);
155/** 156
156 * Create a new plist_t type #PLIST_DATE 157 /**
157 * 158 * Create a new plist_t type #PLIST_DATE
158 * @param sec the number of seconds since 01/01/2001 159 *
159 * @param usec the number of microseconds 160 * @param sec the number of seconds since 01/01/2001
160 * @return the created item 161 * @param usec the number of microseconds
161 * @sa #plist_type 162 * @return the created item
162 */ 163 * @sa #plist_type
163 PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec); 164 */
164 165 PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec);
165/** 166
166 * Destruct a plist_t node and all its children recursively 167 /**
167 * 168 * Destruct a plist_t node and all its children recursively
168 * @param plist the plist to free 169 *
169 */ 170 * @param plist the plist to free
170 PLIST_API void plist_free(plist_t plist); 171 */
171 172 PLIST_API void plist_free(plist_t plist);
172/** 173
173 * Return a copy of passed node and it's children 174 /**
174 * 175 * Return a copy of passed node and it's children
175 * @param plist the plist to copy 176 *
176 * @return copied plist 177 * @param plist the plist to copy
177 */ 178 * @return copied plist
178 PLIST_API plist_t plist_copy(plist_t node); 179 */
179 180 PLIST_API plist_t plist_copy(plist_t node);
180 181
181/******************************************** 182
182 * * 183 /********************************************
183 * Array functions * 184 * *
184 * * 185 * Array functions *
185 ********************************************/ 186 * *
186 187 ********************************************/
187/** 188
188 * Get size of a #PLIST_ARRAY node. 189 /**
189 * 190 * Get size of a #PLIST_ARRAY node.
190 * @param node the node of type #PLIST_ARRAY 191 *
191 * @return size of the #PLIST_ARRAY node 192 * @param node the node of type #PLIST_ARRAY
192 */ 193 * @return size of the #PLIST_ARRAY node
193 PLIST_API uint32_t plist_array_get_size(plist_t node); 194 */
194 195 PLIST_API uint32_t plist_array_get_size(plist_t node);
195/** 196
196 * Get the nth item in a #PLIST_ARRAY node. 197 /**
197 * 198 * Get the nth item in a #PLIST_ARRAY node.
198 * @param node the node of type #PLIST_ARRAY 199 *
199 * @param n the index of the item to get. Range is [0, array_size[ 200 * @param node the node of type #PLIST_ARRAY
200 * @return the nth item or NULL if node is not of type #PLIST_ARRAY 201 * @param n the index of the item to get. Range is [0, array_size[
201 */ 202 * @return the nth item or NULL if node is not of type #PLIST_ARRAY
202 PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n); 203 */
203 204 PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n);
204/** 205
205 * Get the index of an item. item must be a member of a #PLIST_ARRAY node. 206 /**
206 * 207 * Get the index of an item. item must be a member of a #PLIST_ARRAY node.
207 * @param node the node 208 *
208 * @return the node index 209 * @param node the node
209 */ 210 * @return the node index
210 PLIST_API uint32_t plist_array_get_item_index(plist_t node); 211 */
211 212 PLIST_API uint32_t plist_array_get_item_index(plist_t node);
212/** 213
213 * Set the nth item in a #PLIST_ARRAY node. 214 /**
214 * The previous item at index n will be freed using #plist_free 215 * Set the nth item in a #PLIST_ARRAY node.
215 * 216 * The previous item at index n will be freed using #plist_free
216 * @param node the node of type #PLIST_ARRAY 217 *
217 * @param item the new item at index n 218 * @param node the node of type #PLIST_ARRAY
218 * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. 219 * @param item the new item at index n
219 */ 220 * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range.
220 PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n); 221 */
221 222 PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n);
222/** 223
223 * Append a new item at the end of a #PLIST_ARRAY node. 224 /**
224 * 225 * Append a new item at the end of a #PLIST_ARRAY node.
225 * @param node the node of type #PLIST_ARRAY 226 *
226 * @param item the new item 227 * @param node the node of type #PLIST_ARRAY
227 */ 228 * @param item the new item
228 PLIST_API void plist_array_append_item(plist_t node, plist_t item); 229 */
229 230 PLIST_API void plist_array_append_item(plist_t node, plist_t item);
230/** 231
231 * Insert a new item at position n in a #PLIST_ARRAY node. 232 /**
232 * 233 * Insert a new item at position n in a #PLIST_ARRAY node.
233 * @param node the node of type #PLIST_ARRAY 234 *
234 * @param item the new item to insert 235 * @param node the node of type #PLIST_ARRAY
235 * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. 236 * @param item the new item to insert
236 */ 237 * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range.
237 PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); 238 */
238 239 PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n);
239/** 240
240 * Remove an existing position in a #PLIST_ARRAY node. 241 /**
241 * Removed position will be freed using #plist_free 242 * Remove an existing position in a #PLIST_ARRAY node.
242 * 243 * Removed position will be freed using #plist_free
243 * @param node the node of type #PLIST_ARRAY 244 *
244 * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. 245 * @param node the node of type #PLIST_ARRAY
245 */ 246 * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range.
246 PLIST_API void plist_array_remove_item(plist_t node, uint32_t n); 247 */
247 248 PLIST_API void plist_array_remove_item(plist_t node, uint32_t n);
248/******************************************** 249
249 * * 250 /********************************************
250 * Dictionary functions * 251 * *
251 * * 252 * Dictionary functions *
252 ********************************************/ 253 * *
253 254 ********************************************/
254/** 255
255 * Get size of a #PLIST_DICT node. 256 /**
256 * 257 * Get size of a #PLIST_DICT node.
257 * @param node the node of type #PLIST_DICT 258 *
258 * @return size of the #PLIST_DICT node 259 * @param node the node of type #PLIST_DICT
259 */ 260 * @return size of the #PLIST_DICT node
260 PLIST_API uint32_t plist_dict_get_size(plist_t node); 261 */
261 262 PLIST_API uint32_t plist_dict_get_size(plist_t node);
262/** 263
263 * Create iterator of a #PLIST_DICT node. 264 /**
264 * The allocated iterator shoult be freed with tandard free function 265 * Create iterator of a #PLIST_DICT node.
265 * 266 * The allocated iterator shoult be freed with tandard free function
266 * @param node the node of type #PLIST_DICT 267 *
267 * @param iter iterator of the #PLIST_DICT node 268 * @param node the node of type #PLIST_DICT
268 */ 269 * @param iter iterator of the #PLIST_DICT node
269 PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); 270 */
270 271 PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter);
271/** 272
272 * Increment iterator of a #PLIST_DICT node. 273 /**
273 * 274 * Increment iterator of a #PLIST_DICT node.
274 * @param node the node of type #PLIST_DICT 275 *
275 * @param iter iterator of the dictionary 276 * @param node the node of type #PLIST_DICT
276 * @param key a location to store the key, or NULL. 277 * @param iter iterator of the dictionary
277 * @param val a location to store the value, or NULL. 278 * @param key a location to store the key, or NULL.
278 */ 279 * @param val a location to store the value, or NULL.
279 PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); 280 */
280 281 PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val);
281/** 282
282 * Get key associated to an item. Item must be member of a dictionary 283 /**
283 * 284 * Get key associated to an item. Item must be member of a dictionary
284 * @param node the node 285 *
285 * @param key a location to store the key. 286 * @param node the node
286 */ 287 * @param key a location to store the key.
287 PLIST_API void plist_dict_get_item_key(plist_t node, char **key); 288 */
288 289 PLIST_API void plist_dict_get_item_key(plist_t node, char **key);
289/** 290
290 * Get the nth item in a #PLIST_DICT node. 291 /**
291 * 292 * Get the nth item in a #PLIST_DICT node.
292 * @param node the node of type #PLIST_DICT 293 *
293 * @param key the identifier of the item to get. 294 * @param node the node of type #PLIST_DICT
294 * @return the item or NULL if node is not of type #PLIST_DICT 295 * @param key the identifier of the item to get.
295 */ 296 * @return the item or NULL if node is not of type #PLIST_DICT
296 PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key); 297 */
297 298 PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key);
298/** 299
299 * Set item identified by key in a #PLIST_DICT node. 300 /**
300 * The previous item at index n will be freed using #plist_free 301 * Set item identified by key in a #PLIST_DICT node.
301 * 302 * The previous item at index n will be freed using #plist_free
302 * @param node the node of type #PLIST_DICT 303 *
303 * @param item the new item associated to key 304 * @param node the node of type #PLIST_DICT
304 * @param key the identifier of the item to get. Assert if identifier is not present. 305 * @param item the new item associated to key
305 */ 306 * @param key the identifier of the item to get. Assert if identifier is not present.
306 PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item); 307 */
307 308 PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item);
308/** 309
309 * Insert a new item at position n in a #PLIST_DICT node. 310 /**
310 * 311 * Insert a new item at position n in a #PLIST_DICT node.
311 * @param node the node of type #PLIST_DICT 312 *
312 * @param item the new item to insert 313 * @param node the node of type #PLIST_DICT
313 * @param key The identifier of the item to insert. Assert if identifier already present. 314 * @param item the new item to insert
314 */ 315 * @param key The identifier of the item to insert. Assert if identifier already present.
315 PLIST_API void plist_dict_insert_item(plist_t node, const char* key, plist_t item); 316 */
316 317 PLIST_API void plist_dict_insert_item(plist_t node, const char* key, plist_t item);
317/** 318
318 * Remove an existing position in a #PLIST_DICT node. 319 /**
319 * Removed position will be freed using #plist_free 320 * Remove an existing position in a #PLIST_DICT node.
320 * 321 * Removed position will be freed using #plist_free
321 * @param node the node of type #PLIST_DICT 322 *
322 * @param key The identifier of the item to remove. Assert if identifier is not present. 323 * @param node the node of type #PLIST_DICT
323 */ 324 * @param key The identifier of the item to remove. Assert if identifier is not present.
324 PLIST_API void plist_dict_remove_item(plist_t node, const char* key); 325 */
325 326 PLIST_API void plist_dict_remove_item(plist_t node, const char* key);
326 327
327/******************************************** 328
328 * * 329 /********************************************
329 * Getters * 330 * *
330 * * 331 * Getters *
331 ********************************************/ 332 * *
332 333 ********************************************/
333/** 334
334 * Get the parent of a node 335 /**
335 * 336 * Get the parent of a node
336 * @param node the parent (NULL if node is root) 337 *
337 */ 338 * @param node the parent (NULL if node is root)
338 PLIST_API plist_t plist_get_parent(plist_t node); 339 */
339 340 PLIST_API plist_t plist_get_parent(plist_t node);
340/** 341
341 * Get the #plist_type of a node. 342 /**
342 * 343 * Get the #plist_type of a node.
343 * @param node the node 344 *
344 * @return the type of the node 345 * @param node the node
345 */ 346 * @return the type of the node
346 PLIST_API plist_type plist_get_node_type(plist_t node); 347 */
347 348 PLIST_API plist_type plist_get_node_type(plist_t node);
348/** 349
349 * Get the value of a #PLIST_KEY node. 350 /**
350 * This function does nothing if node is not of type #PLIST_KEY 351 * Get the value of a #PLIST_KEY node.
351 * 352 * This function does nothing if node is not of type #PLIST_KEY
352 * @param node the node 353 *
353 * @param val a pointer to a C-string. This function allocates the memory, 354 * @param node the node
354 * caller is responsible for freeing it. 355 * @param val a pointer to a C-string. This function allocates the memory,
355 */ 356 * caller is responsible for freeing it.
356 PLIST_API void plist_get_key_val(plist_t node, char **val); 357 */
357 358 PLIST_API void plist_get_key_val(plist_t node, char **val);
358/** 359
359 * Get the value of a #PLIST_STRING node. 360 /**
360 * This function does nothing if node is not of type #PLIST_STRING 361 * Get the value of a #PLIST_STRING node.
361 * 362 * This function does nothing if node is not of type #PLIST_STRING
362 * @param node the node 363 *
363 * @param val a pointer to a C-string. This function allocates the memory, 364 * @param node the node
364 * caller is responsible for freeing it. Data is UTF-8 encoded. 365 * @param val a pointer to a C-string. This function allocates the memory,
365 */ 366 * caller is responsible for freeing it. Data is UTF-8 encoded.
366 PLIST_API void plist_get_string_val(plist_t node, char **val); 367 */
367 368 PLIST_API void plist_get_string_val(plist_t node, char **val);
368/** 369
369 * Get the value of a #PLIST_BOOLEAN node. 370 /**
370 * This function does nothing if node is not of type #PLIST_BOOLEAN 371 * Get the value of a #PLIST_BOOLEAN node.
371 * 372 * This function does nothing if node is not of type #PLIST_BOOLEAN
372 * @param node the node 373 *
373 * @param val a pointer to a uint8_t variable. 374 * @param node the node
374 */ 375 * @param val a pointer to a uint8_t variable.
375 PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val); 376 */
376 377 PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val);
377/** 378
378 * Get the value of a #PLIST_UINT node. 379 /**
379 * This function does nothing if node is not of type #PLIST_UINT 380 * Get the value of a #PLIST_UINT node.
380 * 381 * This function does nothing if node is not of type #PLIST_UINT
381 * @param node the node 382 *
382 * @param val a pointer to a uint64_t variable. 383 * @param node the node
383 */ 384 * @param val a pointer to a uint64_t variable.
384 PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val); 385 */
385 386 PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val);
386/** 387
387 * Get the value of a #PLIST_REAL node. 388 /**
388 * This function does nothing if node is not of type #PLIST_REAL 389 * Get the value of a #PLIST_REAL node.
389 * 390 * This function does nothing if node is not of type #PLIST_REAL
390 * @param node the node 391 *
391 * @param val a pointer to a double variable. 392 * @param node the node
392 */ 393 * @param val a pointer to a double variable.
393 PLIST_API void plist_get_real_val(plist_t node, double *val); 394 */
394 395 PLIST_API void plist_get_real_val(plist_t node, double *val);
395/** 396
396 * Get the value of a #PLIST_DATA node. 397 /**
397 * This function does nothing if node is not of type #PLIST_DATA 398 * Get the value of a #PLIST_DATA node.
398 * 399 * This function does nothing if node is not of type #PLIST_DATA
399 * @param node the node 400 *
400 * @param val a pointer to an unallocated char buffer. This function allocates the memory, 401 * @param node the node
401 * caller is responsible for freeing it. 402 * @param val a pointer to an unallocated char buffer. This function allocates the memory,
402 */ 403 * caller is responsible for freeing it.
403 PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length); 404 */
404 405 PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length);
405/** 406
406 * Get the value of a #PLIST_DATE node. 407 /**
407 * This function does nothing if node is not of type #PLIST_DATE 408 * Get the value of a #PLIST_DATE node.
408 * 409 * This function does nothing if node is not of type #PLIST_DATE
409 * @param node the node 410 *
410 * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001. 411 * @param node the node
411 * @param usec a pointer to an int32_t variable. Represents the number of microseconds 412 * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001.
412 */ 413 * @param usec a pointer to an int32_t variable. Represents the number of microseconds
413 PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); 414 */
414 415 PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec);
415 416
416/******************************************** 417
417 * * 418 /********************************************
418 * Setters * 419 * *
419 * * 420 * Setters *
420 ********************************************/ 421 * *
421 422 ********************************************/
422/** 423
423 * Forces type of node. Changing type of structured nodes is only allowed if node is empty. 424 /**
424 * Reset value of node; 425 * Forces type of node. Changing type of structured nodes is only allowed if node is empty.
425 * @param node the node 426 * Reset value of node;
426 * @param type the key value 427 * @param node the node
427 */ 428 * @param type the key value
428 PLIST_API void plist_set_type(plist_t node, plist_type type); 429 */
429 430 PLIST_API void plist_set_type(plist_t node, plist_type type);
430/** 431
431 * Set the value of a node. 432 /**
432 * Forces type of node to #PLIST_KEY 433 * Set the value of a node.
433 * 434 * Forces type of node to #PLIST_KEY
434 * @param node the node 435 *
435 * @param val the key value 436 * @param node the node
436 */ 437 * @param val the key value
437 PLIST_API void plist_set_key_val(plist_t node, const char *val); 438 */
438 439 PLIST_API void plist_set_key_val(plist_t node, const char *val);
439/** 440
440 * Set the value of a node. 441 /**
441 * Forces type of node to #PLIST_STRING 442 * Set the value of a node.
442 * 443 * Forces type of node to #PLIST_STRING
443 * @param node the node 444 *
444 * @param val the string value 445 * @param node the node
445 */ 446 * @param val the string value
446 PLIST_API void plist_set_string_val(plist_t node, const char *val); 447 */
447 448 PLIST_API void plist_set_string_val(plist_t node, const char *val);
448/** 449
449 * Set the value of a node. 450 /**
450 * Forces type of node to #PLIST_BOOLEAN 451 * Set the value of a node.
451 * 452 * Forces type of node to #PLIST_BOOLEAN
452 * @param node the node 453 *
453 * @param val the boolean value 454 * @param node the node
454 */ 455 * @param val the boolean value
455 PLIST_API void plist_set_bool_val(plist_t node, uint8_t val); 456 */
456 457 PLIST_API void plist_set_bool_val(plist_t node, uint8_t val);
457/** 458
458 * Set the value of a node. 459 /**
459 * Forces type of node to #PLIST_UINT 460 * Set the value of a node.
460 * 461 * Forces type of node to #PLIST_UINT
461 * @param node the node 462 *
462 * @param val the unsigned integer value 463 * @param node the node
463 */ 464 * @param val the unsigned integer value
464 PLIST_API void plist_set_uint_val(plist_t node, uint64_t val); 465 */
465 466 PLIST_API void plist_set_uint_val(plist_t node, uint64_t val);
466/** 467
467 * Set the value of a node. 468 /**
468 * Forces type of node to #PLIST_REAL 469 * Set the value of a node.
469 * 470 * Forces type of node to #PLIST_REAL
470 * @param node the node 471 *
471 * @param val the real value 472 * @param node the node
472 */ 473 * @param val the real value
473 PLIST_API void plist_set_real_val(plist_t node, double val); 474 */
474 475 PLIST_API void plist_set_real_val(plist_t node, double val);
475/** 476
476 * Set the value of a node. 477 /**
477 * Forces type of node to #PLIST_DATA 478 * Set the value of a node.
478 * 479 * Forces type of node to #PLIST_DATA
479 * @param node the node 480 *
480 * @param val the binary buffer 481 * @param node the node
481 * @param length the length of the buffer 482 * @param val the binary buffer
482 */ 483 * @param length the length of the buffer
483 PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length); 484 */
484 485 PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length);
485/** 486
486 * Set the value of a node. 487 /**
487 * Forces type of node to #PLIST_DATE 488 * Set the value of a node.
488 * 489 * Forces type of node to #PLIST_DATE
489 * @param node the node 490 *
490 * @param sec the number of seconds since 01/01/2001 491 * @param node the node
491 * @param usec the number of microseconds 492 * @param sec the number of seconds since 01/01/2001
492 */ 493 * @param usec the number of microseconds
493 PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); 494 */
494 495 PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec);
495 496
496/******************************************** 497
497 * * 498 /********************************************
498 * Import & Export * 499 * *
499 * * 500 * Import & Export *
500 ********************************************/ 501 * *
501 502 ********************************************/
502/** 503
503 * Export the #plist_t structure to XML format. 504 /**
504 * 505 * Export the #plist_t structure to XML format.
505 * @param plist the root node to export 506 *
506 * @param plist_xml a pointer to a C-string. This function allocates the memory, 507 * @param plist the root node to export
507 * caller is responsible for freeing it. Data is UTF-8 encoded. 508 * @param plist_xml a pointer to a C-string. This function allocates the memory,
508 * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. 509 * caller is responsible for freeing it. Data is UTF-8 encoded.
509 */ 510 * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer.
510 PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); 511 */
511 512 PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length);
512/** 513
513 * Export the #plist_t structure to binary format. 514 /**
514 * 515 * Export the #plist_t structure to binary format.
515 * @param plist the root node to export 516 *
516 * @param plist_bin a pointer to a char* buffer. This function allocates the memory, 517 * @param plist the root node to export
517 * caller is responsible for freeing it. 518 * @param plist_bin a pointer to a char* buffer. This function allocates the memory,
518 * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. 519 * caller is responsible for freeing it.
519 */ 520 * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer.
520 PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); 521 */
521 522 PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length);
522/** 523
523 * Import the #plist_t structure from XML format. 524 /**
524 * 525 * Import the #plist_t structure from XML format.
525 * @param plist_xml a pointer to the xml buffer. 526 *
526 * @param length length of the buffer to read. 527 * @param plist_xml a pointer to the xml buffer.
527 * @param plist a pointer to the imported plist. 528 * @param length length of the buffer to read.
528 */ 529 * @param plist a pointer to the imported plist.
529 PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); 530 */
530 531 PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist);
531/** 532
532 * Import the #plist_t structure from binary format. 533 /**
533 * 534 * Import the #plist_t structure from binary format.
534 * @param plist_bin a pointer to the xml buffer. 535 *
535 * @param length length of the buffer to read. 536 * @param plist_bin a pointer to the xml buffer.
536 * @param plist a pointer to the imported plist. 537 * @param length length of the buffer to read.
537 */ 538 * @param plist a pointer to the imported plist.
538 PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); 539 */
539 540 PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist);
540 541
541/******************************************** 542
542 * * 543 /********************************************
543 * Utils * 544 * *
544 * * 545 * Utils *
545 ********************************************/ 546 * *
546 547 ********************************************/
547/** 548
548 * Get a node from its path. Each path element depends on the associated father node type. 549 /**
549 * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t 550 * Get a node from its path. Each path element depends on the associated father node type.
550 * Search is breath first order. 551 * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t
551 * 552 * Search is breath first order.
552 * @param plist the node to access result from. 553 *
553 * @param length length of the path to access 554 * @param plist the node to access result from.
554 * @return the value to access. 555 * @param length length of the path to access
555 */ 556 * @return the value to access.
556 PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...); 557 */
557 558 PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...);
558/** 559
559 * Variadic version of #plist_access_path. 560 /**
560 * 561 * Variadic version of #plist_access_path.
561 * @param plist the node to access result from. 562 *
562 * @param length length of the path to access 563 * @param plist the node to access result from.
563 * @param v list of array's index and dic'st key 564 * @param length length of the path to access
564 * @return the value to access. 565 * @param v list of array's index and dic'st key
565 */ 566 * @return the value to access.
566 PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); 567 */
567 568 PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v);
568/** 569
569 * Compare two node values 570 /**
570 * 571 * Compare two node values
571 * @param node_l left node to compare 572 *
572 * @param node_r rigth node to compare 573 * @param node_l left node to compare
573 * @return TRUE is type and value match, FALSE otherwise. 574 * @param node_r rigth node to compare
574 */ 575 * @return TRUE is type and value match, FALSE otherwise.
575 PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r); 576 */
577 PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r);
576 578
577 579
578//DEPRECATED API BELOW 580//DEPRECATED API BELOW
579 581
580/*@}*/ 582 /*@}*/
581/** 583 /**
582 * \defgroup DeprecatedAPI Deprecated libplist API 584 * \defgroup DeprecatedAPI Deprecated libplist API
583 */ 585 */
584/*@{*/ 586 /*@{*/
585 587
586/******************************************** 588 /********************************************
587 * * 589 * *
588 * Tree navigation * 590 * Tree navigation *
589 * * 591 * *
590 ********************************************/ 592 ********************************************/
591 593
592/** 594 /**
593 * Get the first child of a node 595 * Get the first child of a node
594 * 596 *
595 * @param node the first child 597 * @param node the first child
596 */ 598 */
597 PLIST_API plist_t plist_get_first_child(plist_t node); 599 PLIST_API plist_t plist_get_first_child(plist_t node);
598 600
599/** 601 /**
600 * Get the next sibling of a node 602 * Get the next sibling of a node
601 * 603 *
602 * @param node the next sibling 604 * @param node the next sibling
603 */ 605 */
604 PLIST_API plist_t plist_get_next_sibling(plist_t node); 606 PLIST_API plist_t plist_get_next_sibling(plist_t node);
605 607
606/** 608 /**
607 * Get the previous sibling of a node 609 * Get the previous sibling of a node
608 * 610 *
609 * @param node the previous sibling 611 * @param node the previous sibling
610 */ 612 */
611 PLIST_API plist_t plist_get_prev_sibling(plist_t node); 613 PLIST_API plist_t plist_get_prev_sibling(plist_t node);
612 614
613/** 615 /**
614 * Get the nth child of a #PLIST_ARRAY node. 616 * Get the nth child of a #PLIST_ARRAY node.
615 * 617 *
616 * @param node the node of type #PLIST_ARRAY 618 * @param node the node of type #PLIST_ARRAY
617 * @param n the index of the child to get. Range is [0, array_size[ 619 * @param n the index of the child to get. Range is [0, array_size[
618 * @return the nth children or NULL if node is not of type #PLIST_ARRAY 620 * @return the nth children or NULL if node is not of type #PLIST_ARRAY
619 */ 621 */
620 PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n); 622 PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n);
621 623
622/** 624 /**
623 * Get the child of a #PLIST_DICT node from the associated key value. 625 * Get the child of a #PLIST_DICT node from the associated key value.
624 * 626 *
625 * @param node the node of type #PLIST_DICT 627 * @param node the node of type #PLIST_DICT
626 * @param key the key associated to the requested value 628 * @param key the key associated to the requested value
627 * @return the key associated value or NULL if node is not of type #PLIST_DICT 629 * @return the key associated value or NULL if node is not of type #PLIST_DICT
628 */ 630 */
629 PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key); 631 PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key);
630 632
631 633
632/******************************************** 634 /********************************************
633 * * 635 * *
634 * Setters * 636 * Setters *
635 * * 637 * *
636 ********************************************/ 638 ********************************************/
637 639
638/** 640 /**
639 * Add a subnode to a node. The node must be of a structured type 641 * Add a subnode to a node. The node must be of a structured type
640 * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently 642 * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently
641 * if subnode already has a father. 643 * if subnode already has a father.
642 * 644 *
643 * @param node the node to add a children to 645 * @param node the node to add a children to
644 * @param subnode the children node 646 * @param subnode the children node
645 */ 647 */
646 PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode); 648 PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode);
647 649
648/** 650 /**
649 * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type 651 * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type
650 * (ie #PLIST_DICT or #PLIST_ARRAY). 652 * (ie #PLIST_DICT or #PLIST_ARRAY).
651 * 653 *
652 * @param node the node to add a children to 654 * @param node the node to add a children to
653 * @param val the key value encoded as an ASCII string (must be null terminated) 655 * @param val the key value encoded as an ASCII string (must be null terminated)
654 */ 656 */
655 PLIST_API void plist_add_sub_key_el(plist_t node, const char *val); 657 PLIST_API void plist_add_sub_key_el(plist_t node, const char *val);
656 658
657/** 659 /**
658 * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type 660 * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type
659 * (ie #PLIST_DICT or #PLIST_ARRAY). 661 * (ie #PLIST_DICT or #PLIST_ARRAY).
660 * 662 *
661 * @param node the node to add a children to 663 * @param node the node to add a children to
662 * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated) 664 * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated)
663 */ 665 */
664 PLIST_API void plist_add_sub_string_el(plist_t node, const char *val); 666 PLIST_API void plist_add_sub_string_el(plist_t node, const char *val);
665 667
666/** 668 /**
667 * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type 669 * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type
668 * (ie #PLIST_DICT or #PLIST_ARRAY). 670 * (ie #PLIST_DICT or #PLIST_ARRAY).
669 * 671 *
670 * @param node the node to add a children to 672 * @param node the node to add a children to
671 * @param val the boolean value (TRUE or FALSE) 673 * @param val the boolean value (TRUE or FALSE)
672 */ 674 */
673 PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val); 675 PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val);
674 676
675/** 677 /**
676 * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type 678 * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type
677 * (ie #PLIST_DICT or #PLIST_ARRAY). 679 * (ie #PLIST_DICT or #PLIST_ARRAY).
678 * 680 *
679 * @param node the node to add a children to 681 * @param node the node to add a children to
680 * @param val the unsigned integer value 682 * @param val the unsigned integer value
681 */ 683 */
682 PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val); 684 PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val);
683 685
684/** 686 /**
685 * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type 687 * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type
686 * (ie #PLIST_DICT or #PLIST_ARRAY). 688 * (ie #PLIST_DICT or #PLIST_ARRAY).
687 * 689 *
688 * @param node the node to add a children to 690 * @param node the node to add a children to
689 * @param val the real value 691 * @param val the real value
690 */ 692 */
691 PLIST_API void plist_add_sub_real_el(plist_t node, double val); 693 PLIST_API void plist_add_sub_real_el(plist_t node, double val);
692 694
693/** 695 /**
694 * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type 696 * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type
695 * (ie #PLIST_DICT or #PLIST_ARRAY). 697 * (ie #PLIST_DICT or #PLIST_ARRAY).
696 * 698 *
697 * @param node the node to add a children to 699 * @param node the node to add a children to
698 * @param val the binary buffer 700 * @param val the binary buffer
699 * @param length the length of the buffer 701 * @param length the length of the buffer
700 */ 702 */
701 PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length); 703 PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length);
702 704
703/** 705 /**
704 * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type 706 * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type
705 * (ie #PLIST_DICT or #PLIST_ARRAY). 707 * (ie #PLIST_DICT or #PLIST_ARRAY).
706 * 708 *
707 * @param node the node to add a children to 709 * @param node the node to add a children to
708 * @param sec the number of seconds since 01/01/2001 710 * @param sec the number of seconds since 01/01/2001
709 * @param usec the number of microseconds 711 * @param usec the number of microseconds
710 */ 712 */
711 PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); 713 PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec);
712 714
713 715
714/******************************************** 716 /********************************************
715 * * 717 * *
716 * Utils * 718 * Utils *
717 * * 719 * *
718 ********************************************/ 720 ********************************************/
719 721
720/** 722 /**
721 * Find the first encountered #PLIST_KEY node mathing that key. 723 * Find the first encountered #PLIST_KEY node mathing that key.
722 * Search is breath first order. 724 * Search is breath first order.
723 * 725 *
724 * @param plist the root node of the plist structure. 726 * @param plist the root node of the plist structure.
725 * @param value the ASCII Key to match. 727 * @param value the ASCII Key to match.
726 */ 728 */
727 PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); 729 PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value);
728 730
729/** 731 /**
730 * Find the first encountered #PLIST_STRING node mathing that string. 732 * Find the first encountered #PLIST_STRING node mathing that string.
731 * Search is breath first order. 733 * Search is breath first order.
732 * 734 *
733 * @param plist the root node of the plist structure. 735 * @param plist the root node of the plist structure.
734 * @param value the ASCII String to match. 736 * @param value the ASCII String to match.
735 */ 737 */
736 PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); 738 PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value);
737 739
738/*@}*/ 740 /*@}*/
739 741
740 742
741#ifdef __cplusplus 743#ifdef __cplusplus
diff --git a/plutil/plutil.c b/plutil/plutil.c
index 75cd3f1..e9eaef1 100644
--- a/plutil/plutil.c
+++ b/plutil/plutil.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
@@ -35,114 +35,129 @@
35 35
36int main(int argc, char *argv[]) 36int main(int argc, char *argv[])
37{ 37{
38 FILE *iplist = NULL; 38 FILE *iplist = NULL;
39 plist_t root_node = NULL; 39 plist_t root_node = NULL;
40 char *plist_out = NULL; 40 char *plist_out = NULL;
41 int size = 0; 41 int size = 0;
42 char *plist_entire = NULL; 42 char *plist_entire = NULL;
43 struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); 43 struct stat *filestats = (struct stat *) malloc(sizeof(struct stat));
44 Options *options = parse_arguments(argc, argv); 44 Options *options = parse_arguments(argc, argv);
45 45
46 if (!options) { 46 if (!options)
47 print_usage(); 47 {
48 free(filestats); 48 print_usage();
49 return 0; 49 free(filestats);
50 } 50 return 0;
51 //read input file 51 }
52 iplist = fopen(options->in_file, "rb"); 52 //read input file
53 if (!iplist) 53 iplist = fopen(options->in_file, "rb");
54 return 1; 54 if (!iplist)
55 stat(options->in_file, filestats); 55 return 1;
56 plist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1)); 56 stat(options->in_file, filestats);
57 fread(plist_entire, sizeof(char), filestats->st_size, iplist); 57 plist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1));
58 fclose(iplist); 58 fread(plist_entire, sizeof(char), filestats->st_size, iplist);
59 59 fclose(iplist);
60 60
61 //convert one format to another 61
62 62 //convert one format to another
63 63
64 if (memcmp(plist_entire, "bplist00", 8) == 0) { 64
65 plist_from_bin(plist_entire, filestats->st_size, &root_node); 65 if (memcmp(plist_entire, "bplist00", 8) == 0)
66 plist_to_xml(root_node, &plist_out, &size); 66 {
67 } else { 67 plist_from_bin(plist_entire, filestats->st_size, &root_node);
68 plist_from_xml(plist_entire, filestats->st_size, &root_node); 68 plist_to_xml(root_node, &plist_out, &size);
69 plist_to_bin(root_node, &plist_out, &size); 69 }
70 } 70 else
71 plist_free(root_node); 71 {
72 free(plist_entire); 72 plist_from_xml(plist_entire, filestats->st_size, &root_node);
73 free(filestats); 73 plist_to_bin(root_node, &plist_out, &size);
74 74 }
75 if (plist_out) { 75 plist_free(root_node);
76 if (options->out_file != NULL) { 76 free(plist_entire);
77 FILE *oplist = fopen(options->out_file, "wb"); 77 free(filestats);
78 if (!oplist) 78
79 return 1; 79 if (plist_out)
80 fwrite(plist_out, size, sizeof(char), oplist); 80 {
81 fclose(oplist); 81 if (options->out_file != NULL)
82 } 82 {
83 //if no output file specified, write to stdout 83 FILE *oplist = fopen(options->out_file, "wb");
84 else 84 if (!oplist)
85 fwrite(plist_out, size, sizeof(char), stdout); 85 return 1;
86 86 fwrite(plist_out, size, sizeof(char), oplist);
87 free(plist_out); 87 fclose(oplist);
88 } else 88 }
89 printf("ERROR\n"); 89 //if no output file specified, write to stdout
90 90 else
91 free(options); 91 fwrite(plist_out, size, sizeof(char), stdout);
92 return 0; 92
93 free(plist_out);
94 }
95 else
96 printf("ERROR\n");
97
98 free(options);
99 return 0;
93} 100}
94 101
95Options *parse_arguments(int argc, char *argv[]) 102Options *parse_arguments(int argc, char *argv[])
96{ 103{
97 int i = 0; 104 int i = 0;
98 105
99 Options *options = (Options *) malloc(sizeof(Options)); 106 Options *options = (Options *) malloc(sizeof(Options));
100 memset(options, 0, sizeof(Options)); 107 memset(options, 0, sizeof(Options));
101 108
102 for (i = 1; i < argc; i++) { 109 for (i = 1; i < argc; i++)
103 if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")) { 110 {
104 if ((i + 1) == argc) { 111 if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i"))
105 free(options); 112 {
106 return NULL; 113 if ((i + 1) == argc)
107 } 114 {
108 options->in_file = argv[i + 1]; 115 free(options);
109 i++; 116 return NULL;
110 continue; 117 }
111 } 118 options->in_file = argv[i + 1];
112 119 i++;
113 if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")) { 120 continue;
114 if ((i + 1) == argc) { 121 }
115 free(options); 122
116 return NULL; 123 if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o"))
117 } 124 {
118 options->out_file = argv[i + 1]; 125 if ((i + 1) == argc)
119 i++; 126 {
120 continue; 127 free(options);
121 } 128 return NULL;
122 129 }
123 if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v")) { 130 options->out_file = argv[i + 1];
124 options->debug = 1; 131 i++;
125 } 132 continue;
126 133 }
127 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { 134
128 free(options); 135 if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v"))
129 return NULL; 136 {
130 } 137 options->debug = 1;
131 } 138 }
132 139
133 if (!options->in_file /*|| !options->out_file */ ) { 140 if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
134 free(options); 141 {
135 return NULL; 142 free(options);
136 } 143 return NULL;
137 144 }
138 return options; 145 }
146
147 if (!options->in_file /*|| !options->out_file */ )
148 {
149 free(options);
150 return NULL;
151 }
152
153 return options;
139} 154}
140 155
141void print_usage() 156void print_usage()
142{ 157{
143 printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n"); 158 printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n");
144 printf("\n"); 159 printf("\n");
145 printf("\t-i or --infile: The file to read in.\n"); 160 printf("\t-i or --infile: The file to read in.\n");
146 printf("\t-o or --outfile: The file to convert to.\n"); 161 printf("\t-o or --outfile: The file to convert to.\n");
147 printf("\t-d, -v or --debug: Provide extended debug information.\n\n"); 162 printf("\t-d, -v or --debug: Provide extended debug information.\n\n");
148} 163}
diff --git a/plutil/plutil.h b/plutil/plutil.h
index 1455fb5..4be716e 100644
--- a/plutil/plutil.h
+++ b/plutil/plutil.h
@@ -8,20 +8,21 @@
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
22typedef struct _options { 22typedef struct _options
23 char *in_file, *out_file; 23{
24 uint8_t debug, in_fmt, out_fmt; 24 char *in_file, *out_file;
25 uint8_t debug, in_fmt, out_fmt;
25} Options; 26} Options;
26 27
27Options *parse_arguments(int argc, char *argv[]); 28Options *parse_arguments(int argc, char *argv[]);
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}
diff --git a/test/plist_cmp.c b/test/plist_cmp.c
index 386264a..709e8d0 100644
--- a/test/plist_cmp.c
+++ b/test/plist_cmp.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
@@ -33,110 +33,114 @@
33 33
34char compare_plist(plist_t node_l, plist_t node_r) 34char compare_plist(plist_t node_l, plist_t node_r)
35{ 35{
36 plist_t cur_l = NULL; 36 plist_t cur_l = NULL;
37 plist_t cur_r = NULL; 37 plist_t cur_r = NULL;
38 int res = 1; 38 int res = 1;
39 39
40 cur_l = plist_get_first_child(node_l); 40 cur_l = plist_get_first_child(node_l);
41 cur_r = plist_get_first_child(node_r); 41 cur_r = plist_get_first_child(node_r);
42 42
43 if ( (!cur_l && cur_r) || (cur_l && !cur_r)) 43 if ( (!cur_l && cur_r) || (cur_l && !cur_r))
44 return 0; 44 return 0;
45 45
46 if ( !cur_l && !cur_r ) 46 if ( !cur_l && !cur_r )
47 return plist_compare_node_value( node_l, node_r ); 47 return plist_compare_node_value( node_l, node_r );
48 48
49 while(cur_l && cur_r && res) { 49 while (cur_l && cur_r && res)
50 {
50 51
51 if (!(res = compare_plist(cur_l, cur_r))) 52 if (!(res = compare_plist(cur_l, cur_r)))
52 return res; 53 return res;
53 54
54 cur_l = plist_get_next_sibling(cur_l); 55 cur_l = plist_get_next_sibling(cur_l);
55 cur_r = plist_get_next_sibling(cur_r); 56 cur_r = plist_get_next_sibling(cur_r);
56 if ( (!cur_l && cur_r) || (cur_l && !cur_r)) 57 if ( (!cur_l && cur_r) || (cur_l && !cur_r))
57 return 0; 58 return 0;
58 } 59 }
59 60
60 return res; 61 return res;
61} 62}
62 63
63int main(int argc, char *argv[]) 64int main(int argc, char *argv[])
64{ 65{
65 FILE *iplist1 = NULL; 66 FILE *iplist1 = NULL;
66 FILE *iplist2 = NULL; 67 FILE *iplist2 = NULL;
67 plist_t root_node1 = NULL; 68 plist_t root_node1 = NULL;
68 plist_t root_node2 = NULL; 69 plist_t root_node2 = NULL;
69 char *plist_1 = NULL; 70 char *plist_1 = NULL;
70 char *plist_2 = NULL; 71 char *plist_2 = NULL;
71 int size_in1 = 0; 72 int size_in1 = 0;
72 int size_in2 = 0; 73 int size_in2 = 0;
73 char *file_in1 = NULL; 74 char *file_in1 = NULL;
74 char *file_in2 = NULL; 75 char *file_in2 = NULL;
75 int res = 0; 76 int res = 0;
76 77
77 struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat)); 78 struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat));
78 struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat)); 79 struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat));
79 80
80 if (argc!= 3) { 81 if (argc!= 3)
81 printf("Wrong input\n"); 82 {
82 return 1; 83 printf("Wrong input\n");
83 } 84 return 1;
84 85 }
85 file_in1 = argv[1]; 86
86 file_in2 = argv[2]; 87 file_in1 = argv[1];
87 88 file_in2 = argv[2];
88 //read input file 89
89 iplist1 = fopen(file_in1, "rb"); 90 //read input file
90 iplist2 = fopen(file_in2, "rb"); 91 iplist1 = fopen(file_in1, "rb");
91 92 iplist2 = fopen(file_in2, "rb");
92 if (!iplist1 || !iplist2) { 93
93 printf("File does not exists\n"); 94 if (!iplist1 || !iplist2)
94 return 2; 95 {
95 } 96 printf("File does not exists\n");
96 97 return 2;
97 stat(file_in1, filestats1); 98 }
98 stat(file_in2, filestats2); 99
99 100 stat(file_in1, filestats1);
100 size_in1 = filestats1->st_size; 101 stat(file_in2, filestats2);
101 size_in2 = filestats2->st_size; 102
102 103 size_in1 = filestats1->st_size;
103 plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1)); 104 size_in2 = filestats2->st_size;
104 plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1)); 105
105 106 plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1));
106 fread(plist_1, sizeof(char), size_in1, iplist1); 107 plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1));
107 fread(plist_2, sizeof(char), size_in2, iplist2); 108
108 109 fread(plist_1, sizeof(char), size_in1, iplist1);
109 fclose(iplist1); 110 fread(plist_2, sizeof(char), size_in2, iplist2);
110 fclose(iplist2); 111
111 112 fclose(iplist1);
112 if (memcmp(plist_1, "bplist00", 8) == 0) 113 fclose(iplist2);
113 plist_from_bin(plist_1, size_in1, &root_node1); 114
114 else 115 if (memcmp(plist_1, "bplist00", 8) == 0)
115 plist_from_xml(plist_1, size_in1, &root_node1); 116 plist_from_bin(plist_1, size_in1, &root_node1);
116 117 else
117 if (memcmp(plist_2, "bplist00", 8) == 0) 118 plist_from_xml(plist_1, size_in1, &root_node1);
118 plist_from_bin(plist_2, size_in2, &root_node2); 119
119 else 120 if (memcmp(plist_2, "bplist00", 8) == 0)
120 plist_from_xml(plist_2, size_in2, &root_node2); 121 plist_from_bin(plist_2, size_in2, &root_node2);
121 122 else
122 if (!root_node1 || !root_node2) { 123 plist_from_xml(plist_2, size_in2, &root_node2);
123 printf("PList parsing failed\n"); 124
124 return 3; 125 if (!root_node1 || !root_node2)
125 } 126 {
126 else 127 printf("PList parsing failed\n");
127 printf("PList parsing succeeded\n"); 128 return 3;
128 129 }
129 res = compare_plist(root_node1, root_node2); 130 else
130 131 printf("PList parsing succeeded\n");
131 132
132 plist_free(root_node1); 133 res = compare_plist(root_node1, root_node2);
133 plist_free(root_node2); 134
134 135
135 free(plist_1); 136 plist_free(root_node1);
136 free(plist_2); 137 plist_free(root_node2);
137 free(filestats1); 138
138 free(filestats2); 139 free(plist_1);
139 140 free(plist_2);
140 return !res; 141 free(filestats1);
142 free(filestats2);
143
144 return !res;
141} 145}
142 146
diff --git a/test/plist_test.c b/test/plist_test.c
index 069701e..a0344e9 100644
--- a/test/plist_test.c
+++ b/test/plist_test.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
@@ -34,95 +34,103 @@
34 34
35int main(int argc, char *argv[]) 35int main(int argc, char *argv[])
36{ 36{
37 FILE *iplist = NULL; 37 FILE *iplist = NULL;
38 FILE *oplist = NULL; 38 FILE *oplist = NULL;
39 plist_t root_node1 = NULL; 39 plist_t root_node1 = NULL;
40 plist_t root_node2 = NULL; 40 plist_t root_node2 = NULL;
41 char *plist_xml = NULL; 41 char *plist_xml = NULL;
42 char *plist_xml2 = NULL; 42 char *plist_xml2 = NULL;
43 char *plist_bin = NULL; 43 char *plist_bin = NULL;
44 int size_in = 0; 44 int size_in = 0;
45 int size_out = 0; 45 int size_out = 0;
46 int size_out2 = 0; 46 int size_out2 = 0;
47 char *file_in = NULL; 47 char *file_in = NULL;
48 struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); 48 struct stat *filestats = (struct stat *) malloc(sizeof(struct stat));
49 if (argc!= 2) { 49 if (argc!= 2)
50 printf("Wrong input\n"); 50 {
51 return 1; 51 printf("Wrong input\n");
52 } 52 return 1;
53 53 }
54 file_in = argv[1]; 54
55 //read input file 55 file_in = argv[1];
56 iplist = fopen(file_in, "rb"); 56 //read input file
57 57 iplist = fopen(file_in, "rb");
58 if (!iplist) { 58
59 printf("File does not exists\n"); 59 if (!iplist)
60 return 2; 60 {
61 } 61 printf("File does not exists\n");
62 printf("File %s is open\n", file_in); 62 return 2;
63 stat(file_in, filestats); 63 }
64 size_in = filestats->st_size; 64 printf("File %s is open\n", file_in);
65 plist_xml = (char *) malloc(sizeof(char) * (size_in + 1)); 65 stat(file_in, filestats);
66 fread(plist_xml, sizeof(char), size_in, iplist); 66 size_in = filestats->st_size;
67 fclose(iplist); 67 plist_xml = (char *) malloc(sizeof(char) * (size_in + 1));
68 68 fread(plist_xml, sizeof(char), size_in, iplist);
69 69 fclose(iplist);
70 //convert one format to another 70
71 plist_from_xml(plist_xml, size_in, &root_node1); 71
72 if (!root_node1) { 72 //convert one format to another
73 printf("PList XML parsing failed\n"); 73 plist_from_xml(plist_xml, size_in, &root_node1);
74 return 3; 74 if (!root_node1)
75 } 75 {
76 else 76 printf("PList XML parsing failed\n");
77 printf("PList XML parsing succeeded\n"); 77 return 3;
78 78 }
79 plist_to_bin(root_node1, &plist_bin, &size_out); 79 else
80 if (!plist_bin) { 80 printf("PList XML parsing succeeded\n");
81 printf("PList BIN writing failed\n"); 81
82 return 4; 82 plist_to_bin(root_node1, &plist_bin, &size_out);
83 } 83 if (!plist_bin)
84 else 84 {
85 printf("PList BIN writing succeeded\n"); 85 printf("PList BIN writing failed\n");
86 86 return 4;
87 plist_from_bin(plist_bin, size_out, &root_node2); 87 }
88 if (!root_node2) { 88 else
89 printf("PList BIN parsing failed\n"); 89 printf("PList BIN writing succeeded\n");
90 return 5; 90
91 } 91 plist_from_bin(plist_bin, size_out, &root_node2);
92 else 92 if (!root_node2)
93 printf("PList BIN parsing succeeded\n"); 93 {
94 94 printf("PList BIN parsing failed\n");
95 plist_to_xml(root_node2, &plist_xml2, &size_out2); 95 return 5;
96 if (!plist_xml2) { 96 }
97 printf("PList XML writing failed\n"); 97 else
98 return 8; 98 printf("PList BIN parsing succeeded\n");
99 } 99
100 else 100 plist_to_xml(root_node2, &plist_xml2, &size_out2);
101 printf("PList XML writing succeeded\n"); 101 if (!plist_xml2)
102 102 {
103 if (plist_xml2) { 103 printf("PList XML writing failed\n");
104 FILE *oplist = NULL; 104 return 8;
105 char file_out[512]; 105 }
106 sprintf(file_out, "%s.out", file_in); 106 else
107 oplist = fopen(file_out, "wb"); 107 printf("PList XML writing succeeded\n");
108 fwrite(plist_xml2, size_out2, sizeof(char), oplist); 108
109 fclose(oplist); 109 if (plist_xml2)
110 } 110 {
111 111 FILE *oplist = NULL;
112 plist_free(root_node1); 112 char file_out[512];
113 plist_free(root_node2); 113 sprintf(file_out, "%s.out", file_in);
114 free(plist_bin); 114 oplist = fopen(file_out, "wb");
115 free(plist_xml); 115 fwrite(plist_xml2, size_out2, sizeof(char), oplist);
116 free(plist_xml2); 116 fclose(oplist);
117 free(filestats); 117 }
118 118
119 if (size_in != size_out2) { 119 plist_free(root_node1);
120 printf("Size of input and output is different\n"); 120 plist_free(root_node2);
121 printf("Input size : %i\n", size_in); 121 free(plist_bin);
122 printf("Output size : %i\n", size_out2); 122 free(plist_xml);
123 } 123 free(plist_xml2);
124 124 free(filestats);
125 //success 125
126 return 0; 126 if (size_in != size_out2)
127 {
128 printf("Size of input and output is different\n");
129 printf("Input size : %i\n", size_in);
130 printf("Output size : %i\n", size_out2);
131 }
132
133 //success
134 return 0;
127} 135}
128 136