diff options
Diffstat (limited to 'src')
-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 |
15 files changed, 1838 insertions, 1724 deletions
diff --git a/src/Array.cpp b/src/Array.cpp index dbb1239..bdd26e1 100644 --- a/src/Array.cpp +++ b/src/Array.cpp @@ -7,15 +7,15 @@ * 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); } |