summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2024-04-18 10:18:17 +0200
committerGravatar Nikias Bassen2024-04-18 10:18:17 +0200
commitf8be42eaefe50ed4275bb86573ed44088ffab6c5 (patch)
tree131e0fd85ec985a3d90df4166f703a966a78fbb2 /src/plist.c
parent0b73e02a2b9b50daeb95b63b39e9496c8899e33d (diff)
downloadlibplist-f8be42eaefe50ed4275bb86573ed44088ffab6c5.tar.gz
libplist-f8be42eaefe50ed4275bb86573ed44088ffab6c5.tar.bz2
Add PLIST_DICT convenience functions for different queries/operations
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/plist.c b/src/plist.c
index 57f5ead..d1b0b5a 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -52,6 +52,13 @@
52typedef SSIZE_T ssize_t; 52typedef SSIZE_T ssize_t;
53#endif 53#endif
54 54
55#ifdef DEBUG
56static int plist_debug = 0;
57#define PLIST_ERR(...) if (plist_debug > 0) { fprintf(stderr, "libplist ERROR: " __VA_ARGS__); }
58#else
59#define PLIST_ERR(...)
60#endif
61
55extern void plist_xml_init(void); 62extern void plist_xml_init(void);
56extern void plist_xml_deinit(void); 63extern void plist_xml_deinit(void);
57extern void plist_bin_init(void); 64extern void plist_bin_init(void);
@@ -61,6 +68,52 @@ extern void plist_json_deinit(void);
61extern void plist_ostep_init(void); 68extern void plist_ostep_init(void);
62extern void plist_ostep_deinit(void); 69extern void plist_ostep_deinit(void);
63 70
71#ifndef bswap16
72#define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
73#endif
74
75#ifndef bswap32
76#define bswap32(x) ((((x) & 0xFF000000) >> 24) \
77 | (((x) & 0x00FF0000) >> 8) \
78 | (((x) & 0x0000FF00) << 8) \
79 | (((x) & 0x000000FF) << 24))
80#endif
81
82#ifndef bswap64
83#define bswap64(x) ((((x) & 0xFF00000000000000ull) >> 56) \
84 | (((x) & 0x00FF000000000000ull) >> 40) \
85 | (((x) & 0x0000FF0000000000ull) >> 24) \
86 | (((x) & 0x000000FF00000000ull) >> 8) \
87 | (((x) & 0x00000000FF000000ull) << 8) \
88 | (((x) & 0x0000000000FF0000ull) << 24) \
89 | (((x) & 0x000000000000FF00ull) << 40) \
90 | (((x) & 0x00000000000000FFull) << 56))
91#endif
92
93#ifndef le16toh
94#ifdef __LITTLE_ENDIAN__
95#define le16toh(x) (x)
96#else
97#define le16toh(x) bswap16(x)
98#endif
99#endif
100
101#ifndef le32toh
102#ifdef __LITTLE_ENDIAN__
103#define le32toh(x) (x)
104#else
105#define le32toh(x) bswap32(x)
106#endif
107#endif
108
109#ifndef le64toh
110#ifdef __LITTLE_ENDIAN__
111#define le64toh(x) (x)
112#else
113#define le64toh(x) bswap64(x)
114#endif
115#endif
116
64static void internal_plist_init(void) 117static void internal_plist_init(void)
65{ 118{
66 plist_bin_init(); 119 plist_bin_init();
@@ -958,6 +1011,195 @@ void plist_dict_merge(plist_t *target, plist_t source)
958 free(it); 1011 free(it);
959} 1012}
960 1013
1014uint8_t plist_dict_get_bool(plist_t dict, const char *key)
1015{
1016 uint8_t bval = 0;
1017 uint64_t uintval = 0;
1018 const char *strval = NULL;
1019 uint64_t strsz = 0;
1020 plist_t node = plist_dict_get_item(dict, key);
1021 if (!node) {
1022 return 0;
1023 }
1024 switch (plist_get_node_type(node)) {
1025 case PLIST_BOOLEAN:
1026 plist_get_bool_val(node, &bval);
1027 break;
1028 case PLIST_INT:
1029 plist_get_uint_val(node, &uintval);
1030 bval = (uintval) ? 1 : 0;
1031 break;
1032 case PLIST_STRING:
1033 strval = plist_get_string_ptr(node, NULL);
1034 if (strval) {
1035 if (strcmp(strval, "true")) {
1036 bval = 1;
1037 } else if (strcmp(strval, "false")) {
1038 bval = 0;
1039 } else {
1040 PLIST_ERR("%s: invalid string '%s' for string to boolean conversion\n", __func__, strval);
1041 }
1042 }
1043 break;
1044 case PLIST_DATA:
1045 strval = (const char*)plist_get_data_ptr(node, &strsz);
1046 if (strval) {
1047 if (strsz == 1) {
1048 bval = (strval[0]) ? 1 : 0;
1049 } else {
1050 PLIST_ERR("%s: invalid size %" PRIu64 " for data to boolean conversion\n", __func__, strsz);
1051 }
1052 }
1053 break;
1054 default:
1055 break;
1056 }
1057 return bval;
1058}
1059
1060int64_t plist_dict_get_int(plist_t dict, const char *key)
1061{
1062 int64_t intval = 0;
1063 const char *strval = NULL;
1064 uint64_t strsz = 0;
1065 plist_t node = plist_dict_get_item(dict, key);
1066 if (!node) {
1067 return intval;
1068 }
1069 switch (plist_get_node_type(node)) {
1070 case PLIST_INT:
1071 plist_get_int_val(node, &intval);
1072 break;
1073 case PLIST_STRING:
1074 strval = plist_get_string_ptr(node, NULL);
1075 if (strval) {
1076 intval = strtoll(strval, NULL, 0);
1077 }
1078 break;
1079 case PLIST_DATA:
1080 strval = (const char*)plist_get_data_ptr(node, &strsz);
1081 if (strval) {
1082 if (strsz == 8) {
1083 intval = le64toh(*(int64_t*)strval);
1084 } else if (strsz == 4) {
1085 intval = le32toh(*(int32_t*)strval);
1086 } else if (strsz == 2) {
1087 intval = le16toh(*(int16_t*)strval);
1088 } else if (strsz == 1) {
1089 intval = strval[0];
1090 } else {
1091 PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
1092 }
1093 }
1094 break;
1095 default:
1096 break;
1097 }
1098 return intval;
1099}
1100
1101
1102uint64_t plist_dict_get_uint(plist_t dict, const char *key)
1103{
1104 uint64_t uintval = 0;
1105 const char *strval = NULL;
1106 uint64_t strsz = 0;
1107 plist_t node = plist_dict_get_item(dict, key);
1108 if (!node) {
1109 return uintval;
1110 }
1111 switch (plist_get_node_type(node)) {
1112 case PLIST_INT:
1113 plist_get_uint_val(node, &uintval);
1114 break;
1115 case PLIST_STRING:
1116 strval = plist_get_string_ptr(node, NULL);
1117 if (strval) {
1118 uintval = strtoull(strval, NULL, 0);
1119 }
1120 break;
1121 case PLIST_DATA:
1122 strval = (const char*)plist_get_data_ptr(node, &strsz);
1123 if (strval) {
1124 if (strsz == 8) {
1125 uintval = le64toh(*(uint64_t*)strval);
1126 } else if (strsz == 4) {
1127 uintval = le32toh(*(uint32_t*)strval);
1128 } else if (strsz == 2) {
1129 uintval = le16toh(*(uint16_t*)strval);
1130 } else if (strsz == 1) {
1131 uintval = strval[0];
1132 } else {
1133 PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
1134 }
1135 }
1136 break;
1137 default:
1138 break;
1139 }
1140 return uintval;
1141}
1142
1143plist_err_t plist_dict_copy_item(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1144{
1145 plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
1146 if (!node) {
1147 return PLIST_ERR_INVALID_ARG;
1148 }
1149 plist_dict_set_item(target_dict, key, plist_copy(node));
1150 return PLIST_ERR_SUCCESS;
1151}
1152
1153plist_err_t plist_dict_copy_bool(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1154{
1155 if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
1156 return PLIST_ERR_INVALID_ARG;
1157 }
1158 uint8_t bval = plist_dict_get_bool(source_dict, (alt_source_key) ? alt_source_key : key);
1159 plist_dict_set_item(target_dict, key, plist_new_bool(bval));
1160 return PLIST_ERR_SUCCESS;
1161}
1162
1163plist_err_t plist_dict_copy_int(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1164{
1165 if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
1166 return PLIST_ERR_INVALID_ARG;
1167 }
1168 int64_t i64val = plist_dict_get_int(source_dict, (alt_source_key) ? alt_source_key : key);
1169 plist_dict_set_item(target_dict, key, plist_new_int(i64val));
1170 return PLIST_ERR_SUCCESS;
1171}
1172
1173plist_err_t plist_dict_copy_uint(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1174{
1175 if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
1176 return PLIST_ERR_INVALID_ARG;
1177 }
1178 uint64_t u64val = plist_dict_get_uint(source_dict, (alt_source_key) ? alt_source_key : key);
1179 plist_dict_set_item(target_dict, key, plist_new_uint(u64val));
1180 return PLIST_ERR_SUCCESS;
1181}
1182
1183plist_err_t plist_dict_copy_data(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1184{
1185 plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
1186 if (!PLIST_IS_DATA(node)) {
1187 return PLIST_ERR_INVALID_ARG;
1188 }
1189 plist_dict_set_item(target_dict, key, plist_copy(node));
1190 return PLIST_ERR_SUCCESS;
1191}
1192
1193plist_err_t plist_dict_copy_string(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
1194{
1195 plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
1196 if (!PLIST_IS_STRING(node)) {
1197 return PLIST_ERR_INVALID_ARG;
1198 }
1199 plist_dict_set_item(target_dict, key, plist_copy(node));
1200 return PLIST_ERR_SUCCESS;
1201}
1202
961plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) 1203plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
962{ 1204{
963 plist_t current = plist; 1205 plist_t current = plist;
@@ -1578,6 +1820,9 @@ extern void plist_ostep_set_debug(int debug);
1578 1820
1579void plist_set_debug(int debug) 1821void plist_set_debug(int debug)
1580{ 1822{
1823#if DEBUG
1824 plist_debug = debug;
1825#endif
1581 plist_xml_set_debug(debug); 1826 plist_xml_set_debug(debug);
1582 plist_bin_set_debug(debug); 1827 plist_bin_set_debug(debug);
1583 plist_json_set_debug(debug); 1828 plist_json_set_debug(debug);