libplist API does not offer a way to clone or modify nodes
Reported by Martin S. | July 8th, 2009 @ 09:16 AM
Attempted to implement lockdown's get/set/remove value request
and came up with those signatures:
iphone_error_t lockdownd_get_value(lockdownd_client_t client, char domain, char key, plist_t value);
iphone_error_t lockdownd_set_value(lockdownd_client_t client, char domain, char key, plist_t value);
iphone_error_t lockdownd_remove_value(lockdownd_client_t client, char domain, char *key);
For instance lockdownd_get_value() returns the value plist subnode for the key named "Value". The issue here was that there is no way in libplist to copy/clone an existing node. This also becomes a problem for set_value(), which actually has to clone the passed value node to construct a lockdown request plist with the value node attached to send to lockdownd.
The intermediate solution was to use plist_to_bin() to serialize the plist subnode into a buffer, then use plist_from_bin() to unserialize the plist into a node again effectively ending up with a cloned node.
Also while thinking about implementing a plist GUI editor similar to the one on Mac OS X, libplist should also provide the necessary functions to deal with modifications of node trees.
I think the missing operations are:
- clone nodes (recurse deep copy) - needed to fix this bug
- modify node values (e.g.: for quick, plist load -> change <string> value, save modified plist)
- remove nodes (Does plist_free() also unlink the "destroyed" node from the parent tree?)
Another question is how far this functionality should make sure the strict "<key /><VALUE />" node structure is not compromised or whether allow the "freedom" to work on individual nodes.
Simple idea:
// Return a copy of passed node and it's children
PLIST_API plist_t plist_copy(plist_t node);
// modify value of a node
PLIST_API void plist_set_key_val(plist_t node, char val);
PLIST_API void plist_set_string_val(plist_t node, char val);
PLIST_API void plist_set_bool_val(plist_t node, uint8_t val);
PLIST_API void plist_set_uint_val(plist_t node, uint64_t val);
PLIST_API void plist_set_real_val(plist_t node, double val);
PLIST_API void plist_set_data_val(plist_t node, char *val, uint64_t length);
PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec);
Comments and changes to this ticket
-
Jonathan Beck July 8th, 2009 @ 05:49 PM
- State changed from new to open
- Assigned user set to Jonathan Beck
Hi Martin,
I updated libplist git HEAD with requested changes.
Please check that it fits your needs.Also I would like to ensure through API that dicts are always well formed (key/value pairs), but that would require to duplicate lots of functions in the API (as single node manipulation is still necessary to handle arrays), so I don't really know what to do here.
If you did not started yet, I will probably investigate making a GUI plist editor.
-
Martin S. July 9th, 2009 @ 03:26 PM
Superb, thanks for looking into this. However I get empty nodes back...
static plist_t plist_copy_node(GNode * node, gpointer parent_node) { 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)); newnode = plist_new_node(newdata); if (parent_node) { g_node_append(parent_node, newnode); } g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, newnode); } plist_t plist_copy(plist_t node) { plist_copy_node(node, NULL); }
... as above obviously can't work returning void. :)
-
Jonathan Beck July 9th, 2009 @ 04:33 PM
I obviously did that a bit too fast :). Strange gcc didn't moan about that though.
Should be fixed now.
-
Martin S. July 10th, 2009 @ 05:07 PM
Attached patch fixes the last issue I encountered with this. After applying it everything works as expected. Thanks a lot.
-
Martin S. July 17th, 2009 @ 05:47 PM
Well, forgot to also copy the string value for "key" which caused issues. Attached corrected patch to use instead of the one before.
-
Jonathan Beck July 18th, 2009 @ 07:05 PM
- State changed from open to resolved
Changes applied and available in libplist-0.13
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป
A project around supporting the iPhone in Linux.
See http://libimobiledevice.org