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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__ARRAY_H @@ -30,23 +30,23 @@ namespace PList class Array : public Structure { - public : - Array(Node* parent = NULL); - Array(plist_t node, Node* parent = NULL); - Array(Array& a); - Array& operator=(Array& a); - virtual ~Array(); - - Node* Clone(); - - Node* operator[](unsigned int index); - void Append(Node* node); - void Insert(Node* node, unsigned int pos); - void Remove(Node* node); - void Remove(unsigned int pos); - - private : - std::vector<Node*> _array; +public : + Array(Node* parent = NULL); + Array(plist_t node, Node* parent = NULL); + Array(Array& a); + Array& operator=(Array& a); + virtual ~Array(); + + Node* Clone(); + + Node* operator[](unsigned int index); + void Append(Node* node); + void Insert(Node* node, unsigned int pos); + void Remove(Node* node); + void Remove(unsigned int pos); + +private : + std::vector<Node*> _array; }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__BOOLEAN_H @@ -29,18 +29,18 @@ namespace PList class Boolean : public Node { - public : - Boolean(Node* parent = NULL); - Boolean(plist_t node, Node* parent = NULL); - Boolean(Boolean& b); - Boolean& operator=(Boolean& b); - Boolean(bool b); - virtual ~Boolean(); - - Node* Clone(); - - void SetValue(bool b); - bool GetValue(); +public : + Boolean(Node* parent = NULL); + Boolean(plist_t node, Node* parent = NULL); + Boolean(Boolean& b); + Boolean& operator=(Boolean& b); + Boolean(bool b); + virtual ~Boolean(); + + Node* Clone(); + + void SetValue(bool b); + bool GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__DATA_H @@ -30,18 +30,18 @@ namespace PList class Data : public Node { - public : - Data(Node* parent = NULL); - Data(plist_t node, Node* parent = NULL); - Data(Data& d); - Data& operator=(Data& d); - Data(const std::vector<char>& buff); - virtual ~Data(); - - Node* Clone(); - - void SetValue(const std::vector<char>& buff); - std::vector<char> GetValue(); +public : + Data(Node* parent = NULL); + Data(plist_t node, Node* parent = NULL); + Data(Data& d); + Data& operator=(Data& d); + Data(const std::vector<char>& buff); + virtual ~Data(); + + Node* Clone(); + + void SetValue(const std::vector<char>& buff); + std::vector<char> GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__DATE_H @@ -34,18 +34,18 @@ namespace PList class Date : public Node { - public : - Date(Node* parent = NULL); - Date(plist_t node, Node* parent = NULL); - Date(Date& d); - Date& operator=(Date& d); - Date(timeval t); - virtual ~Date(); - - Node* Clone(); - - void SetValue(timeval t); - timeval GetValue(); +public : + Date(Node* parent = NULL); + Date(plist_t node, Node* parent = NULL); + Date(Date& d); + Date& operator=(Date& d); + Date(timeval t); + virtual ~Date(); + + Node* Clone(); + + void SetValue(timeval t); + timeval GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__DICTIONARY_H @@ -31,27 +31,27 @@ namespace PList class Dictionary : public Structure { - public : - Dictionary(Node* parent = NULL); - Dictionary(plist_t node, Node* parent = NULL); - Dictionary(Dictionary& d); - Dictionary& operator=(Dictionary& d); - virtual ~Dictionary(); - - Node* Clone(); - - typedef std::map<std::string,Node*>::iterator iterator; - - Node* operator[](const std::string& key); - iterator Begin(); - iterator End(); - iterator Find(const std::string& key); - iterator Insert(const std::string& key, Node* node); - void Remove(Node* node); - void Remove(const std::string& key); - - private : - std::map<std::string,Node*> _map; +public : + Dictionary(Node* parent = NULL); + Dictionary(plist_t node, Node* parent = NULL); + Dictionary(Dictionary& d); + Dictionary& operator=(Dictionary& d); + virtual ~Dictionary(); + + Node* Clone(); + + typedef std::map<std::string,Node*>::iterator iterator; + + Node* operator[](const std::string& key); + iterator Begin(); + iterator End(); + iterator Find(const std::string& key); + iterator Insert(const std::string& key, Node* node); + void Remove(Node* node); + void Remove(const std::string& key); + +private : + std::map<std::string,Node*> _map; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__INTEGER_H @@ -29,18 +29,18 @@ namespace PList class Integer : public Node { - public : - Integer(Node* parent = NULL); - Integer(plist_t node, Node* parent = NULL); - Integer(Integer& i); - Integer& operator=(Integer& i); - Integer(uint64_t i); - virtual ~Integer(); - - Node* Clone(); - - void SetValue(uint64_t i); - uint64_t GetValue(); +public : + Integer(Node* parent = NULL); + Integer(plist_t node, Node* parent = NULL); + Integer(Integer& i); + Integer& operator=(Integer& i); + Integer(uint64_t i); + virtual ~Integer(); + + Node* Clone(); + + void SetValue(uint64_t i); + uint64_t GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__NODE_H @@ -29,22 +29,22 @@ namespace PList class Node { - public : - virtual ~Node(); - - virtual Node* Clone() = 0; - Node * GetParent(); - void SetParent(Node* parent); - - plist_type GetType(); - plist_t GetPlist(); - - protected: - Node(Node* parent = NULL); - Node(plist_t node, Node* parent = NULL); - Node(plist_type type, Node* parent = NULL); - plist_t _node; - Node* _parent; +public : + virtual ~Node(); + + virtual Node* Clone() = 0; + Node * GetParent(); + void SetParent(Node* parent); + + plist_type GetType(); + plist_t GetPlist(); + +protected: + Node(Node* parent = NULL); + Node(plist_t node, Node* parent = NULL); + Node(plist_type type, Node* parent = NULL); + plist_t _node; + Node* _parent; }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__REAL_H @@ -29,18 +29,18 @@ namespace PList class Real : public Node { - public : - Real(Node* parent = NULL); - Real(plist_t node, Node* parent = NULL); - Real(Real& d); - Real& operator=(Real& d); - Real(double d); - virtual ~Real(); - - Node* Clone(); - - void SetValue(double d); - double GetValue(); +public : + Real(Node* parent = NULL); + Real(plist_t node, Node* parent = NULL); + Real(Real& d); + Real& operator=(Real& d); + Real(double d); + virtual ~Real(); + + Node* Clone(); + + void SetValue(double d); + double GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__STRING_H @@ -30,18 +30,18 @@ namespace PList class String : public Node { - public : - String(Node* parent = NULL); - String(plist_t node, Node* parent = NULL); - String(String& s); - String& operator=(String& s); - String(const std::string& s); - virtual ~String(); - - Node* Clone(); - - void SetValue(const std::string& s); - std::string GetValue(); +public : + String(Node* parent = NULL); + String(plist_t node, Node* parent = NULL); + String(String& s); + String& operator=(String& s); + String(const std::string& s); + virtual ~String(); + + Node* Clone(); + + void SetValue(const std::string& s); + std::string GetValue(); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__STRUCTURE_H @@ -31,23 +31,23 @@ namespace PList class Structure : public Node { - public : - virtual ~Structure(); +public : + virtual ~Structure(); + + uint32_t GetSize(); - uint32_t GetSize(); + std::string ToXml(); + std::vector<char> ToBin(); - std::string ToXml(); - std::vector<char> ToBin(); + virtual void Remove(Node* node) = 0; - virtual void Remove(Node* node) = 0; - - protected: - Structure(Node* parent = NULL); - Structure(plist_type type, Node* parent = NULL); +protected: + Structure(Node* parent = NULL); + Structure(plist_type type, Node* parent = NULL); - private: - Structure(Structure& s); - Structure& operator=(const Structure& s); +private: + Structure(Structure& s); + Structure& operator=(const Structure& s); }; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST__UTILS_H @@ -27,17 +27,17 @@ namespace PList { - class Utils - { - public: - static Node* FromPlist(plist_t node, Node* parent = NULL); - static Structure* FromXml(const std::string& xml); - static Structure* FromBin(const std::vector<char>& bin); +class Utils +{ +public: + static Node* FromPlist(plist_t node, Node* parent = NULL); + static Structure* FromXml(const std::string& xml); + static Structure* FromBin(const std::vector<char>& bin); - private: - Utils(); - ~Utils(); - }; +private: + Utils(); + ~Utils(); +}; }; #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LIBPLIST_H #define LIBPLIST_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifdef _MSC_VER @@ -37,705 +38,706 @@ extern "C" { typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; - #ifdef plist_EXPORTS - #define PLIST_API __declspec( dllexport ) - #else - #define PLIST_API __declspec( dllimport ) - #endif +#ifdef plist_EXPORTS +#define PLIST_API __declspec( dllexport ) +#else +#define PLIST_API __declspec( dllimport ) +#endif #else - #include <stdint.h> - #define PLIST_API +#include <stdint.h> +#define PLIST_API #endif #include <sys/types.h> #include <stdarg.h> -/** - * \mainpage libplist : A library to handle Apple Property Lists - * \defgroup PublicAPI Public libplist API - */ -/*@{*/ - - -/** - * The basic plist abstract data type. - */ - typedef void *plist_t; - -/** - * The plist dictionary iterator. - */ - typedef void *plist_dict_iter; - -/** - * The enumeration of plist node types. - */ - typedef enum { - PLIST_BOOLEAN, /**< Boolean, scalar type */ - PLIST_UINT, /**< Unsigned integer, scalar type */ - PLIST_REAL, /**< Real, scalar type */ - PLIST_STRING, /**< ASCII string, scalar type */ - PLIST_ARRAY, /**< Ordered array, structured type */ - PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ - PLIST_DATE, /**< Date, scalar type */ - PLIST_DATA, /**< Binary data, scalar type */ - PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ - PLIST_NONE /**< No type */ - } plist_type; - - -/******************************************** - * * - * Creation & Destruction * - * * - ********************************************/ - -/** - * Create a new root plist_t type #PLIST_DICT - * - * @return the created plist - * @sa #plist_type - */ - PLIST_API plist_t plist_new_dict(void); - -/** - * Create a new root plist_t type #PLIST_ARRAY - * - * @return the created plist - * @sa #plist_type - */ - PLIST_API plist_t plist_new_array(void); - -/** - * Create a new plist_t type #PLIST_STRING - * - * @param val the sting value, encoded in UTF8. - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_string(const char *val); - -/** - * Create a new plist_t type #PLIST_BOOLEAN - * - * @param val the boolean value, 0 is false, other values are true. - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_bool(uint8_t val); - -/** - * Create a new plist_t type #PLIST_UINT - * - * @param val the unsigned integer value - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_uint(uint64_t val); - -/** - * Create a new plist_t type #PLIST_REAL - * - * @param val the real value - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_real(double val); - -/** - * Create a new plist_t type #PLIST_DATA - * - * @param val the binary buffer - * @param length the length of the buffer - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_data(const char *val, uint64_t length); - -/** - * Create a new plist_t type #PLIST_DATE - * - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds - * @return the created item - * @sa #plist_type - */ - PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec); - -/** - * Destruct a plist_t node and all its children recursively - * - * @param plist the plist to free - */ - PLIST_API void plist_free(plist_t plist); - -/** - * Return a copy of passed node and it's children - * - * @param plist the plist to copy - * @return copied plist - */ - PLIST_API plist_t plist_copy(plist_t node); - - -/******************************************** - * * - * Array functions * - * * - ********************************************/ - -/** - * Get size of a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @return size of the #PLIST_ARRAY node - */ - PLIST_API uint32_t plist_array_get_size(plist_t node); - -/** - * Get the nth item in a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param n the index of the item to get. Range is [0, array_size[ - * @return the nth item or NULL if node is not of type #PLIST_ARRAY - */ - PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n); - -/** - * Get the index of an item. item must be a member of a #PLIST_ARRAY node. - * - * @param node the node - * @return the node index - */ - PLIST_API uint32_t plist_array_get_item_index(plist_t node); - -/** - * Set the nth item in a #PLIST_ARRAY node. - * The previous item at index n will be freed using #plist_free - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item at index n - * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. - */ - PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n); - -/** - * Append a new item at the end of a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item - */ - PLIST_API void plist_array_append_item(plist_t node, plist_t item); - -/** - * Insert a new item at position n in a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item to insert - * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. - */ - PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); - -/** - * Remove an existing position in a #PLIST_ARRAY node. - * Removed position will be freed using #plist_free - * - * @param node the node of type #PLIST_ARRAY - * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. - */ - PLIST_API void plist_array_remove_item(plist_t node, uint32_t n); - -/******************************************** - * * - * Dictionary functions * - * * - ********************************************/ - -/** - * Get size of a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @return size of the #PLIST_DICT node - */ - PLIST_API uint32_t plist_dict_get_size(plist_t node); - -/** - * Create iterator of a #PLIST_DICT node. - * The allocated iterator shoult be freed with tandard free function - * - * @param node the node of type #PLIST_DICT - * @param iter iterator of the #PLIST_DICT node - */ - PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); - -/** - * Increment iterator of a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @param iter iterator of the dictionary - * @param key a location to store the key, or NULL. - * @param val a location to store the value, or NULL. - */ - PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); - -/** - * Get key associated to an item. Item must be member of a dictionary - * - * @param node the node - * @param key a location to store the key. - */ - PLIST_API void plist_dict_get_item_key(plist_t node, char **key); - -/** - * Get the nth item in a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @param key the identifier of the item to get. - * @return the item or NULL if node is not of type #PLIST_DICT - */ - PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key); - -/** - * Set item identified by key in a #PLIST_DICT node. - * The previous item at index n will be freed using #plist_free - * - * @param node the node of type #PLIST_DICT - * @param item the new item associated to key - * @param key the identifier of the item to get. Assert if identifier is not present. - */ - PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item); - -/** - * Insert a new item at position n in a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @param item the new item to insert - * @param key The identifier of the item to insert. Assert if identifier already present. - */ - PLIST_API void plist_dict_insert_item(plist_t node, const char* key, plist_t item); - -/** - * Remove an existing position in a #PLIST_DICT node. - * Removed position will be freed using #plist_free - * - * @param node the node of type #PLIST_DICT - * @param key The identifier of the item to remove. Assert if identifier is not present. - */ - PLIST_API void plist_dict_remove_item(plist_t node, const char* key); - - -/******************************************** - * * - * Getters * - * * - ********************************************/ - -/** - * Get the parent of a node - * - * @param node the parent (NULL if node is root) - */ - PLIST_API plist_t plist_get_parent(plist_t node); - -/** - * Get the #plist_type of a node. - * - * @param node the node - * @return the type of the node - */ - PLIST_API plist_type plist_get_node_type(plist_t node); - -/** - * Get the value of a #PLIST_KEY node. - * This function does nothing if node is not of type #PLIST_KEY - * - * @param node the node - * @param val a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. - */ - PLIST_API void plist_get_key_val(plist_t node, char **val); - -/** - * Get the value of a #PLIST_STRING node. - * This function does nothing if node is not of type #PLIST_STRING - * - * @param node the node - * @param val a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. Data is UTF-8 encoded. - */ - PLIST_API void plist_get_string_val(plist_t node, char **val); - -/** - * Get the value of a #PLIST_BOOLEAN node. - * This function does nothing if node is not of type #PLIST_BOOLEAN - * - * @param node the node - * @param val a pointer to a uint8_t variable. - */ - PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val); - -/** - * Get the value of a #PLIST_UINT node. - * This function does nothing if node is not of type #PLIST_UINT - * - * @param node the node - * @param val a pointer to a uint64_t variable. - */ - PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val); - -/** - * Get the value of a #PLIST_REAL node. - * This function does nothing if node is not of type #PLIST_REAL - * - * @param node the node - * @param val a pointer to a double variable. - */ - PLIST_API void plist_get_real_val(plist_t node, double *val); - -/** - * Get the value of a #PLIST_DATA node. - * This function does nothing if node is not of type #PLIST_DATA - * - * @param node the node - * @param val a pointer to an unallocated char buffer. This function allocates the memory, - * caller is responsible for freeing it. - */ - PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length); - -/** - * Get the value of a #PLIST_DATE node. - * This function does nothing if node is not of type #PLIST_DATE - * - * @param node the node - * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001. - * @param usec a pointer to an int32_t variable. Represents the number of microseconds - */ - PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); - - -/******************************************** - * * - * Setters * - * * - ********************************************/ - -/** - * Forces type of node. Changing type of structured nodes is only allowed if node is empty. - * Reset value of node; - * @param node the node - * @param type the key value - */ - PLIST_API void plist_set_type(plist_t node, plist_type type); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_KEY - * - * @param node the node - * @param val the key value - */ - PLIST_API void plist_set_key_val(plist_t node, const char *val); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_STRING - * - * @param node the node - * @param val the string value - */ - PLIST_API void plist_set_string_val(plist_t node, const char *val); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_BOOLEAN - * - * @param node the node - * @param val the boolean value - */ - PLIST_API void plist_set_bool_val(plist_t node, uint8_t val); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_UINT - * - * @param node the node - * @param val the unsigned integer value - */ - PLIST_API void plist_set_uint_val(plist_t node, uint64_t val); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_REAL - * - * @param node the node - * @param val the real value - */ - PLIST_API void plist_set_real_val(plist_t node, double val); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_DATA - * - * @param node the node - * @param val the binary buffer - * @param length the length of the buffer - */ - PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length); - -/** - * Set the value of a node. - * Forces type of node to #PLIST_DATE - * - * @param node the node - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds - */ - PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); - - -/******************************************** - * * - * Import & Export * - * * - ********************************************/ - -/** - * Export the #plist_t structure to XML format. - * - * @param plist the root node to export - * @param plist_xml a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. Data is UTF-8 encoded. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - */ - PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); - -/** - * Export the #plist_t structure to binary format. - * - * @param plist the root node to export - * @param plist_bin a pointer to a char* buffer. This function allocates the memory, - * caller is responsible for freeing it. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - */ - PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); - -/** - * Import the #plist_t structure from XML format. - * - * @param plist_xml a pointer to the xml buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - */ - PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); - -/** - * Import the #plist_t structure from binary format. - * - * @param plist_bin a pointer to the xml buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - */ - PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); - - -/******************************************** - * * - * Utils * - * * - ********************************************/ - -/** - * Get a node from its path. Each path element depends on the associated father node type. - * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t - * Search is breath first order. - * - * @param plist the node to access result from. - * @param length length of the path to access - * @return the value to access. - */ - PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...); - -/** - * Variadic version of #plist_access_path. - * - * @param plist the node to access result from. - * @param length length of the path to access - * @param v list of array's index and dic'st key - * @return the value to access. - */ - PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); - -/** - * Compare two node values - * - * @param node_l left node to compare - * @param node_r rigth node to compare - * @return TRUE is type and value match, FALSE otherwise. - */ - PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r); + /** + * \mainpage libplist : A library to handle Apple Property Lists + * \defgroup PublicAPI Public libplist API + */ + /*@{*/ + + + /** + * The basic plist abstract data type. + */ + typedef void *plist_t; + + /** + * The plist dictionary iterator. + */ + typedef void *plist_dict_iter; + + /** + * The enumeration of plist node types. + */ + typedef enum + { + PLIST_BOOLEAN, /**< Boolean, scalar type */ + PLIST_UINT, /**< Unsigned integer, scalar type */ + PLIST_REAL, /**< Real, scalar type */ + PLIST_STRING, /**< ASCII string, scalar type */ + PLIST_ARRAY, /**< Ordered array, structured type */ + PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ + PLIST_DATE, /**< Date, scalar type */ + PLIST_DATA, /**< Binary data, scalar type */ + PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ + PLIST_NONE /**< No type */ + } plist_type; + + + /******************************************** + * * + * Creation & Destruction * + * * + ********************************************/ + + /** + * Create a new root plist_t type #PLIST_DICT + * + * @return the created plist + * @sa #plist_type + */ + PLIST_API plist_t plist_new_dict(void); + + /** + * Create a new root plist_t type #PLIST_ARRAY + * + * @return the created plist + * @sa #plist_type + */ + PLIST_API plist_t plist_new_array(void); + + /** + * Create a new plist_t type #PLIST_STRING + * + * @param val the sting value, encoded in UTF8. + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_string(const char *val); + + /** + * Create a new plist_t type #PLIST_BOOLEAN + * + * @param val the boolean value, 0 is false, other values are true. + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_bool(uint8_t val); + + /** + * Create a new plist_t type #PLIST_UINT + * + * @param val the unsigned integer value + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_uint(uint64_t val); + + /** + * Create a new plist_t type #PLIST_REAL + * + * @param val the real value + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_real(double val); + + /** + * Create a new plist_t type #PLIST_DATA + * + * @param val the binary buffer + * @param length the length of the buffer + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_data(const char *val, uint64_t length); + + /** + * Create a new plist_t type #PLIST_DATE + * + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec); + + /** + * Destruct a plist_t node and all its children recursively + * + * @param plist the plist to free + */ + PLIST_API void plist_free(plist_t plist); + + /** + * Return a copy of passed node and it's children + * + * @param plist the plist to copy + * @return copied plist + */ + PLIST_API plist_t plist_copy(plist_t node); + + + /******************************************** + * * + * Array functions * + * * + ********************************************/ + + /** + * Get size of a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @return size of the #PLIST_ARRAY node + */ + PLIST_API uint32_t plist_array_get_size(plist_t node); + + /** + * Get the nth item in a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @param n the index of the item to get. Range is [0, array_size[ + * @return the nth item or NULL if node is not of type #PLIST_ARRAY + */ + PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n); + + /** + * Get the index of an item. item must be a member of a #PLIST_ARRAY node. + * + * @param node the node + * @return the node index + */ + PLIST_API uint32_t plist_array_get_item_index(plist_t node); + + /** + * Set the nth item in a #PLIST_ARRAY node. + * The previous item at index n will be freed using #plist_free + * + * @param node the node of type #PLIST_ARRAY + * @param item the new item at index n + * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. + */ + PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n); + + /** + * Append a new item at the end of a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @param item the new item + */ + PLIST_API void plist_array_append_item(plist_t node, plist_t item); + + /** + * Insert a new item at position n in a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @param item the new item to insert + * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. + */ + PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); + + /** + * Remove an existing position in a #PLIST_ARRAY node. + * Removed position will be freed using #plist_free + * + * @param node the node of type #PLIST_ARRAY + * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. + */ + PLIST_API void plist_array_remove_item(plist_t node, uint32_t n); + + /******************************************** + * * + * Dictionary functions * + * * + ********************************************/ + + /** + * Get size of a #PLIST_DICT node. + * + * @param node the node of type #PLIST_DICT + * @return size of the #PLIST_DICT node + */ + PLIST_API uint32_t plist_dict_get_size(plist_t node); + + /** + * Create iterator of a #PLIST_DICT node. + * The allocated iterator shoult be freed with tandard free function + * + * @param node the node of type #PLIST_DICT + * @param iter iterator of the #PLIST_DICT node + */ + PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); + + /** + * Increment iterator of a #PLIST_DICT node. + * + * @param node the node of type #PLIST_DICT + * @param iter iterator of the dictionary + * @param key a location to store the key, or NULL. + * @param val a location to store the value, or NULL. + */ + PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); + + /** + * Get key associated to an item. Item must be member of a dictionary + * + * @param node the node + * @param key a location to store the key. + */ + PLIST_API void plist_dict_get_item_key(plist_t node, char **key); + + /** + * Get the nth item in a #PLIST_DICT node. + * + * @param node the node of type #PLIST_DICT + * @param key the identifier of the item to get. + * @return the item or NULL if node is not of type #PLIST_DICT + */ + PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key); + + /** + * Set item identified by key in a #PLIST_DICT node. + * The previous item at index n will be freed using #plist_free + * + * @param node the node of type #PLIST_DICT + * @param item the new item associated to key + * @param key the identifier of the item to get. Assert if identifier is not present. + */ + PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item); + + /** + * Insert a new item at position n in a #PLIST_DICT node. + * + * @param node the node of type #PLIST_DICT + * @param item the new item to insert + * @param key The identifier of the item to insert. Assert if identifier already present. + */ + PLIST_API void plist_dict_insert_item(plist_t node, const char* key, plist_t item); + + /** + * Remove an existing position in a #PLIST_DICT node. + * Removed position will be freed using #plist_free + * + * @param node the node of type #PLIST_DICT + * @param key The identifier of the item to remove. Assert if identifier is not present. + */ + PLIST_API void plist_dict_remove_item(plist_t node, const char* key); + + + /******************************************** + * * + * Getters * + * * + ********************************************/ + + /** + * Get the parent of a node + * + * @param node the parent (NULL if node is root) + */ + PLIST_API plist_t plist_get_parent(plist_t node); + + /** + * Get the #plist_type of a node. + * + * @param node the node + * @return the type of the node + */ + PLIST_API plist_type plist_get_node_type(plist_t node); + + /** + * Get the value of a #PLIST_KEY node. + * This function does nothing if node is not of type #PLIST_KEY + * + * @param node the node + * @param val a pointer to a C-string. This function allocates the memory, + * caller is responsible for freeing it. + */ + PLIST_API void plist_get_key_val(plist_t node, char **val); + + /** + * Get the value of a #PLIST_STRING node. + * This function does nothing if node is not of type #PLIST_STRING + * + * @param node the node + * @param val a pointer to a C-string. This function allocates the memory, + * caller is responsible for freeing it. Data is UTF-8 encoded. + */ + PLIST_API void plist_get_string_val(plist_t node, char **val); + + /** + * Get the value of a #PLIST_BOOLEAN node. + * This function does nothing if node is not of type #PLIST_BOOLEAN + * + * @param node the node + * @param val a pointer to a uint8_t variable. + */ + PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val); + + /** + * Get the value of a #PLIST_UINT node. + * This function does nothing if node is not of type #PLIST_UINT + * + * @param node the node + * @param val a pointer to a uint64_t variable. + */ + PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val); + + /** + * Get the value of a #PLIST_REAL node. + * This function does nothing if node is not of type #PLIST_REAL + * + * @param node the node + * @param val a pointer to a double variable. + */ + PLIST_API void plist_get_real_val(plist_t node, double *val); + + /** + * Get the value of a #PLIST_DATA node. + * This function does nothing if node is not of type #PLIST_DATA + * + * @param node the node + * @param val a pointer to an unallocated char buffer. This function allocates the memory, + * caller is responsible for freeing it. + */ + PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length); + + /** + * Get the value of a #PLIST_DATE node. + * This function does nothing if node is not of type #PLIST_DATE + * + * @param node the node + * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001. + * @param usec a pointer to an int32_t variable. Represents the number of microseconds + */ + PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); + + + /******************************************** + * * + * Setters * + * * + ********************************************/ + + /** + * Forces type of node. Changing type of structured nodes is only allowed if node is empty. + * Reset value of node; + * @param node the node + * @param type the key value + */ + PLIST_API void plist_set_type(plist_t node, plist_type type); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_KEY + * + * @param node the node + * @param val the key value + */ + PLIST_API void plist_set_key_val(plist_t node, const char *val); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_STRING + * + * @param node the node + * @param val the string value + */ + PLIST_API void plist_set_string_val(plist_t node, const char *val); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_BOOLEAN + * + * @param node the node + * @param val the boolean value + */ + PLIST_API void plist_set_bool_val(plist_t node, uint8_t val); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_UINT + * + * @param node the node + * @param val the unsigned integer value + */ + PLIST_API void plist_set_uint_val(plist_t node, uint64_t val); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_REAL + * + * @param node the node + * @param val the real value + */ + PLIST_API void plist_set_real_val(plist_t node, double val); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_DATA + * + * @param node the node + * @param val the binary buffer + * @param length the length of the buffer + */ + PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length); + + /** + * Set the value of a node. + * Forces type of node to #PLIST_DATE + * + * @param node the node + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + */ + PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); + + + /******************************************** + * * + * Import & Export * + * * + ********************************************/ + + /** + * Export the #plist_t structure to XML format. + * + * @param plist the root node to export + * @param plist_xml a pointer to a C-string. This function allocates the memory, + * caller is responsible for freeing it. Data is UTF-8 encoded. + * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + */ + PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); + + /** + * Export the #plist_t structure to binary format. + * + * @param plist the root node to export + * @param plist_bin a pointer to a char* buffer. This function allocates the memory, + * caller is responsible for freeing it. + * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + */ + PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); + + /** + * Import the #plist_t structure from XML format. + * + * @param plist_xml a pointer to the xml buffer. + * @param length length of the buffer to read. + * @param plist a pointer to the imported plist. + */ + PLIST_API void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); + + /** + * Import the #plist_t structure from binary format. + * + * @param plist_bin a pointer to the xml buffer. + * @param length length of the buffer to read. + * @param plist a pointer to the imported plist. + */ + PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); + + + /******************************************** + * * + * Utils * + * * + ********************************************/ + + /** + * Get a node from its path. Each path element depends on the associated father node type. + * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t + * Search is breath first order. + * + * @param plist the node to access result from. + * @param length length of the path to access + * @return the value to access. + */ + PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...); + + /** + * Variadic version of #plist_access_path. + * + * @param plist the node to access result from. + * @param length length of the path to access + * @param v list of array's index and dic'st key + * @return the value to access. + */ + PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); + + /** + * Compare two node values + * + * @param node_l left node to compare + * @param node_r rigth node to compare + * @return TRUE is type and value match, FALSE otherwise. + */ + PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r); //DEPRECATED API BELOW -/*@}*/ -/** - * \defgroup DeprecatedAPI Deprecated libplist API - */ -/*@{*/ - -/******************************************** - * * - * Tree navigation * - * * - ********************************************/ - -/** - * Get the first child of a node - * - * @param node the first child - */ - PLIST_API plist_t plist_get_first_child(plist_t node); - -/** - * Get the next sibling of a node - * - * @param node the next sibling - */ - PLIST_API plist_t plist_get_next_sibling(plist_t node); - -/** - * Get the previous sibling of a node - * - * @param node the previous sibling - */ - PLIST_API plist_t plist_get_prev_sibling(plist_t node); - -/** - * Get the nth child of a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param n the index of the child to get. Range is [0, array_size[ - * @return the nth children or NULL if node is not of type #PLIST_ARRAY - */ - PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n); - -/** - * Get the child of a #PLIST_DICT node from the associated key value. - * - * @param node the node of type #PLIST_DICT - * @param key the key associated to the requested value - * @return the key associated value or NULL if node is not of type #PLIST_DICT - */ - PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key); - - -/******************************************** - * * - * Setters * - * * - ********************************************/ - -/** - * Add a subnode to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently - * if subnode already has a father. - * - * @param node the node to add a children to - * @param subnode the children node - */ - PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode); - -/** - * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the key value encoded as an ASCII string (must be null terminated) - */ - PLIST_API void plist_add_sub_key_el(plist_t node, const char *val); - -/** - * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated) - */ - PLIST_API void plist_add_sub_string_el(plist_t node, const char *val); - -/** - * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the boolean value (TRUE or FALSE) - */ - PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val); - -/** - * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the unsigned integer value - */ - PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val); - -/** - * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the real value - */ - PLIST_API void plist_add_sub_real_el(plist_t node, double val); - -/** - * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the binary buffer - * @param length the length of the buffer - */ - PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length); - -/** - * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds - */ - PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); - - -/******************************************** - * * - * Utils * - * * - ********************************************/ - -/** - * Find the first encountered #PLIST_KEY node mathing that key. - * Search is breath first order. - * - * @param plist the root node of the plist structure. - * @param value the ASCII Key to match. - */ - PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); - -/** - * Find the first encountered #PLIST_STRING node mathing that string. - * Search is breath first order. - * - * @param plist the root node of the plist structure. - * @param value the ASCII String to match. - */ - PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); - -/*@}*/ + /*@}*/ + /** + * \defgroup DeprecatedAPI Deprecated libplist API + */ + /*@{*/ + + /******************************************** + * * + * Tree navigation * + * * + ********************************************/ + + /** + * Get the first child of a node + * + * @param node the first child + */ + PLIST_API plist_t plist_get_first_child(plist_t node); + + /** + * Get the next sibling of a node + * + * @param node the next sibling + */ + PLIST_API plist_t plist_get_next_sibling(plist_t node); + + /** + * Get the previous sibling of a node + * + * @param node the previous sibling + */ + PLIST_API plist_t plist_get_prev_sibling(plist_t node); + + /** + * Get the nth child of a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @param n the index of the child to get. Range is [0, array_size[ + * @return the nth children or NULL if node is not of type #PLIST_ARRAY + */ + PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n); + + /** + * Get the child of a #PLIST_DICT node from the associated key value. + * + * @param node the node of type #PLIST_DICT + * @param key the key associated to the requested value + * @return the key associated value or NULL if node is not of type #PLIST_DICT + */ + PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key); + + + /******************************************** + * * + * Setters * + * * + ********************************************/ + + /** + * Add a subnode to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently + * if subnode already has a father. + * + * @param node the node to add a children to + * @param subnode the children node + */ + PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode); + + /** + * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the key value encoded as an ASCII string (must be null terminated) + */ + PLIST_API void plist_add_sub_key_el(plist_t node, const char *val); + + /** + * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated) + */ + PLIST_API void plist_add_sub_string_el(plist_t node, const char *val); + + /** + * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the boolean value (TRUE or FALSE) + */ + PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val); + + /** + * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the unsigned integer value + */ + PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val); + + /** + * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the real value + */ + PLIST_API void plist_add_sub_real_el(plist_t node, double val); + + /** + * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the binary buffer + * @param length the length of the buffer + */ + PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length); + + /** + * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + */ + PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); + + + /******************************************** + * * + * Utils * + * * + ********************************************/ + + /** + * Find the first encountered #PLIST_KEY node mathing that key. + * Search is breath first order. + * + * @param plist the root node of the plist structure. + * @param value the ASCII Key to match. + */ + PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); + + /** + * Find the first encountered #PLIST_STRING node mathing that string. + * Search is breath first order. + * + * @param plist the root node of the plist structure. + * @param value the ASCII String to match. + */ + PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); + + /*@}*/ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -35,114 +35,129 @@ int main(int argc, char *argv[]) { - FILE *iplist = NULL; - plist_t root_node = NULL; - char *plist_out = NULL; - int size = 0; - char *plist_entire = NULL; - struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); - Options *options = parse_arguments(argc, argv); - - if (!options) { - print_usage(); - free(filestats); - return 0; - } - //read input file - iplist = fopen(options->in_file, "rb"); - if (!iplist) - return 1; - stat(options->in_file, filestats); - plist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1)); - fread(plist_entire, sizeof(char), filestats->st_size, iplist); - fclose(iplist); - - - //convert one format to another - - - if (memcmp(plist_entire, "bplist00", 8) == 0) { - plist_from_bin(plist_entire, filestats->st_size, &root_node); - plist_to_xml(root_node, &plist_out, &size); - } else { - plist_from_xml(plist_entire, filestats->st_size, &root_node); - plist_to_bin(root_node, &plist_out, &size); - } - plist_free(root_node); - free(plist_entire); - free(filestats); - - if (plist_out) { - if (options->out_file != NULL) { - FILE *oplist = fopen(options->out_file, "wb"); - if (!oplist) - return 1; - fwrite(plist_out, size, sizeof(char), oplist); - fclose(oplist); - } - //if no output file specified, write to stdout - else - fwrite(plist_out, size, sizeof(char), stdout); - - free(plist_out); - } else - printf("ERROR\n"); - - free(options); - return 0; + FILE *iplist = NULL; + plist_t root_node = NULL; + char *plist_out = NULL; + int size = 0; + char *plist_entire = NULL; + struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); + Options *options = parse_arguments(argc, argv); + + if (!options) + { + print_usage(); + free(filestats); + return 0; + } + //read input file + iplist = fopen(options->in_file, "rb"); + if (!iplist) + return 1; + stat(options->in_file, filestats); + plist_entire = (char *) malloc(sizeof(char) * (filestats->st_size + 1)); + fread(plist_entire, sizeof(char), filestats->st_size, iplist); + fclose(iplist); + + + //convert one format to another + + + if (memcmp(plist_entire, "bplist00", 8) == 0) + { + plist_from_bin(plist_entire, filestats->st_size, &root_node); + plist_to_xml(root_node, &plist_out, &size); + } + else + { + plist_from_xml(plist_entire, filestats->st_size, &root_node); + plist_to_bin(root_node, &plist_out, &size); + } + plist_free(root_node); + free(plist_entire); + free(filestats); + + if (plist_out) + { + if (options->out_file != NULL) + { + FILE *oplist = fopen(options->out_file, "wb"); + if (!oplist) + return 1; + fwrite(plist_out, size, sizeof(char), oplist); + fclose(oplist); + } + //if no output file specified, write to stdout + else + fwrite(plist_out, size, sizeof(char), stdout); + + free(plist_out); + } + else + printf("ERROR\n"); + + free(options); + return 0; } Options *parse_arguments(int argc, char *argv[]) { - int i = 0; - - Options *options = (Options *) malloc(sizeof(Options)); - memset(options, 0, sizeof(Options)); - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")) { - if ((i + 1) == argc) { - free(options); - return NULL; - } - options->in_file = argv[i + 1]; - i++; - continue; - } - - if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")) { - if ((i + 1) == argc) { - free(options); - return NULL; - } - options->out_file = argv[i + 1]; - i++; - continue; - } - - if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v")) { - options->debug = 1; - } - - if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { - free(options); - return NULL; - } - } - - if (!options->in_file /*|| !options->out_file */ ) { - free(options); - return NULL; - } - - return options; + int i = 0; + + Options *options = (Options *) malloc(sizeof(Options)); + memset(options, 0, sizeof(Options)); + + for (i = 1; i < argc; i++) + { + if (!strcmp(argv[i], "--infile") || !strcmp(argv[i], "-i")) + { + if ((i + 1) == argc) + { + free(options); + return NULL; + } + options->in_file = argv[i + 1]; + i++; + continue; + } + + if (!strcmp(argv[i], "--outfile") || !strcmp(argv[i], "-o")) + { + if ((i + 1) == argc) + { + free(options); + return NULL; + } + options->out_file = argv[i + 1]; + i++; + continue; + } + + if (!strcmp(argv[i], "--debug") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-v")) + { + options->debug = 1; + } + + if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) + { + free(options); + return NULL; + } + } + + if (!options->in_file /*|| !options->out_file */ ) + { + free(options); + return NULL; + } + + return options; } void print_usage() { - printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n"); - printf("\n"); - printf("\t-i or --infile: The file to read in.\n"); - printf("\t-o or --outfile: The file to convert to.\n"); - printf("\t-d, -v or --debug: Provide extended debug information.\n\n"); + printf("Usage: plistutil -i|--infile in_file.plist -o|--outfile out_file.plist [--debug]\n"); + printf("\n"); + printf("\t-i or --infile: The file to read in.\n"); + printf("\t-o or --outfile: The file to convert to.\n"); + printf("\t-d, -v or --debug: Provide extended debug information.\n\n"); } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -typedef struct _options { - char *in_file, *out_file; - uint8_t debug, in_fmt, out_fmt; +typedef struct _options +{ + char *in_file, *out_file; + uint8_t debug, in_fmt, out_fmt; } Options; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -37,7 +37,7 @@ Array::Array(plist_t node, Node* parent) : Structure(parent) for (uint32_t i = 0; i < size; i++) { - plist_t subnode = plist_array_get_item(_node, i); + plist_t subnode = plist_array_get_item(_node, i); _array.push_back( Utils::FromPlist(subnode, this) ); } } @@ -50,7 +50,7 @@ Array::Array(PList::Array& a) : Structure() for (uint32_t i = 0; i < size; i++) { - plist_t subnode = plist_array_get_item(_node, i); + plist_t subnode = plist_array_get_item(_node, i); _array.push_back( Utils::FromPlist(subnode, this) ); } } @@ -60,7 +60,7 @@ Array& Array::operator=(PList::Array& a) plist_free(_node); for (unsigned int it = 0; it < _array.size(); it++) { - delete _array.at(it); + delete _array.at(it); } _array.clear(); @@ -69,7 +69,7 @@ Array& Array::operator=(PList::Array& a) for (uint32_t i = 0; i < size; i++) { - plist_t subnode = plist_array_get_item(_node, i); + plist_t subnode = plist_array_get_item(_node, i); _array.push_back( Utils::FromPlist(subnode, this) ); } return *this; @@ -77,11 +77,11 @@ Array& Array::operator=(PList::Array& a) Array::~Array() { - for (unsigned int it = 0; it < _array.size(); it++) - { - delete (_array.at(it)); - } - _array.clear(); + for (unsigned int it = 0; it < _array.size(); it++) + { + delete (_array.at(it)); + } + _array.clear(); } Node* Array::Clone() @@ -98,10 +98,10 @@ void Array::Append(Node* node) { if (node) { - Node* clone = node->Clone(); + Node* clone = node->Clone(); clone->SetParent(this); - plist_array_append_item(_node, clone->GetPlist()); - _array.push_back(clone); + plist_array_append_item(_node, clone->GetPlist()); + _array.push_back(clone); } } @@ -109,12 +109,12 @@ void Array::Insert(Node* node, unsigned int pos) { if (node) { - Node* clone = node->Clone(); + Node* clone = node->Clone(); clone->SetParent(this); - plist_array_insert_item(_node, clone->GetPlist(), pos); - std::vector<Node*>::iterator it = _array.begin(); - it += pos; - _array.insert(it, clone); + plist_array_insert_item(_node, clone->GetPlist(), pos); + std::vector<Node*>::iterator it = _array.begin(); + it += pos; + _array.insert(it, clone); } } @@ -122,12 +122,12 @@ void Array::Remove(Node* node) { if (node) { - uint32_t pos = plist_array_get_item_index(node->GetPlist()); - plist_array_remove_item(_node, pos); - std::vector<Node*>::iterator it = _array.begin(); - it += pos; - _array.erase(it); - delete node; + uint32_t pos = plist_array_get_item_index(node->GetPlist()); + plist_array_remove_item(_node, pos); + std::vector<Node*>::iterator it = _array.begin(); + it += pos; + _array.erase(it); + delete node; } } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -41,11 +41,11 @@ Dictionary::Dictionary(plist_t node, Node* parent) : Structure(parent) while (subnode) { _map[std::string(key)] = Utils::FromPlist(subnode, this); - - subnode = NULL; - free(key); - key = NULL; - plist_dict_next_item(_node, it, &key, &subnode); + + subnode = NULL; + free(key); + key = NULL; + plist_dict_next_item(_node, it, &key, &subnode); } free(it); } @@ -54,8 +54,8 @@ Dictionary::Dictionary(PList::Dictionary& d) : Structure() { for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) { - plist_free(it->second->GetPlist()); - delete it->second; + plist_free(it->second->GetPlist()); + delete it->second; } _map.clear(); @@ -69,11 +69,11 @@ Dictionary::Dictionary(PList::Dictionary& d) : Structure() while (subnode) { _map[std::string(key)] = Utils::FromPlist(subnode, this); - - subnode = NULL; - free(key); - key = NULL; - plist_dict_next_item(_node, it, NULL, &subnode); + + subnode = NULL; + free(key); + key = NULL; + plist_dict_next_item(_node, it, NULL, &subnode); } free(it); } @@ -82,8 +82,8 @@ Dictionary& Dictionary::operator=(PList::Dictionary& d) { for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) { - plist_free(it->second->GetPlist()); - delete it->second; + plist_free(it->second->GetPlist()); + delete it->second; } _map.clear(); @@ -97,11 +97,11 @@ Dictionary& Dictionary::operator=(PList::Dictionary& d) while (subnode) { _map[std::string(key)] = Utils::FromPlist(subnode, this); - - subnode = NULL; - free(key); - key = NULL; - plist_dict_next_item(_node, it, NULL, &subnode); + + subnode = NULL; + free(key); + key = NULL; + plist_dict_next_item(_node, it, NULL, &subnode); } free(it); return *this; @@ -111,8 +111,8 @@ Dictionary::~Dictionary() { for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) { - plist_free(it->second->GetPlist()); - delete it->second; + plist_free(it->second->GetPlist()); + delete it->second; } _map.clear(); } @@ -146,12 +146,12 @@ Dictionary::iterator Dictionary::Insert(const std::string& key, Node* node) { if (node) { - Node* clone = node->Clone(); + Node* clone = node->Clone(); clone->SetParent(this); - plist_dict_insert_item(_node, key.c_str(), clone->GetPlist()); - delete _map[key]; - _map[key] = clone; - return _map.find(key); + plist_dict_insert_item(_node, key.c_str(), clone->GetPlist()); + delete _map[key]; + _map[key] = clone; + return _map.find(key); } return iterator(NULL); } @@ -160,21 +160,21 @@ void Dictionary::Remove(Node* node) { if (node) { - char* key = NULL; - plist_dict_get_item_key(node->GetPlist(), &key); - plist_dict_remove_item(_node, key); - std::string skey = key; - free(key); - _map.erase(skey); - delete node; + char* key = NULL; + plist_dict_get_item_key(node->GetPlist(), &key); + plist_dict_remove_item(_node, key); + std::string skey = key; + free(key); + _map.erase(skey); + delete node; } } void Dictionary::Remove(const std::string& key) { - plist_dict_remove_item(_node, key.c_str()); - delete _map[key]; - _map.erase(key); + plist_dict_remove_item(_node, key.c_str()); + delete _map[key]; + _map.erase(key); } }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -36,36 +36,37 @@ Node::Node(plist_t node, Node* parent) : _node(node), _parent(parent) Node::Node(plist_type type, Node* parent) : _parent(parent) { _node = NULL; - - switch(type) { - case PLIST_BOOLEAN: - _node = plist_new_bool(0); - break; - case PLIST_UINT: - _node = plist_new_uint(0); - break; - case PLIST_REAL: - _node = plist_new_real(0.); - break; - case PLIST_STRING: - _node = plist_new_string(""); - break; - case PLIST_DATA: - _node = plist_new_data(NULL,0); - break; - case PLIST_DATE: - _node = plist_new_date(0,0); - break; - case PLIST_ARRAY: - _node = plist_new_array(); - break; - case PLIST_DICT: - _node = plist_new_dict(); - break; - case PLIST_KEY: - case PLIST_NONE: - default: - break; + + switch (type) + { + case PLIST_BOOLEAN: + _node = plist_new_bool(0); + break; + case PLIST_UINT: + _node = plist_new_uint(0); + break; + case PLIST_REAL: + _node = plist_new_real(0.); + break; + case PLIST_STRING: + _node = plist_new_string(""); + break; + case PLIST_DATA: + _node = plist_new_data(NULL,0); + break; + case PLIST_DATE: + _node = plist_new_date(0,0); + break; + case PLIST_ARRAY: + _node = plist_new_array(); + break; + case PLIST_DICT: + _node = plist_new_dict(); + break; + case PLIST_KEY: + case PLIST_NONE: + default: + break; } } @@ -80,7 +81,7 @@ plist_type Node::GetType() { if (_node) { - return plist_get_node_type(_node); + return plist_get_node_type(_node); } return PLIST_NONE; } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -41,11 +41,11 @@ uint32_t Structure::GetSize() plist_type type = plist_get_node_type(_node); if (type == PLIST_ARRAY) { - size = plist_array_get_size(_node); + size = plist_array_get_size(_node); } else if (type == PLIST_DICT) { - size = plist_dict_get_size(_node); + size = plist_dict_get_size(_node); } return size; } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -38,36 +38,36 @@ Node* Utils::FromPlist(plist_t node, Node* parent) if (node) { plist_type type = plist_get_node_type(node); - switch(type) - { - case PLIST_DICT: - ret = new Dictionary(node, parent); - break; - case PLIST_ARRAY: - ret = new Array(node, parent); - break; - case PLIST_BOOLEAN: - ret = new Boolean(node, parent); - break; - case PLIST_UINT: - ret = new Integer(node, parent); - break; - case PLIST_REAL: - ret = new Real(node, parent); - break; - case PLIST_STRING: - ret = new String(node, parent); - break; - case PLIST_DATE: - ret = new Date(node, parent); - break; - case PLIST_DATA: - ret = new Data(node, parent); - break; - default: - plist_free(node); - break; - } + switch (type) + { + case PLIST_DICT: + ret = new Dictionary(node, parent); + break; + case PLIST_ARRAY: + ret = new Array(node, parent); + break; + case PLIST_BOOLEAN: + ret = new Boolean(node, parent); + break; + case PLIST_UINT: + ret = new Integer(node, parent); + break; + case PLIST_REAL: + ret = new Real(node, parent); + break; + case PLIST_STRING: + ret = new String(node, parent); + break; + case PLIST_DATE: + ret = new Date(node, parent); + break; + case PLIST_DATA: + ret = new Data(node, parent); + break; + default: + plist_free(node); + break; + } } return ret; } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -44,46 +44,48 @@ #define BPLIST_TRL_ROOTOBJ_IDX 10 #define BPLIST_TRL_OFFTAB_IDX 18 -enum { - BPLIST_NULL = 0x00, - BPLIST_FALSE = 0x08, - BPLIST_TRUE = 0x09, - BPLIST_FILL = 0x0F, /* will be used for length grabbing */ - BPLIST_UINT = 0x10, - BPLIST_REAL = 0x20, - BPLIST_DATE = 0x30, - BPLIST_DATA = 0x40, - BPLIST_STRING = 0x50, - BPLIST_UNICODE = 0x60, - BPLIST_UID = 0x70, - BPLIST_ARRAY = 0xA0, - BPLIST_SET = 0xC0, - BPLIST_DICT = 0xD0, - BPLIST_MASK = 0xF0 +enum +{ + BPLIST_NULL = 0x00, + BPLIST_FALSE = 0x08, + BPLIST_TRUE = 0x09, + BPLIST_FILL = 0x0F, /* will be used for length grabbing */ + BPLIST_UINT = 0x10, + BPLIST_REAL = 0x20, + BPLIST_DATE = 0x30, + BPLIST_DATA = 0x40, + BPLIST_STRING = 0x50, + BPLIST_UNICODE = 0x60, + BPLIST_UID = 0x70, + BPLIST_ARRAY = 0xA0, + BPLIST_SET = 0xC0, + BPLIST_DICT = 0xD0, + BPLIST_MASK = 0xF0 }; static void byte_convert(uint8_t * address, size_t size) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN - uint8_t i = 0, j = 0; - uint8_t tmp = 0; - - for (i = 0; i < (size / 2); i++) { - tmp = address[i]; - j = ((size - 1) + 0) - i; - address[i] = address[j]; - address[j] = tmp; - } + uint8_t i = 0, j = 0; + uint8_t tmp = 0; + + for (i = 0; i < (size / 2); i++) + { + tmp = address[i]; + j = ((size - 1) + 0) - i; + address[i] = address[j]; + address[j] = tmp; + } #endif } static uint32_t uint24_from_be(char *buff) { - uint32_t ret = 0; - char *tmp = (char *) &ret; - memcpy(tmp + 1, buff, 3 * sizeof(char)); - byte_convert(tmp, sizeof(uint32_t)); - return ret; + uint32_t ret = 0; + char *tmp = (char *) &ret; + memcpy(tmp + 1, buff, 3 * sizeof(char)); + byte_convert(tmp, sizeof(uint32_t)); + return ret; } #define UINT_TO_HOST(x, n) \ @@ -106,787 +108,822 @@ static uint32_t uint24_from_be(char *buff) static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object) { - plist_data_t data = plist_new_plist_data(); - - size = 1 << size; // make length less misleading - switch (size) { - case sizeof(uint8_t): - case sizeof(uint16_t): - case sizeof(uint32_t): - case sizeof(uint64_t): - memcpy(&data->intval, bnode, size); - data->intval = UINT_TO_HOST(&data->intval, size); - break; - default: - free(data); - return NULL; - }; - - *next_object = bnode + size; - data->type = PLIST_UINT; - data->length = sizeof(uint64_t); - - return g_node_new(data); + plist_data_t data = plist_new_plist_data(); + + size = 1 << size; // make length less misleading + switch (size) + { + case sizeof(uint8_t): + case sizeof(uint16_t): + case sizeof(uint32_t): + case sizeof(uint64_t): + memcpy(&data->intval, bnode, size); + data->intval = UINT_TO_HOST(&data->intval, size); + break; + default: + free(data); + return NULL; + }; + + *next_object = bnode + size; + data->type = PLIST_UINT; + data->length = sizeof(uint64_t); + + return g_node_new(data); } static plist_t parse_real_node(char *bnode, uint8_t size) { - plist_data_t data = plist_new_plist_data(); - float floatval = 0.0; - - size = 1 << size; // make length less misleading - switch (size) { - case sizeof(float): - floatval = *(float *) bnode; - byte_convert((uint8_t *) & floatval, sizeof(float)); - data->realval = floatval; - break; - case sizeof(double): - data->realval = *(double *) bnode; - byte_convert((uint8_t *) & (data->realval), sizeof(double)); - break; - default: - free(data); - return NULL; - } - data->type = PLIST_REAL; - data->length = sizeof(double); - - return g_node_new(data); + plist_data_t data = plist_new_plist_data(); + float floatval = 0.0; + + size = 1 << size; // make length less misleading + switch (size) + { + case sizeof(float): + floatval = *(float *) bnode; + byte_convert((uint8_t *) & floatval, sizeof(float)); + data->realval = floatval; + break; + case sizeof(double): + data->realval = *(double *) bnode; + byte_convert((uint8_t *) & (data->realval), sizeof(double)); + break; + default: + free(data); + return NULL; + } + data->type = PLIST_REAL; + data->length = sizeof(double); + + return g_node_new(data); } static plist_t parse_date_node(char *bnode, uint8_t size) { - plist_t node = parse_real_node(bnode, size); - plist_data_t data = plist_get_data(node); + plist_t node = parse_real_node(bnode, size); + plist_data_t data = plist_get_data(node); - double time_real = data->realval; - data->timeval.tv_sec = (glong) time_real; - data->timeval.tv_usec = (time_real - (glong) time_real) * G_USEC_PER_SEC; - data->type = PLIST_DATE; - data->length = sizeof(GTimeVal); + double time_real = data->realval; + data->timeval.tv_sec = (glong) time_real; + data->timeval.tv_usec = (time_real - (glong) time_real) * G_USEC_PER_SEC; + data->type = PLIST_DATE; + data->length = sizeof(GTimeVal); - return node; + return node; } static plist_t parse_string_node(char *bnode, uint64_t size) { - plist_data_t data = plist_new_plist_data(); + plist_data_t data = plist_new_plist_data(); - data->type = PLIST_STRING; - data->strval = (char *) malloc(sizeof(char) * (size + 1)); - memcpy(data->strval, bnode, size); - data->strval[size] = '\0'; - data->length = strlen(data->strval); + data->type = PLIST_STRING; + data->strval = (char *) malloc(sizeof(char) * (size + 1)); + memcpy(data->strval, bnode, size); + data->strval[size] = '\0'; + data->length = strlen(data->strval); - return g_node_new(data); + return g_node_new(data); } static plist_t parse_unicode_node(char *bnode, uint64_t size) { - plist_data_t data = plist_new_plist_data(); - uint64_t i = 0; - gunichar2 *unicodestr = NULL; - gchar *tmpstr = NULL; - int type = 0; - glong items_read = 0; - glong items_written = 0; - GError *error = NULL; - - data->type = PLIST_STRING; - unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size); - memcpy(unicodestr, bnode, sizeof(gunichar2) * size); - for (i = 0; i < size; i++) - byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2)); - - tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error); - free(unicodestr); - - data->type = PLIST_STRING; - data->strval = (char *) malloc(sizeof(char) * (items_written + 1)); - memcpy(data->strval, tmpstr, items_written); - data->strval[items_written] = '\0'; - data->length = strlen(data->strval); - g_free(tmpstr); - return g_node_new(data); + plist_data_t data = plist_new_plist_data(); + uint64_t i = 0; + gunichar2 *unicodestr = NULL; + gchar *tmpstr = NULL; + int type = 0; + glong items_read = 0; + glong items_written = 0; + GError *error = NULL; + + data->type = PLIST_STRING; + unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size); + memcpy(unicodestr, bnode, sizeof(gunichar2) * size); + for (i = 0; i < size; i++) + byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2)); + + tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error); + free(unicodestr); + + data->type = PLIST_STRING; + data->strval = (char *) malloc(sizeof(char) * (items_written + 1)); + memcpy(data->strval, tmpstr, items_written); + data->strval[items_written] = '\0'; + data->length = strlen(data->strval); + g_free(tmpstr); + return g_node_new(data); } static plist_t parse_data_node(char *bnode, uint64_t size) { - plist_data_t data = plist_new_plist_data(); + plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DATA; - data->length = size; - data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size); - memcpy(data->buff, bnode, sizeof(uint8_t) * size); + data->type = PLIST_DATA; + data->length = size; + data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size); + memcpy(data->buff, bnode, sizeof(uint8_t) * size); - return g_node_new(data); + return g_node_new(data); } static plist_t parse_dict_node(char *bnode, uint64_t size, uint32_t ref_size) { - plist_data_t data = plist_new_plist_data(); + plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DICT; - data->length = size; - data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size * 2); - memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size * 2); + data->type = PLIST_DICT; + data->length = size; + data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size * 2); + memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size * 2); - return g_node_new(data); + return g_node_new(data); } static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size) { - plist_data_t data = plist_new_plist_data(); + plist_data_t data = plist_new_plist_data(); - data->type = PLIST_ARRAY; - data->length = size; - data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size); - memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size); + data->type = PLIST_ARRAY; + data->length = size; + data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size * ref_size); + memcpy(data->buff, bnode, sizeof(uint8_t) * size * ref_size); - return g_node_new(data); + return g_node_new(data); } static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object) { - uint16_t type = 0; - uint64_t size = 0; - - if (!object) - return NULL; - - type = (*object) & 0xF0; - size = (*object) & 0x0F; - object++; - - switch (type) { - - case BPLIST_NULL: - switch (size) { - - case BPLIST_TRUE: - { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_BOOLEAN; - data->boolval = TRUE; - data->length = 1; - return g_node_new(data); - } - - case BPLIST_FALSE: - { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_BOOLEAN; - data->boolval = FALSE; - data->length = 1; - return g_node_new(data); - } - - case BPLIST_NULL: - default: - return NULL; - } - - case BPLIST_UINT: - return parse_uint_node(object, size, next_object); - - case BPLIST_REAL: - return parse_real_node(object, size); - - case BPLIST_DATE: - if (3 != size) - return NULL; - else - return parse_date_node(object, size); - - case BPLIST_DATA: - if (0x0F == size) { - plist_t size_node = parse_bin_node(object, dict_size, &object); - if (plist_get_node_type(size_node) != PLIST_UINT) - return NULL; - plist_get_uint_val(size_node, &size); - plist_free(size_node); - } - return parse_data_node(object, size); - - case BPLIST_STRING: - if (0x0F == size) { - plist_t size_node = parse_bin_node(object, dict_size, &object); - if (plist_get_node_type(size_node) != PLIST_UINT) - return NULL; - plist_get_uint_val(size_node, &size); - plist_free(size_node); - } - return parse_string_node(object, size); - - case BPLIST_UNICODE: - if (0x0F == size) { - plist_t size_node = parse_bin_node(object, dict_size, &object); - if (plist_get_node_type(size_node) != PLIST_UINT) - return NULL; - plist_get_uint_val(size_node, &size); - plist_free(size_node); - } - return parse_unicode_node(object, size); - - case BPLIST_UID: - case BPLIST_ARRAY: - if (0x0F == size) { - plist_t size_node = parse_bin_node(object, dict_size, &object); - if (plist_get_node_type(size_node) != PLIST_UINT) - return NULL; - plist_get_uint_val(size_node, &size); - plist_free(size_node); - } - return parse_array_node(object, size, dict_size); - - case BPLIST_SET: - case BPLIST_DICT: - if (0x0F == size) { - plist_t size_node = parse_bin_node(object, dict_size, &object); - if (plist_get_node_type(size_node) != PLIST_UINT) - return NULL; - plist_get_uint_val(size_node, &size); - plist_free(size_node); - } - return parse_dict_node(object, size, dict_size); - default: - return NULL; - } - return NULL; + uint16_t type = 0; + uint64_t size = 0; + + if (!object) + return NULL; + + type = (*object) & 0xF0; + size = (*object) & 0x0F; + object++; + + switch (type) + { + + case BPLIST_NULL: + switch (size) + { + + case BPLIST_TRUE: + { + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_BOOLEAN; + data->boolval = TRUE; + data->length = 1; + return g_node_new(data); + } + + case BPLIST_FALSE: + { + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_BOOLEAN; + data->boolval = FALSE; + data->length = 1; + return g_node_new(data); + } + + case BPLIST_NULL: + default: + return NULL; + } + + case BPLIST_UINT: + return parse_uint_node(object, size, next_object); + + case BPLIST_REAL: + return parse_real_node(object, size); + + case BPLIST_DATE: + if (3 != size) + return NULL; + else + return parse_date_node(object, size); + + case BPLIST_DATA: + if (0x0F == size) + { + plist_t size_node = parse_bin_node(object, dict_size, &object); + if (plist_get_node_type(size_node) != PLIST_UINT) + return NULL; + plist_get_uint_val(size_node, &size); + plist_free(size_node); + } + return parse_data_node(object, size); + + case BPLIST_STRING: + if (0x0F == size) + { + plist_t size_node = parse_bin_node(object, dict_size, &object); + if (plist_get_node_type(size_node) != PLIST_UINT) + return NULL; + plist_get_uint_val(size_node, &size); + plist_free(size_node); + } + return parse_string_node(object, size); + + case BPLIST_UNICODE: + if (0x0F == size) + { + plist_t size_node = parse_bin_node(object, dict_size, &object); + if (plist_get_node_type(size_node) != PLIST_UINT) + return NULL; + plist_get_uint_val(size_node, &size); + plist_free(size_node); + } + return parse_unicode_node(object, size); + + case BPLIST_UID: + case BPLIST_ARRAY: + if (0x0F == size) + { + plist_t size_node = parse_bin_node(object, dict_size, &object); + if (plist_get_node_type(size_node) != PLIST_UINT) + return NULL; + plist_get_uint_val(size_node, &size); + plist_free(size_node); + } + return parse_array_node(object, size, dict_size); + + case BPLIST_SET: + case BPLIST_DICT: + if (0x0F == size) + { + plist_t size_node = parse_bin_node(object, dict_size, &object); + if (plist_get_node_type(size_node) != PLIST_UINT) + return NULL; + plist_get_uint_val(size_node, &size); + plist_free(size_node); + } + return parse_dict_node(object, size, dict_size); + default: + return NULL; + } + return NULL; } static gpointer copy_plist_data(gconstpointer src, gpointer data) { - plist_data_t srcdata = (plist_data_t) src; - plist_data_t dstdata = plist_new_plist_data(); - - dstdata->type = srcdata->type; - dstdata->length = srcdata->length; - switch (dstdata->type) { - case PLIST_BOOLEAN: - dstdata->boolval = srcdata->boolval; - break; - case PLIST_UINT: - dstdata->intval = srcdata->intval; - break; - case PLIST_DATE: - dstdata->timeval.tv_sec = srcdata->timeval.tv_sec; - dstdata->timeval.tv_usec = srcdata->timeval.tv_usec; - break; - case PLIST_REAL: - dstdata->realval = srcdata->realval; - break; - case PLIST_KEY: - case PLIST_STRING: - dstdata->strval = strdup(srcdata->strval); - break; - case PLIST_DATA: - case PLIST_ARRAY: - dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length); - memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length); - break; - case PLIST_DICT: - dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length * 2); - memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length * 2); - break; - default: - break; - } - - return dstdata; + plist_data_t srcdata = (plist_data_t) src; + plist_data_t dstdata = plist_new_plist_data(); + + dstdata->type = srcdata->type; + dstdata->length = srcdata->length; + switch (dstdata->type) + { + case PLIST_BOOLEAN: + dstdata->boolval = srcdata->boolval; + break; + case PLIST_UINT: + dstdata->intval = srcdata->intval; + break; + case PLIST_DATE: + dstdata->timeval.tv_sec = srcdata->timeval.tv_sec; + dstdata->timeval.tv_usec = srcdata->timeval.tv_usec; + break; + case PLIST_REAL: + dstdata->realval = srcdata->realval; + break; + case PLIST_KEY: + case PLIST_STRING: + dstdata->strval = strdup(srcdata->strval); + break; + case PLIST_DATA: + case PLIST_ARRAY: + dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length); + memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length); + break; + case PLIST_DICT: + dstdata->buff = (uint8_t *) malloc(sizeof(uint8_t *) * srcdata->length * 2); + memcpy(dstdata->buff, srcdata->buff, sizeof(uint8_t *) * srcdata->length * 2); + break; + default: + break; + } + + return dstdata; } void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) { - char *trailer = NULL; - - uint8_t offset_size = 0; - uint8_t dict_param_size = 0; - uint64_t num_objects = 0; - uint64_t root_object = 0; - uint64_t offset_table_index = 0; - - plist_t *nodeslist = NULL; - uint64_t i = 0; - uint64_t current_offset = 0; - char *offset_table = NULL; - uint32_t j = 0, str_i = 0, str_j = 0; - uint32_t index1 = 0, index2 = 0; - - - //first check we have enough data - if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) - return; - //check that plist_bin in actually a plist - if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) - return; - //check for known version - if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) - return; - - //now parse trailer - trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE)); - - offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX]; - dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX]; - num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); - root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); - offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); - - if (num_objects == 0) - return; - - //allocate serialized array of nodes - nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects); - - if (!nodeslist) - return; - - //parse serialized nodes - offset_table = (char *) (plist_bin + offset_table_index); - for (i = 0; i < num_objects; i++) { - char *obj = NULL; - current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size); - - obj = (char *) (plist_bin + current_offset); - nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj); - } - - //setup children for structured types - for (i = 0; i < num_objects; i++) { - - plist_data_t data = plist_get_data(nodeslist[i]); - - switch (data->type) { - case PLIST_DICT: - for (j = 0; j < data->length; j++) { - str_i = j * dict_param_size; - str_j = (j + data->length) * dict_param_size; - - index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size); - index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size); - - //first one is actually a key - plist_get_data(nodeslist[index1])->type = PLIST_KEY; - - if (index1 < num_objects) { - if (G_NODE_IS_ROOT(nodeslist[index1])) - g_node_append(nodeslist[i], nodeslist[index1]); - else - g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); - } - - if (index2 < num_objects) { - if (G_NODE_IS_ROOT(nodeslist[index2])) - g_node_append(nodeslist[i], nodeslist[index2]); - else - g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL)); - } - } - - free(data->buff); - break; - - case PLIST_ARRAY: - for (j = 0; j < data->length; j++) { - str_j = j * dict_param_size; - index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size); - - if (index1 < num_objects) { - if (G_NODE_IS_ROOT(nodeslist[index1])) - g_node_append(nodeslist[i], nodeslist[index1]); - else - g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); - } - } - free(data->buff); - break; - default: - break; - } - } - - *plist = nodeslist[root_object]; - free(nodeslist); + char *trailer = NULL; + + uint8_t offset_size = 0; + uint8_t dict_param_size = 0; + uint64_t num_objects = 0; + uint64_t root_object = 0; + uint64_t offset_table_index = 0; + + plist_t *nodeslist = NULL; + uint64_t i = 0; + uint64_t current_offset = 0; + char *offset_table = NULL; + uint32_t j = 0, str_i = 0, str_j = 0; + uint32_t index1 = 0, index2 = 0; + + + //first check we have enough data + if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) + return; + //check that plist_bin in actually a plist + if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) + return; + //check for known version + if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) + return; + + //now parse trailer + trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE)); + + offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX]; + dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX]; + num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); + root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); + offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); + + if (num_objects == 0) + return; + + //allocate serialized array of nodes + nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects); + + if (!nodeslist) + return; + + //parse serialized nodes + offset_table = (char *) (plist_bin + offset_table_index); + for (i = 0; i < num_objects; i++) + { + char *obj = NULL; + current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size); + + obj = (char *) (plist_bin + current_offset); + nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj); + } + + //setup children for structured types + for (i = 0; i < num_objects; i++) + { + + plist_data_t data = plist_get_data(nodeslist[i]); + + switch (data->type) + { + case PLIST_DICT: + for (j = 0; j < data->length; j++) + { + str_i = j * dict_param_size; + str_j = (j + data->length) * dict_param_size; + + index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size); + index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size); + + //first one is actually a key + plist_get_data(nodeslist[index1])->type = PLIST_KEY; + + if (index1 < num_objects) + { + if (G_NODE_IS_ROOT(nodeslist[index1])) + g_node_append(nodeslist[i], nodeslist[index1]); + else + g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); + } + + if (index2 < num_objects) + { + if (G_NODE_IS_ROOT(nodeslist[index2])) + g_node_append(nodeslist[i], nodeslist[index2]); + else + g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index2], copy_plist_data, NULL)); + } + } + + free(data->buff); + break; + + case PLIST_ARRAY: + for (j = 0; j < data->length; j++) + { + str_j = j * dict_param_size; + index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size); + + if (index1 < num_objects) + { + if (G_NODE_IS_ROOT(nodeslist[index1])) + g_node_append(nodeslist[i], nodeslist[index1]); + else + g_node_append(nodeslist[i], g_node_copy_deep(nodeslist[index1], copy_plist_data, NULL)); + } + } + free(data->buff); + break; + default: + break; + } + } + + *plist = nodeslist[root_object]; + free(nodeslist); } static guint plist_data_hash(gconstpointer key) { - plist_data_t data = plist_get_data((plist_t) key); - - guint hash = data->type; - guint i = 0; - - char *buff = NULL; - guint size = 0; - - switch (data->type) { - case PLIST_BOOLEAN: - case PLIST_UINT: - case PLIST_REAL: - buff = (char *) &data->intval; //works also for real as we use an union - size = 8; - break; - case PLIST_KEY: - case PLIST_STRING: - buff = data->strval; - size = strlen(buff); - break; - case PLIST_DATA: - case PLIST_ARRAY: - case PLIST_DICT: - //for these types only hash pointer - buff = (char *) &key; - size = sizeof(gconstpointer); - break; - case PLIST_DATE: - buff = (char *) &(data->timeval); - size = data->length; - break; - default: - break; - } - - //now perform hash - for (i = 0; i < size; buff++, i++) - hash = hash << 7 ^ (*buff); - - return hash; + plist_data_t data = plist_get_data((plist_t) key); + + guint hash = data->type; + guint i = 0; + + char *buff = NULL; + guint size = 0; + + switch (data->type) + { + case PLIST_BOOLEAN: + case PLIST_UINT: + case PLIST_REAL: + buff = (char *) &data->intval; //works also for real as we use an union + size = 8; + break; + case PLIST_KEY: + case PLIST_STRING: + buff = data->strval; + size = strlen(buff); + break; + case PLIST_DATA: + case PLIST_ARRAY: + case PLIST_DICT: + //for these types only hash pointer + buff = (char *) &key; + size = sizeof(gconstpointer); + break; + case PLIST_DATE: + buff = (char *) &(data->timeval); + size = data->length; + break; + default: + break; + } + + //now perform hash + for (i = 0; i < size; buff++, i++) + hash = hash << 7 ^ (*buff); + + return hash; } -struct serialize_s { - GPtrArray *objects; - GHashTable *ref_table; +struct serialize_s +{ + GPtrArray *objects; + GHashTable *ref_table; }; static void serialize_plist(GNode * node, gpointer data) { - uint64_t *index_val = NULL; - struct serialize_s *ser = (struct serialize_s *) data; - uint64_t current_index = ser->objects->len; - - //first check that node is not yet in objects - gpointer val = g_hash_table_lookup(ser->ref_table, node); - if (val) { - //data is already in table - return; - } - //insert new ref - index_val = (uint64_t *) malloc(sizeof(uint64_t)); - *index_val = current_index; - g_hash_table_insert(ser->ref_table, node, index_val); - - //now append current node to object array - g_ptr_array_add(ser->objects, node); - - //now recurse on children - g_node_children_foreach(node, G_TRAVERSE_ALL, serialize_plist, data); - return; + uint64_t *index_val = NULL; + struct serialize_s *ser = (struct serialize_s *) data; + uint64_t current_index = ser->objects->len; + + //first check that node is not yet in objects + gpointer val = g_hash_table_lookup(ser->ref_table, node); + if (val) + { + //data is already in table + return; + } + //insert new ref + index_val = (uint64_t *) malloc(sizeof(uint64_t)); + *index_val = current_index; + g_hash_table_insert(ser->ref_table, node, index_val); + + //now append current node to object array + g_ptr_array_add(ser->objects, node); + + //now recurse on children + g_node_children_foreach(node, G_TRAVERSE_ALL, serialize_plist, data); + return; } static gboolean free_index(gpointer key, gpointer value, gpointer user_data) { - free((uint64_t *) value); - return TRUE; + free((uint64_t *) value); + return TRUE; } #define Log2(x) (x == 8 ? 3 : (x == 4 ? 2 : (x == 2 ? 1 : 0))) static void write_int(GByteArray * bplist, uint64_t val) { - uint64_t size = get_needed_bytes(val); - uint8_t *buff = NULL; - //do not write 3bytes int node - if (size == 3) - size++; - buff = (uint8_t *) malloc(sizeof(uint8_t) + size); - buff[0] = BPLIST_UINT | Log2(size); - memcpy(buff + 1, &val, size); - byte_convert(buff + 1, size); - g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); - free(buff); + uint64_t size = get_needed_bytes(val); + uint8_t *buff = NULL; + //do not write 3bytes int node + if (size == 3) + size++; + buff = (uint8_t *) malloc(sizeof(uint8_t) + size); + buff[0] = BPLIST_UINT | Log2(size); + memcpy(buff + 1, &val, size); + byte_convert(buff + 1, size); + g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); + free(buff); } static void write_real(GByteArray * bplist, double val) { - uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space - uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); - buff[0] = BPLIST_REAL | Log2(size); - if (size == sizeof(double)) { - memcpy(buff + 1, &val, size); - } else if (size == sizeof(float)) { - float tmpval = (float) val; - memcpy(buff + 1, &tmpval, size); - } - byte_convert(buff + 1, size); - g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); - free(buff); + uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space + uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); + buff[0] = BPLIST_REAL | Log2(size); + if (size == sizeof(double)) + { + memcpy(buff + 1, &val, size); + } + else if (size == sizeof(float)) + { + float tmpval = (float) val; + memcpy(buff + 1, &tmpval, size); + } + byte_convert(buff + 1, size); + g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); + free(buff); } static void write_date(GByteArray * bplist, double val) { - uint64_t size = 8; //dates always use 8 bytes - uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); - buff[0] = BPLIST_DATE | Log2(size); - memcpy(buff + 1, &val, size); - byte_convert(buff + 1, size); - g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); - free(buff); + uint64_t size = 8; //dates always use 8 bytes + uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); + buff[0] = BPLIST_DATE | Log2(size); + memcpy(buff + 1, &val, size); + byte_convert(buff + 1, size); + g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); + free(buff); } static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size) { - uint8_t *buff = NULL; - uint8_t marker = mark | (size < 15 ? size : 0xf); - g_byte_array_append(bplist, &marker, sizeof(uint8_t)); - if (size >= 15) { - GByteArray *int_buff = g_byte_array_new(); - write_int(int_buff, size); - g_byte_array_append(bplist, int_buff->data, int_buff->len); - g_byte_array_free(int_buff, TRUE); - } - buff = (uint8_t *) malloc(size); - memcpy(buff, val, size); - g_byte_array_append(bplist, buff, size); - free(buff); + uint8_t *buff = NULL; + uint8_t marker = mark | (size < 15 ? size : 0xf); + g_byte_array_append(bplist, &marker, sizeof(uint8_t)); + if (size >= 15) + { + GByteArray *int_buff = g_byte_array_new(); + write_int(int_buff, size); + g_byte_array_append(bplist, int_buff->data, int_buff->len); + g_byte_array_free(int_buff, TRUE); + } + buff = (uint8_t *) malloc(size); + memcpy(buff, val, size); + g_byte_array_append(bplist, buff, size); + free(buff); } static void write_data(GByteArray * bplist, uint8_t * val, uint64_t size) { - write_raw_data(bplist, BPLIST_DATA, val, size); + write_raw_data(bplist, BPLIST_DATA, val, size); } static void write_string(GByteArray * bplist, char *val) { - uint64_t size = strlen(val); - write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size); + uint64_t size = strlen(val); + write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size); } static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size) { - uint64_t i = 0; - uint64_t size2 = size * sizeof(gunichar2); - uint8_t *buff = (uint8_t *) malloc(size2); - memcpy(buff, val, size2); - for (i = 0; i < size; i++) - byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2)); - write_raw_data(bplist, BPLIST_STRING, buff, size2); + uint64_t i = 0; + uint64_t size2 = size * sizeof(gunichar2); + uint8_t *buff = (uint8_t *) malloc(size2); + memcpy(buff, val, size2); + for (i = 0; i < size; i++) + byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2)); + write_raw_data(bplist, BPLIST_STRING, buff, size2); } static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) { - uint64_t idx = 0; - uint8_t *buff = NULL; - - GNode *cur = NULL; - uint64_t i = 0; - - uint64_t size = g_node_n_children(node); - uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf); - g_byte_array_append(bplist, &marker, sizeof(uint8_t)); - if (size >= 15) { - GByteArray *int_buff = g_byte_array_new(); - write_int(int_buff, size); - g_byte_array_append(bplist, int_buff->data, int_buff->len); - g_byte_array_free(int_buff, TRUE); - } - - buff = (uint8_t *) malloc(size * dict_param_size); - - for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) { - idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); - memcpy(buff + i * dict_param_size, &idx, dict_param_size); - byte_convert(buff + i * dict_param_size, dict_param_size); - } - - //now append to bplist - g_byte_array_append(bplist, buff, size * dict_param_size); - free(buff); + uint64_t idx = 0; + uint8_t *buff = NULL; + + GNode *cur = NULL; + uint64_t i = 0; + + uint64_t size = g_node_n_children(node); + uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf); + g_byte_array_append(bplist, &marker, sizeof(uint8_t)); + if (size >= 15) + { + GByteArray *int_buff = g_byte_array_new(); + write_int(int_buff, size); + g_byte_array_append(bplist, int_buff->data, int_buff->len); + g_byte_array_free(int_buff, TRUE); + } + + buff = (uint8_t *) malloc(size * dict_param_size); + + for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) + { + idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); + memcpy(buff + i * dict_param_size, &idx, dict_param_size); + byte_convert(buff + i * dict_param_size, dict_param_size); + } + + //now append to bplist + g_byte_array_append(bplist, buff, size * dict_param_size); + free(buff); } static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) { - uint64_t idx1 = 0; - uint64_t idx2 = 0; - uint8_t *buff = NULL; - - GNode *cur = NULL; - uint64_t i = 0; - - uint64_t size = g_node_n_children(node) / 2; - uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf); - g_byte_array_append(bplist, &marker, sizeof(uint8_t)); - if (size >= 15) { - GByteArray *int_buff = g_byte_array_new(); - write_int(int_buff, size); - g_byte_array_append(bplist, int_buff->data, int_buff->len); - g_byte_array_free(int_buff, TRUE); - } - - buff = (uint8_t *) malloc(size * 2 * dict_param_size); - - for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) { - idx1 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); - memcpy(buff + i * dict_param_size, &idx1, dict_param_size); - byte_convert(buff + i * dict_param_size, dict_param_size); - - idx2 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur->next)); - memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size); - byte_convert(buff + (i + size) * dict_param_size, dict_param_size); - } - - //now append to bplist - g_byte_array_append(bplist, buff, size * 2 * dict_param_size); - free(buff); + uint64_t idx1 = 0; + uint64_t idx2 = 0; + uint8_t *buff = NULL; + + GNode *cur = NULL; + uint64_t i = 0; + + uint64_t size = g_node_n_children(node) / 2; + uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf); + g_byte_array_append(bplist, &marker, sizeof(uint8_t)); + if (size >= 15) + { + GByteArray *int_buff = g_byte_array_new(); + write_int(int_buff, size); + g_byte_array_append(bplist, int_buff->data, int_buff->len); + g_byte_array_free(int_buff, TRUE); + } + + buff = (uint8_t *) malloc(size * 2 * dict_param_size); + + for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) + { + idx1 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); + memcpy(buff + i * dict_param_size, &idx1, dict_param_size); + byte_convert(buff + i * dict_param_size, dict_param_size); + + idx2 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur->next)); + memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size); + byte_convert(buff + (i + size) * dict_param_size, dict_param_size); + } + + //now append to bplist + g_byte_array_append(bplist, buff, size * 2 * dict_param_size); + free(buff); } void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) { - GPtrArray *objects = NULL; - GHashTable *ref_table = NULL; - struct serialize_s ser_s; - uint8_t offset_size = 0; - uint8_t dict_param_size = 0; - uint64_t num_objects = 0; - uint64_t root_object = 0; - uint64_t offset_table_index = 0; - GByteArray *bplist_buff = NULL; - uint64_t i = 0; - uint8_t *buff = NULL; - uint64_t *offsets = NULL; - uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 }; - uint8_t trailer[BPLIST_TRL_SIZE]; - //for string - glong len = 0; - int type = 0; - glong items_read = 0; - glong items_written = 0; - GError *error = NULL; - gunichar2 *unicodestr = NULL; - - //check for valid input - if (!plist || !plist_bin || *plist_bin || !length) - return; - - //list of objects - objects = g_ptr_array_new(); - //hashtable to write only once same nodes - ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); - - //serialize plist - ser_s.objects = objects; - ser_s.ref_table = ref_table; - serialize_plist(plist, &ser_s); - - //now stream to output buffer - offset_size = 0; //unknown yet - dict_param_size = get_needed_bytes(objects->len); - num_objects = objects->len; - root_object = 0; //root is first in list - offset_table_index = 0; //unknown yet - - //setup a dynamic bytes array to store bplist in - bplist_buff = g_byte_array_new(); - - //set magic number and version - g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); - g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); - - //write objects and table - offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t)); - for (i = 0; i < num_objects; i++) { - - plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); - offsets[i] = bplist_buff->len; - - switch (data->type) { - case PLIST_BOOLEAN: - buff = (uint8_t *) malloc(sizeof(uint8_t)); - buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; - g_byte_array_append(bplist_buff, buff, sizeof(uint8_t)); - free(buff); - break; - - case PLIST_UINT: - write_int(bplist_buff, data->intval); - break; - - case PLIST_REAL: - write_real(bplist_buff, data->realval); - break; - - case PLIST_KEY: - case PLIST_STRING: - len = strlen(data->strval); - type = xmlDetectCharEncoding(data->strval, len); - if (XML_CHAR_ENCODING_UTF8 == type) { - unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); - write_unicode(bplist_buff, unicodestr, items_written); - g_free(unicodestr); - } else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { - write_string(bplist_buff, data->strval); - } - break; - case PLIST_DATA: - write_data(bplist_buff, data->buff, data->length); - case PLIST_ARRAY: - write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); - break; - case PLIST_DICT: - write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); - break; - case PLIST_DATE: - write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC); - break; - default: - break; - } - } - - //free intermediate objects - g_hash_table_foreach_remove(ref_table, free_index, NULL); - g_ptr_array_free(objects, TRUE); - g_hash_table_destroy(ref_table); - - //write offsets - offset_size = get_needed_bytes(bplist_buff->len); - offset_table_index = bplist_buff->len; - for (i = 0; i < num_objects; i++) { - uint8_t *offsetbuff = (uint8_t *) malloc(offset_size); - memcpy(offsetbuff, offsets + i, offset_size); - byte_convert(offsetbuff, offset_size); - g_byte_array_append(bplist_buff, offsetbuff, offset_size); - free(offsetbuff); - } - - //experimental pad to reflect apple's files - g_byte_array_append(bplist_buff, pad, 6); - - //setup trailer - num_objects = GUINT64_FROM_BE(num_objects); - root_object = GUINT64_FROM_BE(root_object); - offset_table_index = GUINT64_FROM_BE(offset_table_index); - - memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); - memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); - memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); - memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t)); - memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t)); - - g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE); - - //duplicate buffer - *plist_bin = (char *) malloc(bplist_buff->len); - memcpy(*plist_bin, bplist_buff->data, bplist_buff->len); - *length = bplist_buff->len; - - g_byte_array_free(bplist_buff, TRUE); - free(offsets); + GPtrArray *objects = NULL; + GHashTable *ref_table = NULL; + struct serialize_s ser_s; + uint8_t offset_size = 0; + uint8_t dict_param_size = 0; + uint64_t num_objects = 0; + uint64_t root_object = 0; + uint64_t offset_table_index = 0; + GByteArray *bplist_buff = NULL; + uint64_t i = 0; + uint8_t *buff = NULL; + uint64_t *offsets = NULL; + uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 }; + uint8_t trailer[BPLIST_TRL_SIZE]; + //for string + glong len = 0; + int type = 0; + glong items_read = 0; + glong items_written = 0; + GError *error = NULL; + gunichar2 *unicodestr = NULL; + + //check for valid input + if (!plist || !plist_bin || *plist_bin || !length) + return; + + //list of objects + objects = g_ptr_array_new(); + //hashtable to write only once same nodes + ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); + + //serialize plist + ser_s.objects = objects; + ser_s.ref_table = ref_table; + serialize_plist(plist, &ser_s); + + //now stream to output buffer + offset_size = 0; //unknown yet + dict_param_size = get_needed_bytes(objects->len); + num_objects = objects->len; + root_object = 0; //root is first in list + offset_table_index = 0; //unknown yet + + //setup a dynamic bytes array to store bplist in + bplist_buff = g_byte_array_new(); + + //set magic number and version + g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); + g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); + + //write objects and table + offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t)); + for (i = 0; i < num_objects; i++) + { + + plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); + offsets[i] = bplist_buff->len; + + switch (data->type) + { + case PLIST_BOOLEAN: + buff = (uint8_t *) malloc(sizeof(uint8_t)); + buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; + g_byte_array_append(bplist_buff, buff, sizeof(uint8_t)); + free(buff); + break; + + case PLIST_UINT: + write_int(bplist_buff, data->intval); + break; + + case PLIST_REAL: + write_real(bplist_buff, data->realval); + break; + + case PLIST_KEY: + case PLIST_STRING: + len = strlen(data->strval); + type = xmlDetectCharEncoding(data->strval, len); + if (XML_CHAR_ENCODING_UTF8 == type) + { + unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); + write_unicode(bplist_buff, unicodestr, items_written); + g_free(unicodestr); + } + else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) + { + write_string(bplist_buff, data->strval); + } + break; + case PLIST_DATA: + write_data(bplist_buff, data->buff, data->length); + case PLIST_ARRAY: + write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); + break; + case PLIST_DICT: + write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); + break; + case PLIST_DATE: + write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC); + break; + default: + break; + } + } + + //free intermediate objects + g_hash_table_foreach_remove(ref_table, free_index, NULL); + g_ptr_array_free(objects, TRUE); + g_hash_table_destroy(ref_table); + + //write offsets + offset_size = get_needed_bytes(bplist_buff->len); + offset_table_index = bplist_buff->len; + for (i = 0; i < num_objects; i++) + { + uint8_t *offsetbuff = (uint8_t *) malloc(offset_size); + memcpy(offsetbuff, offsets + i, offset_size); + byte_convert(offsetbuff, offset_size); + g_byte_array_append(bplist_buff, offsetbuff, offset_size); + free(offsetbuff); + } + + //experimental pad to reflect apple's files + g_byte_array_append(bplist_buff, pad, 6); + + //setup trailer + num_objects = GUINT64_FROM_BE(num_objects); + root_object = GUINT64_FROM_BE(root_object); + offset_table_index = GUINT64_FROM_BE(offset_table_index); + + memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); + memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); + memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); + memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t)); + memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t)); + + g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE); + + //duplicate buffer + *plist_bin = (char *) malloc(bplist_buff->len); + memcpy(*plist_bin, bplist_buff->data, bplist_buff->len); + *length = bplist_buff->len; + + g_byte_array_free(bplist_buff, TRUE); + free(offsets); } 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 @@ plist_t plist_new_node(plist_data_t data) { - return (plist_t) g_node_new(data); + return (plist_t) g_node_new(data); } plist_data_t plist_get_data(const plist_t node) { - if (!node) - return NULL; - return ((GNode *) node)->data; + if (!node) + return NULL; + return ((GNode *) node)->data; } plist_data_t plist_new_plist_data(void) { - plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1); - return data; + plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1); + return data; } static void plist_free_data(plist_data_t data) { - if (data) { - switch (data->type) { - case PLIST_KEY: - case PLIST_STRING: - free(data->strval); - break; - case PLIST_DATA: - free(data->buff); - break; - default: - break; - } - free(data); - } + if (data) + { + switch (data->type) + { + case PLIST_KEY: + case PLIST_STRING: + free(data->strval); + break; + case PLIST_DATA: + free(data->buff); + break; + default: + break; + } + free(data); + } } static void plist_free_node(GNode * node, gpointer none) { plist_data_t data = NULL; - g_node_unlink(node); - data = plist_get_data(node); - plist_free_data(data); - node->data = NULL; - g_node_children_foreach(node, G_TRAVERSE_ALL, plist_free_node, NULL); + g_node_unlink(node); + data = plist_get_data(node); + plist_free_data(data); + node->data = NULL; + g_node_children_foreach(node, G_TRAVERSE_ALL, plist_free_node, NULL); } plist_t plist_new_dict(void) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DICT; - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DICT; + return plist_new_node(data); } plist_t plist_new_array(void) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_ARRAY; - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_ARRAY; + return plist_new_node(data); } //These nodes should not be handled by users static plist_t plist_new_key(const char *val) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_KEY; - data->strval = strdup(val); - data->length = strlen(val); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_KEY; + data->strval = strdup(val); + data->length = strlen(val); + return plist_new_node(data); } plist_t plist_new_string(const char *val) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_STRING; - data->strval = strdup(val); - data->length = strlen(val); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_STRING; + data->strval = strdup(val); + data->length = strlen(val); + return plist_new_node(data); } plist_t plist_new_bool(uint8_t val) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_BOOLEAN; - data->boolval = val; - data->length = sizeof(uint8_t); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_BOOLEAN; + data->boolval = val; + data->length = sizeof(uint8_t); + return plist_new_node(data); } plist_t plist_new_uint(uint64_t val) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_UINT; - data->intval = val; - data->length = sizeof(uint64_t); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_UINT; + data->intval = val; + data->length = sizeof(uint64_t); + return plist_new_node(data); } plist_t plist_new_real(double val) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_REAL; - data->realval = val; - data->length = sizeof(double); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_REAL; + data->realval = val; + data->length = sizeof(double); + return plist_new_node(data); } plist_t plist_new_data(const char *val, uint64_t length) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DATA; - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, val, length); - data->length = length; - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DATA; + data->buff = (uint8_t *) malloc(length); + memcpy(data->buff, val, length); + data->length = length; + return plist_new_node(data); } plist_t plist_new_date(int32_t sec, int32_t usec) { - plist_data_t data = plist_new_plist_data(); - data->type = PLIST_DATE; - data->timeval.tv_sec = sec; - data->timeval.tv_usec = usec; - data->length = sizeof(GTimeVal); - return plist_new_node(data); + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DATE; + data->timeval.tv_sec = sec; + data->timeval.tv_usec = usec; + data->length = sizeof(GTimeVal); + return plist_new_node(data); } void plist_free(plist_t plist) { - if (plist) { - plist_free_node(plist, NULL); - g_node_destroy(plist); - } + if (plist) + { + plist_free_node(plist, NULL); + g_node_destroy(plist); + } } static void plist_copy_node(GNode * node, gpointer parent_node_ptr) { plist_type node_type = PLIST_NONE; - plist_t newnode = NULL; - plist_data_t data = plist_get_data(node); - plist_data_t newdata = plist_new_plist_data(); - - assert(data); // plist should always have data - - memcpy(newdata, data, sizeof(struct plist_data_s)); - - node_type = plist_get_node_type(node); - if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY) { - switch (node_type) { - case PLIST_DATA: - newdata->buff = (uint8_t *) malloc(data->length); - memcpy(newdata->buff, data->buff, data->length); - case PLIST_KEY: - case PLIST_STRING: - newdata->strval = strdup((char *) data->strval); - default: - break; - } - } - newnode = plist_new_node(newdata); - - if (*(plist_t*)parent_node_ptr) { - g_node_append(*(plist_t*)parent_node_ptr, newnode); - } - else { - *(plist_t*)parent_node_ptr = newnode; - } - - g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, &newnode); + plist_t newnode = NULL; + plist_data_t data = plist_get_data(node); + plist_data_t newdata = plist_new_plist_data(); + + assert(data); // plist should always have data + + memcpy(newdata, data, sizeof(struct plist_data_s)); + + node_type = plist_get_node_type(node); + if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY) + { + switch (node_type) + { + case PLIST_DATA: + newdata->buff = (uint8_t *) malloc(data->length); + memcpy(newdata->buff, data->buff, data->length); + case PLIST_KEY: + case PLIST_STRING: + newdata->strval = strdup((char *) data->strval); + default: + break; + } + } + newnode = plist_new_node(newdata); + + if (*(plist_t*)parent_node_ptr) + { + g_node_append(*(plist_t*)parent_node_ptr, newnode); + } + else + { + *(plist_t*)parent_node_ptr = newnode; + } + + g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, &newnode); } plist_t plist_copy(plist_t node) { - plist_t copied = NULL; - plist_copy_node(node, &copied); - return copied; + plist_t copied = NULL; + plist_copy_node(node, &copied); + return copied; } uint32_t plist_array_get_size(plist_t node) { - uint32_t ret = 0; - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - ret = g_node_n_children(node); - } - return ret; + uint32_t ret = 0; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + ret = g_node_n_children(node); + } + return ret; } plist_t plist_array_get_item(plist_t node, uint32_t n) { - plist_t ret = NULL; - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - ret = (plist_t)g_node_nth_child(node, n); - } - return ret; + plist_t ret = NULL; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + ret = (plist_t)g_node_nth_child(node, n); + } + return ret; } uint32_t plist_array_get_item_index(plist_t node) { - plist_t father = plist_get_parent(node); - if (PLIST_ARRAY == plist_get_node_type(father)) { - return g_node_child_position(father, node); - } + plist_t father = plist_get_parent(node); + if (PLIST_ARRAY == plist_get_node_type(father)) + { + return g_node_child_position(father, node); + } return 0; } void plist_array_set_item(plist_t node, plist_t item, uint32_t n) { - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - plist_t old_item = plist_array_get_item(node, n); - if (old_item) { - plist_free_node(old_item, NULL); - old_item = NULL; - plist_copy_node(item, &old_item); - } - } - return; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + plist_t old_item = plist_array_get_item(node, n); + if (old_item) + { + plist_free_node(old_item, NULL); + old_item = NULL; + plist_copy_node(item, &old_item); + } + } + return; } void plist_array_append_item(plist_t node, plist_t item) { - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - g_node_append(node, item); - } - return; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + g_node_append(node, item); + } + return; } void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) { - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - g_node_insert(node, n, item); - } - return; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + g_node_insert(node, n, item); + } + return; } void plist_array_remove_item(plist_t node, uint32_t n) { - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - plist_t old_item = plist_array_get_item(node, n); - if (old_item) { - plist_free(old_item); - } - } - return; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + plist_t old_item = plist_array_get_item(node, n); + if (old_item) + { + plist_free(old_item); + } + } + return; } uint32_t plist_dict_get_size(plist_t node) { - uint32_t ret = 0; - if (node && PLIST_DICT == plist_get_node_type(node)) { - ret = g_node_n_children(node) / 2; - } - return ret; + uint32_t ret = 0; + if (node && PLIST_DICT == plist_get_node_type(node)) + { + ret = g_node_n_children(node) / 2; + } + return ret; } void plist_dict_new_iter(plist_t node, plist_dict_iter *iter) { - if (iter && *iter == NULL) { - *iter = malloc(sizeof(uint32_t)); - *((uint32_t*)(*iter)) = 0; - } - return; + if (iter && *iter == NULL) + { + *iter = malloc(sizeof(uint32_t)); + *((uint32_t*)(*iter)) = 0; + } + return; } void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val) { - uint32_t* iter_int = (uint32_t*) iter; + uint32_t* iter_int = (uint32_t*) iter; - if (key) { - *key = NULL; - } - if (val) { - *val = NULL; - } + if (key) + { + *key = NULL; + } + if (val) + { + *val = NULL; + } - if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < g_node_n_children(node)) { + if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < g_node_n_children(node)) + { - if (key) { - plist_get_key_val((plist_t)g_node_nth_child(node, *iter_int), key); - } + if (key) + { + plist_get_key_val((plist_t)g_node_nth_child(node, *iter_int), key); + } - if (val) { - *val = (plist_t) g_node_nth_child(node, *iter_int + 1); - } + if (val) + { + *val = (plist_t) g_node_nth_child(node, *iter_int + 1); + } - *iter_int += 2; - } - return; + *iter_int += 2; + } + return; } void plist_dict_get_item_key(plist_t node, char **key) { - plist_t father = plist_get_parent(node); - if (PLIST_DICT == plist_get_node_type(father)) { - plist_get_key_val( (plist_t) g_node_prev_sibling(node), key); - } + plist_t father = plist_get_parent(node); + if (PLIST_DICT == plist_get_node_type(father)) + { + plist_get_key_val( (plist_t) g_node_prev_sibling(node), key); + } } plist_t plist_dict_get_item(plist_t node, const char* key) { - plist_t ret = NULL; + plist_t ret = NULL; - if (node && PLIST_DICT == plist_get_node_type(node)) { + if (node && PLIST_DICT == plist_get_node_type(node)) + { - plist_t current = NULL; - for (current = (plist_t)g_node_first_child(node); - current; - current = (plist_t)g_node_next_sibling(g_node_next_sibling(current))) { + plist_t current = NULL; + for (current = (plist_t)g_node_first_child(node); + current; + current = (plist_t)g_node_next_sibling(g_node_next_sibling(current))) + { - plist_data_t data = plist_get_data(current); + plist_data_t data = plist_get_data(current); assert( PLIST_KEY == plist_get_node_type(current) ); - if (data && !strcmp(key, data->strval)) { - ret = (plist_t)g_node_next_sibling(current); - break; - } - } - } - return ret; + if (data && !strcmp(key, data->strval)) + { + ret = (plist_t)g_node_next_sibling(current); + break; + } + } + } + return ret; } void plist_dict_set_item(plist_t node, const char* key, plist_t item) { - if (node && PLIST_DICT == plist_get_node_type(node)) { - plist_t old_item = plist_dict_get_item(node, key); - if (old_item) { - plist_free_node(old_item, NULL); - old_item = NULL; - plist_copy_node(item, &old_item); - } - } - return; + if (node && PLIST_DICT == plist_get_node_type(node)) + { + plist_t old_item = plist_dict_get_item(node, key); + if (old_item) + { + plist_free_node(old_item, NULL); + old_item = NULL; + plist_copy_node(item, &old_item); + } + } + return; } void plist_dict_insert_item(plist_t node, const char* key, plist_t item) { - if (node && PLIST_DICT == plist_get_node_type(node)) { - g_node_append(node, plist_new_key(key)); - g_node_append(node, item); - } - return; + if (node && PLIST_DICT == plist_get_node_type(node)) + { + g_node_append(node, plist_new_key(key)); + g_node_append(node, item); + } + return; } void plist_dict_remove_item(plist_t node, const char* key) { - if (node && PLIST_DICT == plist_get_node_type(node)) { - plist_t old_item = plist_dict_get_item(node, key); - if (old_item) { - plist_t key_node = g_node_prev_sibling(old_item); - plist_free(key_node); - plist_free(old_item); - } - } - return; + if (node && PLIST_DICT == plist_get_node_type(node)) + { + plist_t old_item = plist_dict_get_item(node, key); + if (old_item) + { + plist_t key_node = g_node_prev_sibling(old_item); + plist_free(key_node); + plist_free(old_item); + } + } + return; } static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length) { - char res = FALSE; - switch (type) { - case PLIST_BOOLEAN: - res = data->boolval == *((char *) value) ? TRUE : FALSE; - break; - case PLIST_UINT: - res = data->intval == *((uint64_t *) value) ? TRUE : FALSE; - break; - case PLIST_REAL: - res = data->realval == *((double *) value) ? TRUE : FALSE; - break; - case PLIST_KEY: - case PLIST_STRING: - res = !strcmp(data->strval, ((char *) value)); - break; - case PLIST_DATA: - res = !memcmp(data->buff, (char *) value, length); - break; - case PLIST_DATE: - res = !memcmp(&(data->timeval), value, sizeof(GTimeVal)); - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } - return res; + char res = FALSE; + switch (type) + { + case PLIST_BOOLEAN: + res = data->boolval == *((char *) value) ? TRUE : FALSE; + break; + case PLIST_UINT: + res = data->intval == *((uint64_t *) value) ? TRUE : FALSE; + break; + case PLIST_REAL: + res = data->realval == *((double *) value) ? TRUE : FALSE; + break; + case PLIST_KEY: + case PLIST_STRING: + res = !strcmp(data->strval, ((char *) value)); + break; + case PLIST_DATA: + res = !memcmp(data->buff, (char *) value, length); + break; + case PLIST_DATE: + res = !memcmp(&(data->timeval), value, sizeof(GTimeVal)); + break; + case PLIST_ARRAY: + case PLIST_DICT: + default: + break; + } + return res; } plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) { - plist_t current = plist; - plist_type type = PLIST_NONE; - uint32_t i = 0; - - for (i = 0; i < length && current; i++) { - type = plist_get_node_type(current); - - if (type == PLIST_ARRAY) { - uint32_t index = va_arg(v, uint32_t); - current = plist_array_get_item(current, index); - } - else if (type == PLIST_DICT) { - const char* key = va_arg(v, const char*); - current = plist_dict_get_item(current, key); - } - } - return current; + plist_t current = plist; + plist_type type = PLIST_NONE; + uint32_t i = 0; + + for (i = 0; i < length && current; i++) + { + type = plist_get_node_type(current); + + if (type == PLIST_ARRAY) + { + uint32_t index = va_arg(v, uint32_t); + current = plist_array_get_item(current, index); + } + else if (type == PLIST_DICT) + { + const char* key = va_arg(v, const char*); + current = plist_dict_get_item(current, key); + } + } + return current; } plist_t plist_access_path(plist_t plist, uint32_t length, ...) { - plist_t ret = NULL; - va_list v; - - va_start(v, length); - ret = plist_access_pathv(plist, length, v); - va_end(v); - return ret; + plist_t ret = NULL; + va_list v; + + va_start(v, length); + ret = plist_access_pathv(plist, length, v); + va_end(v); + return ret; } static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) { - plist_data_t data = NULL; - - if (!node) - return; - - data = plist_get_data(node); - - *type = data->type; - *length = data->length; - - switch (*type) { - case PLIST_BOOLEAN: - *((char *) value) = data->boolval; - break; - case PLIST_UINT: - *((uint64_t *) value) = data->intval; - break; - case PLIST_REAL: - *((double *) value) = data->realval; - break; - case PLIST_KEY: - case PLIST_STRING: - *((char **) value) = strdup(data->strval); - break; - case PLIST_DATA: - *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); - memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); - break; - case PLIST_DATE: - //exception : here we use memory on the stack since it is just a temporary buffer - ((GTimeVal *) value)->tv_sec = data->timeval.tv_sec; - ((GTimeVal *) value)->tv_usec = data->timeval.tv_usec; - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } + plist_data_t data = NULL; + + if (!node) + return; + + data = plist_get_data(node); + + *type = data->type; + *length = data->length; + + switch (*type) + { + case PLIST_BOOLEAN: + *((char *) value) = data->boolval; + break; + case PLIST_UINT: + *((uint64_t *) value) = data->intval; + break; + case PLIST_REAL: + *((double *) value) = data->realval; + break; + case PLIST_KEY: + case PLIST_STRING: + *((char **) value) = strdup(data->strval); + break; + case PLIST_DATA: + *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t)); + memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t)); + break; + case PLIST_DATE: + //exception : here we use memory on the stack since it is just a temporary buffer + ((GTimeVal *) value)->tv_sec = data->timeval.tv_sec; + ((GTimeVal *) value)->tv_usec = data->timeval.tv_usec; + break; + case PLIST_ARRAY: + case PLIST_DICT: + default: + break; + } } plist_t plist_get_parent(plist_t node) { - return node ? (plist_t) ((GNode *) node)->parent : NULL; + return node ? (plist_t) ((GNode *) node)->parent : NULL; } plist_type plist_get_node_type(plist_t node) { - if (node) { - plist_data_t data = plist_get_data(node); - if (data) - return data->type; - } - return PLIST_NONE; + if (node) + { + plist_data_t data = plist_get_data(node); + if (data) + return data->type; + } + return PLIST_NONE; } void plist_get_key_val(plist_t node, char **val) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_KEY == type) - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == strlen(*val)); + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + if (PLIST_KEY == type) + plist_get_type_and_value(node, &type, (void *) val, &length); + assert(length == strlen(*val)); } void plist_get_string_val(plist_t node, char **val) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_STRING == type) - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == strlen(*val)); + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + if (PLIST_STRING == type) + plist_get_type_and_value(node, &type, (void *) val, &length); + assert(length == strlen(*val)); } void plist_get_bool_val(plist_t node, uint8_t * val) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_BOOLEAN == type) - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(uint8_t)); + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + if (PLIST_BOOLEAN == type) + plist_get_type_and_value(node, &type, (void *) val, &length); + assert(length == sizeof(uint8_t)); } void plist_get_uint_val(plist_t node, uint64_t * val) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_UINT == type) - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(uint64_t)); + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + if (PLIST_UINT == type) + plist_get_type_and_value(node, &type, (void *) val, &length); + assert(length == sizeof(uint64_t)); } void plist_get_real_val(plist_t node, double *val) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - if (PLIST_REAL == type) - plist_get_type_and_value(node, &type, (void *) val, &length); - assert(length == sizeof(double)); + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + if (PLIST_REAL == type) + plist_get_type_and_value(node, &type, (void *) val, &length); + assert(length == sizeof(double)); } void plist_get_data_val(plist_t node, char **val, uint64_t * length) { - plist_type type = plist_get_node_type(node); - if (PLIST_DATA == type) - plist_get_type_and_value(node, &type, (void *) val, length); + plist_type type = plist_get_node_type(node); + if (PLIST_DATA == type) + plist_get_type_and_value(node, &type, (void *) val, length); } void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) { - plist_type type = plist_get_node_type(node); - uint64_t length = 0; - GTimeVal val = { 0, 0 }; - if (PLIST_DATE == type) - plist_get_type_and_value(node, &type, (void *) &val, &length); - assert(length == sizeof(GTimeVal)); - *sec = val.tv_sec; - *usec = val.tv_usec; + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + GTimeVal val = { 0, 0 }; + if (PLIST_DATE == type) + plist_get_type_and_value(node, &type, (void *) &val, &length); + assert(length == sizeof(GTimeVal)); + *sec = val.tv_sec; + *usec = val.tv_usec; } gboolean plist_data_compare(gconstpointer a, gconstpointer b) { - plist_data_t val_a = NULL; - plist_data_t val_b = NULL; - - if (!a || !b) - return FALSE; - - if (!((GNode *) a)->data || !((GNode *) b)->data) - return FALSE; - - val_a = plist_get_data((plist_t) a); - val_b = plist_get_data((plist_t) b); - - if (val_a->type != val_b->type) - return FALSE; - - switch (val_a->type) { - case PLIST_BOOLEAN: - case PLIST_UINT: - case PLIST_REAL: - if (val_a->intval == val_b->intval) //it is an union so this is sufficient - return TRUE; - else - return FALSE; - - case PLIST_KEY: - case PLIST_STRING: - if (!strcmp(val_a->strval, val_b->strval)) - return TRUE; - else - return FALSE; - - case PLIST_DATA: - if (!memcmp(val_a->buff, val_b->buff, val_a->length)) - return TRUE; - else - return FALSE; - case PLIST_ARRAY: - case PLIST_DICT: - //compare pointer - if (a == b) - return TRUE; - else - return FALSE; - break; - case PLIST_DATE: - if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal))) - return TRUE; - else - return FALSE; - default: - break; - } - return FALSE; + plist_data_t val_a = NULL; + plist_data_t val_b = NULL; + + if (!a || !b) + return FALSE; + + if (!((GNode *) a)->data || !((GNode *) b)->data) + return FALSE; + + val_a = plist_get_data((plist_t) a); + val_b = plist_get_data((plist_t) b); + + if (val_a->type != val_b->type) + return FALSE; + + switch (val_a->type) + { + case PLIST_BOOLEAN: + case PLIST_UINT: + case PLIST_REAL: + if (val_a->intval == val_b->intval) //it is an union so this is sufficient + return TRUE; + else + return FALSE; + + case PLIST_KEY: + case PLIST_STRING: + if (!strcmp(val_a->strval, val_b->strval)) + return TRUE; + else + return FALSE; + + case PLIST_DATA: + if (!memcmp(val_a->buff, val_b->buff, val_a->length)) + return TRUE; + else + return FALSE; + case PLIST_ARRAY: + case PLIST_DICT: + //compare pointer + if (a == b) + return TRUE; + else + return FALSE; + break; + case PLIST_DATE: + if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal))) + return TRUE; + else + return FALSE; + default: + break; + } + return FALSE; } char plist_compare_node_value(plist_t node_l, plist_t node_r) { - return plist_data_compare(node_l, node_r); + return plist_data_compare(node_l, node_r); } static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) { - //free previous allocated buffer - plist_data_t data = plist_get_data(node); - assert(data); // a node should always have data attached - - switch (data->type) { - case PLIST_KEY: - case PLIST_STRING: - free(data->strval); - data->strval = NULL; - break; - case PLIST_DATA: - free(data->buff); - data->buff = NULL; - break; - default: - break; - } - - //now handle value - - data->type = type; - data->length = length; - - switch (type) { - case PLIST_BOOLEAN: - data->boolval = *((char *) value); - break; - case PLIST_UINT: - data->intval = *((uint64_t *) value); - break; - case PLIST_REAL: - data->realval = *((double *) value); - break; - case PLIST_KEY: - case PLIST_STRING: - data->strval = strdup((char *) value); - break; - case PLIST_DATA: - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, value, length); - break; - case PLIST_DATE: - data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; - data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } + //free previous allocated buffer + plist_data_t data = plist_get_data(node); + assert(data); // a node should always have data attached + + switch (data->type) + { + case PLIST_KEY: + case PLIST_STRING: + free(data->strval); + data->strval = NULL; + break; + case PLIST_DATA: + free(data->buff); + data->buff = NULL; + break; + default: + break; + } + + //now handle value + + data->type = type; + data->length = length; + + switch (type) + { + case PLIST_BOOLEAN: + data->boolval = *((char *) value); + break; + case PLIST_UINT: + data->intval = *((uint64_t *) value); + break; + case PLIST_REAL: + data->realval = *((double *) value); + break; + case PLIST_KEY: + case PLIST_STRING: + data->strval = strdup((char *) value); + break; + case PLIST_DATA: + data->buff = (uint8_t *) malloc(length); + memcpy(data->buff, value, length); + break; + case PLIST_DATE: + data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; + data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; + break; + case PLIST_ARRAY: + case PLIST_DICT: + default: + break; + } } void plist_set_type(plist_t node, plist_type type) { - if ( g_node_n_children(node) == 0 ) { - plist_data_t data = plist_get_data(node); - plist_free_data( data ); - data = plist_new_plist_data(); - data->type = type; - switch(type){ - case PLIST_BOOLEAN: - data->length = sizeof(uint8_t); - break; - case PLIST_UINT: - data->length = sizeof(uint64_t); - break; - case PLIST_REAL: - data->length = sizeof(double); - break; - case PLIST_DATE: - data->length = sizeof(GTimeVal); - break; - default: - data->length = 0; - break; - } - } + if ( g_node_n_children(node) == 0 ) + { + plist_data_t data = plist_get_data(node); + plist_free_data( data ); + data = plist_new_plist_data(); + data->type = type; + switch (type) + { + case PLIST_BOOLEAN: + data->length = sizeof(uint8_t); + break; + case PLIST_UINT: + data->length = sizeof(uint64_t); + break; + case PLIST_REAL: + data->length = sizeof(double); + break; + case PLIST_DATE: + data->length = sizeof(GTimeVal); + break; + default: + data->length = 0; + break; + } + } } void plist_set_key_val(plist_t node, const char *val) { - plist_set_element_val(node, PLIST_KEY, val, strlen(val)); + plist_set_element_val(node, PLIST_KEY, val, strlen(val)); } void plist_set_string_val(plist_t node, const char *val) { - plist_set_element_val(node, PLIST_STRING, val, strlen(val)); + plist_set_element_val(node, PLIST_STRING, val, strlen(val)); } void plist_set_bool_val(plist_t node, uint8_t val) { - plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); + plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); } void plist_set_uint_val(plist_t node, uint64_t val) { - plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t)); + plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t)); } void plist_set_real_val(plist_t node, double val) { - plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); + plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); } void plist_set_data_val(plist_t node, const char *val, uint64_t length) { - plist_set_element_val(node, PLIST_DATA, val, length); + plist_set_element_val(node, PLIST_DATA, val, length); } void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) { - GTimeVal val = { sec, usec }; - plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal)); + GTimeVal val = { sec, usec }; + plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal)); } //DEPRECATED API BELOW @@ -748,176 +791,187 @@ void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length) { - //only structured types can have children - plist_type node_type = plist_get_node_type(node); - if (node_type == PLIST_DICT || node_type == PLIST_ARRAY) { - //only structured types are allowed to have nulll value - if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY))) { - - plist_t subnode = NULL; - - //now handle value - plist_data_t data = plist_new_plist_data(); - data->type = type; - data->length = length; - - switch (type) { - case PLIST_BOOLEAN: - data->boolval = *((char *) value); - break; - case PLIST_UINT: - data->intval = *((uint64_t *) value); - break; - case PLIST_REAL: - data->realval = *((double *) value); - break; - case PLIST_KEY: - case PLIST_STRING: - data->strval = strdup((char *) value); - break; - case PLIST_DATA: - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, value, length); - break; - case PLIST_DATE: - data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; - data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } - - subnode = plist_new_node(data); - if (node) - g_node_append(node, subnode); - return subnode; - } else - return NULL; - } - return NULL; + //only structured types can have children + plist_type node_type = plist_get_node_type(node); + if (node_type == PLIST_DICT || node_type == PLIST_ARRAY) + { + //only structured types are allowed to have nulll value + if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY))) + { + + plist_t subnode = NULL; + + //now handle value + plist_data_t data = plist_new_plist_data(); + data->type = type; + data->length = length; + + switch (type) + { + case PLIST_BOOLEAN: + data->boolval = *((char *) value); + break; + case PLIST_UINT: + data->intval = *((uint64_t *) value); + break; + case PLIST_REAL: + data->realval = *((double *) value); + break; + case PLIST_KEY: + case PLIST_STRING: + data->strval = strdup((char *) value); + break; + case PLIST_DATA: + data->buff = (uint8_t *) malloc(length); + memcpy(data->buff, value, length); + break; + case PLIST_DATE: + data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; + data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; + break; + case PLIST_ARRAY: + case PLIST_DICT: + default: + break; + } + + subnode = plist_new_node(data); + if (node) + g_node_append(node, subnode); + return subnode; + } + else + return NULL; + } + return NULL; } plist_t plist_get_first_child(plist_t node) { - return (plist_t) g_node_first_child((GNode *) node); + return (plist_t) g_node_first_child((GNode *) node); } plist_t plist_get_next_sibling(plist_t node) { - return (plist_t) g_node_next_sibling((GNode *) node); + return (plist_t) g_node_next_sibling((GNode *) node); } plist_t plist_get_prev_sibling(plist_t node) { - return (plist_t) g_node_prev_sibling((GNode *) node); + return (plist_t) g_node_prev_sibling((GNode *) node); } plist_t plist_get_array_nth_el(plist_t node, uint32_t n) { - plist_t ret = NULL; - if (node && PLIST_ARRAY == plist_get_node_type(node)) { - uint32_t i = 0; - plist_t temp = plist_get_first_child(node); + plist_t ret = NULL; + if (node && PLIST_ARRAY == plist_get_node_type(node)) + { + uint32_t i = 0; + plist_t temp = plist_get_first_child(node); - while (i <= n && temp) { - if (i == n) - ret = temp; - temp = plist_get_next_sibling(temp); - i++; - } - } - return ret; + while (i <= n && temp) + { + if (i == n) + ret = temp; + temp = plist_get_next_sibling(temp); + i++; + } + } + return ret; } plist_t plist_get_dict_el_from_key(plist_t node, const char *key) { - plist_t ret = NULL; - if (node && PLIST_DICT == plist_get_node_type(node)) { + plist_t ret = NULL; + if (node && PLIST_DICT == plist_get_node_type(node)) + { - plist_t key_node = plist_find_node_by_key(node, key); - ret = plist_get_next_sibling(key_node); - } - return ret; + plist_t key_node = plist_find_node_by_key(node, key); + ret = plist_get_next_sibling(key_node); + } + return ret; } void plist_add_sub_node(plist_t node, plist_t subnode) { - if (node && subnode) { - plist_type type = plist_get_node_type(node); - if (type == PLIST_DICT || type == PLIST_ARRAY) - g_node_append(node, subnode); - } + if (node && subnode) + { + plist_type type = plist_get_node_type(node); + if (type == PLIST_DICT || type == PLIST_ARRAY) + g_node_append(node, subnode); + } } void plist_add_sub_key_el(plist_t node, const char *val) { - plist_add_sub_element(node, PLIST_KEY, val, strlen(val)); + plist_add_sub_element(node, PLIST_KEY, val, strlen(val)); } void plist_add_sub_string_el(plist_t node, const char *val) { - plist_add_sub_element(node, PLIST_STRING, val, strlen(val)); + plist_add_sub_element(node, PLIST_STRING, val, strlen(val)); } void plist_add_sub_bool_el(plist_t node, uint8_t val) { - plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); + plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); } void plist_add_sub_uint_el(plist_t node, uint64_t val) { - plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t)); + plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t)); } void plist_add_sub_real_el(plist_t node, double val) { - plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double)); + plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double)); } void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length) { - plist_add_sub_element(node, PLIST_DATA, val, length); + plist_add_sub_element(node, PLIST_DATA, val, length); } void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) { - GTimeVal val = { sec, usec }; - plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); + GTimeVal val = { sec, usec }; + plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); } static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) { - plist_t current = NULL; + plist_t current = NULL; - if (!plist) - return NULL; + if (!plist) + return NULL; - for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { + for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) + { - plist_data_t data = plist_get_data(current); + plist_data_t data = plist_get_data(current); - if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { - return current; - } - if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { - plist_t sub = plist_find_node(current, type, value, length); - if (sub) - return sub; - } - } - return NULL; + if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) + { + return current; + } + if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) + { + plist_t sub = plist_find_node(current, type, value, length); + if (sub) + return sub; + } + } + return NULL; } plist_t plist_find_node_by_key(plist_t plist, const char *value) { - return plist_find_node(plist, PLIST_KEY, value, strlen(value)); + return plist_find_node(plist, PLIST_KEY, value, strlen(value)); } plist_t plist_find_node_by_string(plist_t plist, const char *value) { - return plist_find_node(plist, PLIST_STRING, value, strlen(value)); + return plist_find_node(plist, PLIST_STRING, value, strlen(value)); } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLIST_H @@ -35,17 +35,19 @@ #endif -struct plist_data_s { - union { - char boolval; - uint64_t intval; - double realval; - char *strval; - uint8_t *buff; - GTimeVal timeval; - }; - uint64_t length; - plist_type type; +struct plist_data_s +{ + union + { + char boolval; + uint64_t intval; + double realval; + char *strval; + uint8_t *buff; + GTimeVal timeval; + }; + uint64_t length; + plist_type type; }; 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -50,7 +50,7 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ /** Formats a block of text to be a given indentation and width. - * + * * The total width of the return string will be depth + cols. * * @param buf The string to format. @@ -61,303 +61,323 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ */ static gchar *format_string(const char *buf, int cols, int depth) { - int colw = depth + cols + 1; - int len = strlen(buf); - int nlines = len / cols + 1; - gchar *new_buf = (gchar *) g_malloc0(nlines * colw + depth + 1); - int i = 0; - int j = 0; - - assert(cols >= 0); - assert(depth >= 0); - - // Inserts new lines and tabs at appropriate locations - for (i = 0; i < nlines; i++) { - new_buf[i * colw] = '\n'; - for (j = 0; j < depth; j++) - new_buf[i * colw + 1 + j] = '\t'; - memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, (i + 1) * cols <= len ? cols : len - i * cols); - } - new_buf[len + (1 + depth) * nlines] = '\n'; - - // Inserts final row of indentation and termination character - for (j = 0; j < depth; j++) - new_buf[len + (1 + depth) * nlines + 1 + j] = '\t'; - new_buf[len + (1 + depth) * nlines + depth + 1] = '\0'; - - return new_buf; + int colw = depth + cols + 1; + int len = strlen(buf); + int nlines = len / cols + 1; + gchar *new_buf = (gchar *) g_malloc0(nlines * colw + depth + 1); + int i = 0; + int j = 0; + + assert(cols >= 0); + assert(depth >= 0); + + // Inserts new lines and tabs at appropriate locations + for (i = 0; i < nlines; i++) + { + new_buf[i * colw] = '\n'; + for (j = 0; j < depth; j++) + new_buf[i * colw + 1 + j] = '\t'; + memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, (i + 1) * cols <= len ? cols : len - i * cols); + } + new_buf[len + (1 + depth) * nlines] = '\n'; + + // Inserts final row of indentation and termination character + for (j = 0; j < depth; j++) + new_buf[len + (1 + depth) * nlines + 1 + j] = '\t'; + new_buf[len + (1 + depth) * nlines + depth + 1] = '\0'; + + return new_buf; } -struct xml_node { - xmlNodePtr xml; - uint32_t depth; +struct xml_node +{ + xmlNodePtr xml; + uint32_t depth; }; /** Creates a new plist XML document. - * + * * @return The plist XML document. */ static xmlDocPtr new_xml_plist(void) { - char *plist = strdup(plist_base); - xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist)); + char *plist = strdup(plist_base); + xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist)); - if (!plist_xml) - return NULL; + if (!plist_xml) + return NULL; - free(plist); + free(plist); - return plist_xml; + return plist_xml; } static void node_to_xml(GNode * node, gpointer xml_struct) { - struct xml_node *xstruct = NULL; - plist_data_t node_data = NULL; - - xmlNodePtr child_node = NULL; - char isStruct = FALSE; - - const xmlChar *tag = NULL; - gchar *val = NULL; - - //for base64 - gchar *valtmp = NULL; - - uint32_t i = 0; - - if (!node) - return; - - xstruct = (struct xml_node *) xml_struct; - node_data = plist_get_data(node); - - switch (node_data->type) { - case PLIST_BOOLEAN: - { - if (node_data->boolval) - tag = XPLIST_TRUE; - else - tag = XPLIST_FALSE; - } - break; - - case PLIST_UINT: - tag = XPLIST_INT; - val = g_strdup_printf("%llu", node_data->intval); - break; - - case PLIST_REAL: - tag = XPLIST_REAL; - val = g_strdup_printf("%f", node_data->realval); - break; - - case PLIST_STRING: - tag = XPLIST_STRING; - val = g_strdup(node_data->strval); - break; - - case PLIST_KEY: - tag = XPLIST_KEY; - val = g_strdup((gchar *) node_data->strval); - break; - - case PLIST_DATA: - tag = XPLIST_DATA; - if (node_data->length) { - valtmp = g_base64_encode(node_data->buff, node_data->length); - val = format_string(valtmp, 60, xstruct->depth); - g_free(valtmp); - } - break; - case PLIST_ARRAY: - tag = XPLIST_ARRAY; - isStruct = TRUE; - break; - case PLIST_DICT: - tag = XPLIST_DICT; - isStruct = TRUE; - break; - case PLIST_DATE: - tag = XPLIST_DATE; - val = g_time_val_to_iso8601(&node_data->timeval); - break; - default: - break; - } - - for (i = 0; i < xstruct->depth; i++) { - xmlNodeAddContent(xstruct->xml, BAD_CAST("\t")); - } - child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val)); - xmlNodeAddContent(xstruct->xml, BAD_CAST("\n")); - g_free(val); - - //add return for structured types - if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) - xmlNodeAddContent(child_node, BAD_CAST("\n")); - - if (isStruct) { - struct xml_node child = { child_node, xstruct->depth + 1 }; - g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); - } - //fix indent for structured types - if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) { - - for (i = 0; i < xstruct->depth; i++) { - xmlNodeAddContent(child_node, BAD_CAST("\t")); - } - } - - return; + struct xml_node *xstruct = NULL; + plist_data_t node_data = NULL; + + xmlNodePtr child_node = NULL; + char isStruct = FALSE; + + const xmlChar *tag = NULL; + gchar *val = NULL; + + //for base64 + gchar *valtmp = NULL; + + uint32_t i = 0; + + if (!node) + return; + + xstruct = (struct xml_node *) xml_struct; + node_data = plist_get_data(node); + + switch (node_data->type) + { + case PLIST_BOOLEAN: + { + if (node_data->boolval) + tag = XPLIST_TRUE; + else + tag = XPLIST_FALSE; + } + break; + + case PLIST_UINT: + tag = XPLIST_INT; + val = g_strdup_printf("%llu", node_data->intval); + break; + + case PLIST_REAL: + tag = XPLIST_REAL; + val = g_strdup_printf("%f", node_data->realval); + break; + + case PLIST_STRING: + tag = XPLIST_STRING; + val = g_strdup(node_data->strval); + break; + + case PLIST_KEY: + tag = XPLIST_KEY; + val = g_strdup((gchar *) node_data->strval); + break; + + case PLIST_DATA: + tag = XPLIST_DATA; + if (node_data->length) + { + valtmp = g_base64_encode(node_data->buff, node_data->length); + val = format_string(valtmp, 60, xstruct->depth); + g_free(valtmp); + } + break; + case PLIST_ARRAY: + tag = XPLIST_ARRAY; + isStruct = TRUE; + break; + case PLIST_DICT: + tag = XPLIST_DICT; + isStruct = TRUE; + break; + case PLIST_DATE: + tag = XPLIST_DATE; + val = g_time_val_to_iso8601(&node_data->timeval); + break; + default: + break; + } + + for (i = 0; i < xstruct->depth; i++) + { + xmlNodeAddContent(xstruct->xml, BAD_CAST("\t")); + } + child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val)); + xmlNodeAddContent(xstruct->xml, BAD_CAST("\n")); + g_free(val); + + //add return for structured types + if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) + xmlNodeAddContent(child_node, BAD_CAST("\n")); + + if (isStruct) + { + struct xml_node child = { child_node, xstruct->depth + 1 }; + g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); + } + //fix indent for structured types + if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT) + { + + for (i = 0; i < xstruct->depth; i++) + { + xmlNodeAddContent(child_node, BAD_CAST("\t")); + } + } + + return; } static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) { - xmlNodePtr node = NULL; - plist_data_t data = NULL; - plist_t subnode = NULL; - - //for string - glong len = 0; - int type = 0; - - if (!xml_node) - return; - - for (node = xml_node->children; node; node = node->next) { - - while (node && !xmlStrcmp(node->name, XPLIST_TEXT)) - node = node->next; - if (!node) - break; - - data = plist_new_plist_data(); - subnode = plist_new_node(data); - if (*plist_node) - g_node_append(*plist_node, subnode); - else - *plist_node = subnode; - - if (!xmlStrcmp(node->name, XPLIST_TRUE)) { - data->boolval = TRUE; - data->type = PLIST_BOOLEAN; - data->length = 1; - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_FALSE)) { - data->boolval = FALSE; - data->type = PLIST_BOOLEAN; - data->length = 1; - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_INT)) { - xmlChar *strval = xmlNodeGetContent(node); - data->intval = g_ascii_strtoull((char *) strval, NULL, 0); - data->type = PLIST_UINT; - data->length = 8; - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_REAL)) { - xmlChar *strval = xmlNodeGetContent(node); - data->realval = atof((char *) strval); - data->type = PLIST_REAL; - data->length = 8; - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_DATE)) { - xmlChar *strval = xmlNodeGetContent(node); - g_time_val_from_iso8601((char *) strval, &data->timeval); - data->type = PLIST_DATE; - data->length = sizeof(GTimeVal); - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_STRING)) { - xmlChar *strval = xmlNodeGetContent(node); - len = strlen((char *) strval); - type = xmlDetectCharEncoding(strval, len); - - if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { - data->strval = strdup((char *) strval); - data->type = PLIST_STRING; - data->length = strlen(data->strval); - } - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_KEY)) { - xmlChar *strval = xmlNodeGetContent(node); - data->strval = strdup((char *) strval); - data->type = PLIST_KEY; - data->length = strlen(data->strval); - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_DATA)) { - xmlChar *strval = xmlNodeGetContent(node); - gsize size = 0; - guchar *dec = g_base64_decode((char *) strval, &size); - data->buff = (uint8_t *) malloc(size * sizeof(uint8_t)); - memcpy(data->buff, dec, size * sizeof(uint8_t)); - g_free(dec); - data->length = size; - data->type = PLIST_DATA; - xmlFree(strval); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_ARRAY)) { - data->type = PLIST_ARRAY; - xml_to_node(node, &subnode); - continue; - } - - if (!xmlStrcmp(node->name, XPLIST_DICT)) { - data->type = PLIST_DICT; - xml_to_node(node, &subnode); - continue; - } - } + xmlNodePtr node = NULL; + plist_data_t data = NULL; + plist_t subnode = NULL; + + //for string + glong len = 0; + int type = 0; + + if (!xml_node) + return; + + for (node = xml_node->children; node; node = node->next) + { + + while (node && !xmlStrcmp(node->name, XPLIST_TEXT)) + node = node->next; + if (!node) + break; + + data = plist_new_plist_data(); + subnode = plist_new_node(data); + if (*plist_node) + g_node_append(*plist_node, subnode); + else + *plist_node = subnode; + + if (!xmlStrcmp(node->name, XPLIST_TRUE)) + { + data->boolval = TRUE; + data->type = PLIST_BOOLEAN; + data->length = 1; + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_FALSE)) + { + data->boolval = FALSE; + data->type = PLIST_BOOLEAN; + data->length = 1; + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_INT)) + { + xmlChar *strval = xmlNodeGetContent(node); + data->intval = g_ascii_strtoull((char *) strval, NULL, 0); + data->type = PLIST_UINT; + data->length = 8; + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_REAL)) + { + xmlChar *strval = xmlNodeGetContent(node); + data->realval = atof((char *) strval); + data->type = PLIST_REAL; + data->length = 8; + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_DATE)) + { + xmlChar *strval = xmlNodeGetContent(node); + g_time_val_from_iso8601((char *) strval, &data->timeval); + data->type = PLIST_DATE; + data->length = sizeof(GTimeVal); + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_STRING)) + { + xmlChar *strval = xmlNodeGetContent(node); + len = strlen((char *) strval); + type = xmlDetectCharEncoding(strval, len); + + if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) + { + data->strval = strdup((char *) strval); + data->type = PLIST_STRING; + data->length = strlen(data->strval); + } + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_KEY)) + { + xmlChar *strval = xmlNodeGetContent(node); + data->strval = strdup((char *) strval); + data->type = PLIST_KEY; + data->length = strlen(data->strval); + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_DATA)) + { + xmlChar *strval = xmlNodeGetContent(node); + gsize size = 0; + guchar *dec = g_base64_decode((char *) strval, &size); + data->buff = (uint8_t *) malloc(size * sizeof(uint8_t)); + memcpy(data->buff, dec, size * sizeof(uint8_t)); + g_free(dec); + data->length = size; + data->type = PLIST_DATA; + xmlFree(strval); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_ARRAY)) + { + data->type = PLIST_ARRAY; + xml_to_node(node, &subnode); + continue; + } + + if (!xmlStrcmp(node->name, XPLIST_DICT)) + { + data->type = PLIST_DICT; + xml_to_node(node, &subnode); + continue; + } + } } void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) { - xmlDocPtr plist_doc = NULL; - xmlNodePtr root_node = NULL; - struct xml_node root = { NULL, 0 }; - int size = 0; - - if (!plist || !plist_xml || *plist_xml) - return; - plist_doc = new_xml_plist(); - root_node = xmlDocGetRootElement(plist_doc); - root.xml = root_node; - - node_to_xml(plist, &root); - - xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); - if (size >= 0) - *length = size; - xmlFreeDoc(plist_doc); + xmlDocPtr plist_doc = NULL; + xmlNodePtr root_node = NULL; + struct xml_node root = { NULL, 0 }; + int size = 0; + + if (!plist || !plist_xml || *plist_xml) + return; + plist_doc = new_xml_plist(); + root_node = xmlDocGetRootElement(plist_doc); + root.xml = root_node; + + node_to_xml(plist, &root); + + xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); + if (size >= 0) + *length = size; + xmlFreeDoc(plist_doc); } void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist) { - xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length); - xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); + xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length); + xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); - xml_to_node(root_node, plist); - xmlFreeDoc(plist_doc); + xml_to_node(root_node, plist); + xmlFreeDoc(plist_doc); } 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,110 +33,114 @@ char compare_plist(plist_t node_l, plist_t node_r) { - plist_t cur_l = NULL; - plist_t cur_r = NULL; - int res = 1; + plist_t cur_l = NULL; + plist_t cur_r = NULL; + int res = 1; - cur_l = plist_get_first_child(node_l); - cur_r = plist_get_first_child(node_r); + cur_l = plist_get_first_child(node_l); + cur_r = plist_get_first_child(node_r); - if ( (!cur_l && cur_r) || (cur_l && !cur_r)) - return 0; + if ( (!cur_l && cur_r) || (cur_l && !cur_r)) + return 0; - if ( !cur_l && !cur_r ) - return plist_compare_node_value( node_l, node_r ); + if ( !cur_l && !cur_r ) + return plist_compare_node_value( node_l, node_r ); - while(cur_l && cur_r && res) { + while (cur_l && cur_r && res) + { - if (!(res = compare_plist(cur_l, cur_r))) - return res; + if (!(res = compare_plist(cur_l, cur_r))) + return res; - cur_l = plist_get_next_sibling(cur_l); - cur_r = plist_get_next_sibling(cur_r); - if ( (!cur_l && cur_r) || (cur_l && !cur_r)) - return 0; - } + cur_l = plist_get_next_sibling(cur_l); + cur_r = plist_get_next_sibling(cur_r); + if ( (!cur_l && cur_r) || (cur_l && !cur_r)) + return 0; + } - return res; + return res; } int main(int argc, char *argv[]) { - FILE *iplist1 = NULL; - FILE *iplist2 = NULL; - plist_t root_node1 = NULL; - plist_t root_node2 = NULL; - char *plist_1 = NULL; - char *plist_2 = NULL; - int size_in1 = 0; - int size_in2 = 0; - char *file_in1 = NULL; - char *file_in2 = NULL; - int res = 0; - - struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat)); - struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat)); - - if (argc!= 3) { - printf("Wrong input\n"); - return 1; - } - - file_in1 = argv[1]; - file_in2 = argv[2]; - - //read input file - iplist1 = fopen(file_in1, "rb"); - iplist2 = fopen(file_in2, "rb"); - - if (!iplist1 || !iplist2) { - printf("File does not exists\n"); - return 2; - } - - stat(file_in1, filestats1); - stat(file_in2, filestats2); - - size_in1 = filestats1->st_size; - size_in2 = filestats2->st_size; - - plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1)); - plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1)); - - fread(plist_1, sizeof(char), size_in1, iplist1); - fread(plist_2, sizeof(char), size_in2, iplist2); - - fclose(iplist1); - fclose(iplist2); - - if (memcmp(plist_1, "bplist00", 8) == 0) - plist_from_bin(plist_1, size_in1, &root_node1); - else - plist_from_xml(plist_1, size_in1, &root_node1); - - if (memcmp(plist_2, "bplist00", 8) == 0) - plist_from_bin(plist_2, size_in2, &root_node2); - else - plist_from_xml(plist_2, size_in2, &root_node2); - - if (!root_node1 || !root_node2) { - printf("PList parsing failed\n"); - return 3; - } - else - printf("PList parsing succeeded\n"); - - res = compare_plist(root_node1, root_node2); - - - plist_free(root_node1); - plist_free(root_node2); - - free(plist_1); - free(plist_2); - free(filestats1); - free(filestats2); - - return !res; + FILE *iplist1 = NULL; + FILE *iplist2 = NULL; + plist_t root_node1 = NULL; + plist_t root_node2 = NULL; + char *plist_1 = NULL; + char *plist_2 = NULL; + int size_in1 = 0; + int size_in2 = 0; + char *file_in1 = NULL; + char *file_in2 = NULL; + int res = 0; + + struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat)); + struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat)); + + if (argc!= 3) + { + printf("Wrong input\n"); + return 1; + } + + file_in1 = argv[1]; + file_in2 = argv[2]; + + //read input file + iplist1 = fopen(file_in1, "rb"); + iplist2 = fopen(file_in2, "rb"); + + if (!iplist1 || !iplist2) + { + printf("File does not exists\n"); + return 2; + } + + stat(file_in1, filestats1); + stat(file_in2, filestats2); + + size_in1 = filestats1->st_size; + size_in2 = filestats2->st_size; + + plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1)); + plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1)); + + fread(plist_1, sizeof(char), size_in1, iplist1); + fread(plist_2, sizeof(char), size_in2, iplist2); + + fclose(iplist1); + fclose(iplist2); + + if (memcmp(plist_1, "bplist00", 8) == 0) + plist_from_bin(plist_1, size_in1, &root_node1); + else + plist_from_xml(plist_1, size_in1, &root_node1); + + if (memcmp(plist_2, "bplist00", 8) == 0) + plist_from_bin(plist_2, size_in2, &root_node2); + else + plist_from_xml(plist_2, size_in2, &root_node2); + + if (!root_node1 || !root_node2) + { + printf("PList parsing failed\n"); + return 3; + } + else + printf("PList parsing succeeded\n"); + + res = compare_plist(root_node1, root_node2); + + + plist_free(root_node1); + plist_free(root_node2); + + free(plist_1); + free(plist_2); + free(filestats1); + free(filestats2); + + return !res; } - + 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 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,95 +34,103 @@ int main(int argc, char *argv[]) { - FILE *iplist = NULL; - FILE *oplist = NULL; - plist_t root_node1 = NULL; - plist_t root_node2 = NULL; - char *plist_xml = NULL; - char *plist_xml2 = NULL; - char *plist_bin = NULL; - int size_in = 0; - int size_out = 0; - int size_out2 = 0; - char *file_in = NULL; - struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); - if (argc!= 2) { - printf("Wrong input\n"); - return 1; - } - - file_in = argv[1]; - //read input file - iplist = fopen(file_in, "rb"); - - if (!iplist) { - printf("File does not exists\n"); - return 2; - } - printf("File %s is open\n", file_in); - stat(file_in, filestats); - size_in = filestats->st_size; - plist_xml = (char *) malloc(sizeof(char) * (size_in + 1)); - fread(plist_xml, sizeof(char), size_in, iplist); - fclose(iplist); - - - //convert one format to another - plist_from_xml(plist_xml, size_in, &root_node1); - if (!root_node1) { - printf("PList XML parsing failed\n"); - return 3; - } - else - printf("PList XML parsing succeeded\n"); - - plist_to_bin(root_node1, &plist_bin, &size_out); - if (!plist_bin) { - printf("PList BIN writing failed\n"); - return 4; - } - else - printf("PList BIN writing succeeded\n"); - - plist_from_bin(plist_bin, size_out, &root_node2); - if (!root_node2) { - printf("PList BIN parsing failed\n"); - return 5; - } - else - printf("PList BIN parsing succeeded\n"); - - plist_to_xml(root_node2, &plist_xml2, &size_out2); - if (!plist_xml2) { - printf("PList XML writing failed\n"); - return 8; - } - else - printf("PList XML writing succeeded\n"); - - if (plist_xml2) { - FILE *oplist = NULL; - char file_out[512]; - sprintf(file_out, "%s.out", file_in); - oplist = fopen(file_out, "wb"); - fwrite(plist_xml2, size_out2, sizeof(char), oplist); - fclose(oplist); - } - - plist_free(root_node1); - plist_free(root_node2); - free(plist_bin); - free(plist_xml); - free(plist_xml2); - free(filestats); - - if (size_in != size_out2) { - printf("Size of input and output is different\n"); - printf("Input size : %i\n", size_in); - printf("Output size : %i\n", size_out2); - } - - //success - return 0; + FILE *iplist = NULL; + FILE *oplist = NULL; + plist_t root_node1 = NULL; + plist_t root_node2 = NULL; + char *plist_xml = NULL; + char *plist_xml2 = NULL; + char *plist_bin = NULL; + int size_in = 0; + int size_out = 0; + int size_out2 = 0; + char *file_in = NULL; + struct stat *filestats = (struct stat *) malloc(sizeof(struct stat)); + if (argc!= 2) + { + printf("Wrong input\n"); + return 1; + } + + file_in = argv[1]; + //read input file + iplist = fopen(file_in, "rb"); + + if (!iplist) + { + printf("File does not exists\n"); + return 2; + } + printf("File %s is open\n", file_in); + stat(file_in, filestats); + size_in = filestats->st_size; + plist_xml = (char *) malloc(sizeof(char) * (size_in + 1)); + fread(plist_xml, sizeof(char), size_in, iplist); + fclose(iplist); + + + //convert one format to another + plist_from_xml(plist_xml, size_in, &root_node1); + if (!root_node1) + { + printf("PList XML parsing failed\n"); + return 3; + } + else + printf("PList XML parsing succeeded\n"); + + plist_to_bin(root_node1, &plist_bin, &size_out); + if (!plist_bin) + { + printf("PList BIN writing failed\n"); + return 4; + } + else + printf("PList BIN writing succeeded\n"); + + plist_from_bin(plist_bin, size_out, &root_node2); + if (!root_node2) + { + printf("PList BIN parsing failed\n"); + return 5; + } + else + printf("PList BIN parsing succeeded\n"); + + plist_to_xml(root_node2, &plist_xml2, &size_out2); + if (!plist_xml2) + { + printf("PList XML writing failed\n"); + return 8; + } + else + printf("PList XML writing succeeded\n"); + + if (plist_xml2) + { + FILE *oplist = NULL; + char file_out[512]; + sprintf(file_out, "%s.out", file_in); + oplist = fopen(file_out, "wb"); + fwrite(plist_xml2, size_out2, sizeof(char), oplist); + fclose(oplist); + } + + plist_free(root_node1); + plist_free(root_node2); + free(plist_bin); + free(plist_xml); + free(plist_xml2); + free(filestats); + + if (size_in != size_out2) + { + printf("Size of input and output is different\n"); + printf("Input size : %i\n", size_in); + printf("Output size : %i\n", size_out2); + } + + //success + return 0; } - + |