diff options
| -rw-r--r-- | include/plist/Array.h | 40 | ||||
| -rw-r--r-- | include/plist/Boolean.h | 30 | ||||
| -rw-r--r-- | include/plist/Data.h | 30 | ||||
| -rw-r--r-- | include/plist/Date.h | 30 | ||||
| -rw-r--r-- | include/plist/Dictionary.h | 48 | ||||
| -rw-r--r-- | include/plist/Integer.h | 30 | ||||
| -rw-r--r-- | include/plist/Node.h | 38 | ||||
| -rw-r--r-- | include/plist/Real.h | 30 | ||||
| -rw-r--r-- | include/plist/String.h | 30 | ||||
| -rw-r--r-- | include/plist/Structure.h | 32 | ||||
| -rw-r--r-- | include/plist/Utils.h | 26 | ||||
| -rw-r--r-- | include/plist/plist++.h | 6 | ||||
| -rw-r--r-- | include/plist/plist.h | 1388 | ||||
| -rw-r--r-- | plutil/plutil.c | 225 | ||||
| -rw-r--r-- | plutil/plutil.h | 13 | ||||
| -rw-r--r-- | src/Array.cpp | 52 | ||||
| -rw-r--r-- | src/Boolean.cpp | 6 | ||||
| -rw-r--r-- | src/Data.cpp | 6 | ||||
| -rw-r--r-- | src/Date.cpp | 6 | ||||
| -rw-r--r-- | src/Dictionary.cpp | 78 | ||||
| -rw-r--r-- | src/Integer.cpp | 6 | ||||
| -rw-r--r-- | src/Node.cpp | 69 | ||||
| -rw-r--r-- | src/Real.cpp | 6 | ||||
| -rw-r--r-- | src/String.cpp | 6 | ||||
| -rw-r--r-- | src/Structure.cpp | 10 | ||||
| -rw-r--r-- | src/Utils.cpp | 66 | ||||
| -rw-r--r-- | src/bplist.c | 1445 | ||||
| -rw-r--r-- | src/plist.c | 1212 | ||||
| -rw-r--r-- | src/plist.h | 30 | ||||
| -rw-r--r-- | src/xplist.c | 564 | ||||
| -rw-r--r-- | test/plist_cmp.c | 200 | ||||
| -rw-r--r-- | test/plist_test.c | 196 |
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 | ||
| 31 | class Array : public Structure | 31 | class Array : public Structure |
| 32 | { | 32 | { |
| 33 | public : | 33 | public : |
| 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 : | 48 | private : |
| 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 | ||
| 30 | class Boolean : public Node | 30 | class Boolean : public Node |
| 31 | { | 31 | { |
| 32 | public : | 32 | public : |
| 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 | ||
| 31 | class Data : public Node | 31 | class Data : public Node |
| 32 | { | 32 | { |
| 33 | public : | 33 | public : |
| 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 | ||
| 35 | class Date : public Node | 35 | class Date : public Node |
| 36 | { | 36 | { |
| 37 | public : | 37 | public : |
| 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 | ||
| 32 | class Dictionary : public Structure | 32 | class Dictionary : public Structure |
| 33 | { | 33 | { |
| 34 | public : | 34 | public : |
| 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 : | 53 | private : |
| 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 | ||
| 30 | class Integer : public Node | 30 | class Integer : public Node |
| 31 | { | 31 | { |
| 32 | public : | 32 | public : |
| 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 | ||
| 30 | class Node | 30 | class Node |
| 31 | { | 31 | { |
| 32 | public : | 32 | public : |
| 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: | 42 | protected: |
| 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 | ||
| 30 | class Real : public Node | 30 | class Real : public Node |
| 31 | { | 31 | { |
| 32 | public : | 32 | public : |
| 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 | ||
| 31 | class String : public Node | 31 | class String : public Node |
| 32 | { | 32 | { |
| 33 | public : | 33 | public : |
| 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 | ||
| 32 | class Structure : public Node | 32 | class Structure : public Node |
| 33 | { | 33 | { |
| 34 | public : | 34 | public : |
| 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; | 44 | protected: |
| 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: | 48 | private: |
| 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 | ||
| 28 | namespace PList | 28 | namespace PList |
| 29 | { | 29 | { |
| 30 | class Utils | 30 | class Utils |
| 31 | { | 31 | { |
| 32 | public: | 32 | public: |
| 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: | 37 | private: |
| 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 |
| 26 | extern "C" { | 26 | extern "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 | ||
| 36 | int main(int argc, char *argv[]) | 36 | int 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 | ||
| 95 | Options *parse_arguments(int argc, char *argv[]) | 102 | Options *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 | ||
| 141 | void print_usage() | 156 | void 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 | ||
| 22 | typedef struct _options { | 22 | typedef 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 | ||
| 27 | Options *parse_arguments(int argc, char *argv[]); | 28 | Options *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 | ||
| 78 | Array::~Array() | 78 | Array::~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 | ||
| 87 | Node* Array::Clone() | 87 | Node* 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 | ||
| 173 | void Dictionary::Remove(const std::string& key) | 173 | void 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) | |||
| 36 | Node::Node(plist_type type, Node* parent) : _parent(parent) | 36 | Node::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 | ||
| 47 | enum { | 47 | enum |
| 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 | ||
| 65 | static void byte_convert(uint8_t * address, size_t size) | 66 | static 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 | ||
| 80 | static uint32_t uint24_from_be(char *buff) | 82 | static 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 | ||
| 107 | static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object) | 109 | static 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 | ||
| 132 | static plist_t parse_real_node(char *bnode, uint8_t size) | 135 | static 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 | ||
| 158 | static plist_t parse_date_node(char *bnode, uint8_t size) | 162 | static 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 | ||
| 172 | static plist_t parse_string_node(char *bnode, uint64_t size) | 176 | static 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 | ||
| 185 | static plist_t parse_unicode_node(char *bnode, uint64_t size) | 189 | static 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 | ||
| 214 | static plist_t parse_data_node(char *bnode, uint64_t size) | 218 | static 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 | ||
| 226 | static plist_t parse_dict_node(char *bnode, uint64_t size, uint32_t ref_size) | 230 | static 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 | ||
| 238 | static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size) | 242 | static 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 | ||
| 252 | static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object) | 256 | static 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 | ||
| 361 | static gpointer copy_plist_data(gconstpointer src, gpointer data) | 372 | static 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 | ||
| 402 | void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) | 414 | void 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 | ||
| 516 | static guint plist_data_hash(gconstpointer key) | 536 | static 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 | ||
| 562 | struct serialize_s { | 583 | struct serialize_s |
| 563 | GPtrArray *objects; | 584 | { |
| 564 | GHashTable *ref_table; | 585 | GPtrArray *objects; |
| 586 | GHashTable *ref_table; | ||
| 565 | }; | 587 | }; |
| 566 | 588 | ||
| 567 | static void serialize_plist(GNode * node, gpointer data) | 589 | static 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 | ||
| 592 | static gboolean free_index(gpointer key, gpointer value, gpointer user_data) | 615 | static 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 | ||
| 600 | static void write_int(GByteArray * bplist, uint64_t val) | 623 | static 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 | ||
| 615 | static void write_real(GByteArray * bplist, double val) | 638 | static 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 | ||
| 631 | static void write_date(GByteArray * bplist, double val) | 657 | static 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 | ||
| 642 | static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size) | 668 | static 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 | ||
| 659 | static void write_data(GByteArray * bplist, uint8_t * val, uint64_t size) | 686 | static 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 | ||
| 664 | static void write_string(GByteArray * bplist, char *val) | 691 | static 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 | ||
| 670 | static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size) | 697 | static 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 | ||
| 681 | static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) | 708 | static 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 | ||
| 713 | static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) | 742 | static 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 | ||
| 750 | void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | 781 | void 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 | ||
| 29 | plist_t plist_new_node(plist_data_t data) | 29 | plist_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 | ||
| 34 | plist_data_t plist_get_data(const plist_t node) | 34 | plist_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 | ||
| 41 | plist_data_t plist_new_plist_data(void) | 41 | plist_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 | ||
| 47 | static void plist_free_data(plist_data_t data) | 47 | static 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 | ||
| 65 | static void plist_free_node(GNode * node, gpointer none) | 67 | static 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 | ||
| 75 | plist_t plist_new_dict(void) | 77 | plist_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 | ||
| 82 | plist_t plist_new_array(void) | 84 | plist_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 |
| 90 | static plist_t plist_new_key(const char *val) | 92 | static 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 | ||
| 99 | plist_t plist_new_string(const char *val) | 101 | plist_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 | ||
| 108 | plist_t plist_new_bool(uint8_t val) | 110 | plist_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 | ||
| 117 | plist_t plist_new_uint(uint64_t val) | 119 | plist_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 | ||
| 126 | plist_t plist_new_real(double val) | 128 | plist_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 | ||
| 135 | plist_t plist_new_data(const char *val, uint64_t length) | 137 | plist_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 | ||
| 145 | plist_t plist_new_date(int32_t sec, int32_t usec) | 147 | plist_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 | ||
| 155 | void plist_free(plist_t plist) | 157 | void 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 | ||
| 163 | static void plist_copy_node(GNode * node, gpointer parent_node_ptr) | 166 | static 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 | ||
| 199 | plist_t plist_copy(plist_t node) | 206 | plist_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 | ||
| 206 | uint32_t plist_array_get_size(plist_t node) | 213 | uint32_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 | ||
| 215 | plist_t plist_array_get_item(plist_t node, uint32_t n) | 223 | plist_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 | ||
| 224 | uint32_t plist_array_get_item_index(plist_t node) | 233 | uint32_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 | ||
| 233 | void plist_array_set_item(plist_t node, plist_t item, uint32_t n) | 243 | void 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 | ||
| 246 | void plist_array_append_item(plist_t node, plist_t item) | 258 | void 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 | ||
| 254 | void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) | 267 | void 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 | ||
| 262 | void plist_array_remove_item(plist_t node, uint32_t n) | 276 | void 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 | ||
| 273 | uint32_t plist_dict_get_size(plist_t node) | 289 | uint32_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 | ||
| 282 | void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) | 299 | void 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 | ||
| 291 | void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) | 309 | void 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 | ||
| 317 | void plist_dict_get_item_key(plist_t node, char **key) | 340 | void 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 | ||
| 325 | plist_t plist_dict_get_item(plist_t node, const char* key) | 349 | plist_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 | ||
| 348 | void plist_dict_set_item(plist_t node, const char* key, plist_t item) | 375 | void 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 | ||
| 361 | void plist_dict_insert_item(plist_t node, const char* key, plist_t item) | 390 | void 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 | ||
| 370 | void plist_dict_remove_item(plist_t node, const char* key) | 400 | void 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 | ||
| 383 | static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length) | 415 | static 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 | ||
| 414 | plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) | 447 | plist_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 | ||
| 435 | plist_t plist_access_path(plist_t plist, uint32_t length, ...) | 471 | plist_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 | ||
| 446 | static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) | 482 | static 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 | ||
| 488 | plist_t plist_get_parent(plist_t node) | 525 | plist_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 | ||
| 493 | plist_type plist_get_node_type(plist_t node) | 530 | plist_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 | ||
| 503 | void plist_get_key_val(plist_t node, char **val) | 541 | void 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 | ||
| 512 | void plist_get_string_val(plist_t node, char **val) | 550 | void 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 | ||
| 521 | void plist_get_bool_val(plist_t node, uint8_t * val) | 559 | void 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 | ||
| 530 | void plist_get_uint_val(plist_t node, uint64_t * val) | 568 | void 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 | ||
| 539 | void plist_get_real_val(plist_t node, double *val) | 577 | void 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 | ||
| 548 | void plist_get_data_val(plist_t node, char **val, uint64_t * length) | 586 | void 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 | ||
| 555 | void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) | 593 | void 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 | ||
| 567 | gboolean plist_data_compare(gconstpointer a, gconstpointer b) | 605 | gboolean 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 | ||
| 624 | char plist_compare_node_value(plist_t node_l, plist_t node_r) | 663 | char 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 | ||
| 629 | static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) | 668 | static 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 | ||
| 683 | void plist_set_type(plist_t node, plist_type type) | 724 | void 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 | ||
| 710 | void plist_set_key_val(plist_t node, const char *val) | 753 | void 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 | ||
| 715 | void plist_set_string_val(plist_t node, const char *val) | 758 | void 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 | ||
| 720 | void plist_set_bool_val(plist_t node, uint8_t val) | 763 | void 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 | ||
| 725 | void plist_set_uint_val(plist_t node, uint64_t val) | 768 | void 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 | ||
| 730 | void plist_set_real_val(plist_t node, double val) | 773 | void 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 | ||
| 735 | void plist_set_data_val(plist_t node, const char *val, uint64_t length) | 778 | void 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 | ||
| 740 | void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) | 783 | void 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 | ||
| 749 | static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length) | 792 | static 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 | ||
| 803 | plist_t plist_get_first_child(plist_t node) | 850 | plist_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 | ||
| 808 | plist_t plist_get_next_sibling(plist_t node) | 855 | plist_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 | ||
| 813 | plist_t plist_get_prev_sibling(plist_t node) | 860 | plist_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 | ||
| 818 | plist_t plist_get_array_nth_el(plist_t node, uint32_t n) | 865 | plist_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 | ||
| 835 | plist_t plist_get_dict_el_from_key(plist_t node, const char *key) | 884 | plist_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 | ||
| 846 | void plist_add_sub_node(plist_t node, plist_t subnode) | 896 | void 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 | ||
| 855 | void plist_add_sub_key_el(plist_t node, const char *val) | 906 | void 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 | ||
| 860 | void plist_add_sub_string_el(plist_t node, const char *val) | 911 | void 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 | ||
| 865 | void plist_add_sub_bool_el(plist_t node, uint8_t val) | 916 | void 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 | ||
| 870 | void plist_add_sub_uint_el(plist_t node, uint64_t val) | 921 | void 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 | ||
| 875 | void plist_add_sub_real_el(plist_t node, double val) | 926 | void 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 | ||
| 880 | void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length) | 931 | void 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 | ||
| 885 | void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) | 936 | void 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 | ||
| 891 | static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) | 942 | static 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 | ||
| 914 | plist_t plist_find_node_by_key(plist_t plist, const char *value) | 968 | plist_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 | ||
| 919 | plist_t plist_find_node_by_string(plist_t plist, const char *value) | 973 | plist_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 | ||
| 38 | struct plist_data_s { | 38 | struct 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 | ||
| 51 | typedef struct plist_data_s *plist_data_t; | 53 | typedef 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 | */ |
| 62 | static gchar *format_string(const char *buf, int cols, int depth) | 62 | static 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 | ||
| 93 | struct xml_node { | 94 | struct 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 | */ |
| 102 | static xmlDocPtr new_xml_plist(void) | 104 | static 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 | ||
| 115 | static void node_to_xml(GNode * node, gpointer xml_struct) | 117 | static 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 | ||
| 217 | static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) | 225 | static 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 | ||
| 335 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) | 355 | void 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 | ||
| 356 | void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist) | 376 | void 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 | ||
| 34 | char compare_plist(plist_t node_l, plist_t node_r) | 34 | char 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 | ||
| 63 | int main(int argc, char *argv[]) | 64 | int 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 | ||
| 35 | int main(int argc, char *argv[]) | 35 | int 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 | ||
