diff options
| author | 2024-04-18 10:18:17 +0200 | |
|---|---|---|
| committer | 2024-04-18 10:18:17 +0200 | |
| commit | f8be42eaefe50ed4275bb86573ed44088ffab6c5 (patch) | |
| tree | 131e0fd85ec985a3d90df4166f703a966a78fbb2 /src | |
| parent | 0b73e02a2b9b50daeb95b63b39e9496c8899e33d (diff) | |
| download | libplist-f8be42eaefe50ed4275bb86573ed44088ffab6c5.tar.gz libplist-f8be42eaefe50ed4275bb86573ed44088ffab6c5.tar.bz2 | |
Add PLIST_DICT convenience functions for different queries/operations
Diffstat (limited to 'src')
| -rw-r--r-- | src/plist.c | 245 |
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 @@ | |||
| 52 | typedef SSIZE_T ssize_t; | 52 | typedef SSIZE_T ssize_t; |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | #ifdef DEBUG | ||
| 56 | static 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 | |||
| 55 | extern void plist_xml_init(void); | 62 | extern void plist_xml_init(void); |
| 56 | extern void plist_xml_deinit(void); | 63 | extern void plist_xml_deinit(void); |
| 57 | extern void plist_bin_init(void); | 64 | extern void plist_bin_init(void); |
| @@ -61,6 +68,52 @@ extern void plist_json_deinit(void); | |||
| 61 | extern void plist_ostep_init(void); | 68 | extern void plist_ostep_init(void); |
| 62 | extern void plist_ostep_deinit(void); | 69 | extern 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 | |||
| 64 | static void internal_plist_init(void) | 117 | static 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 | ||
| 1014 | uint8_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 | |||
| 1060 | int64_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 | |||
| 1102 | uint64_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 | |||
| 1143 | plist_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 | |||
| 1153 | plist_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 | |||
| 1163 | plist_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 | |||
| 1173 | plist_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 | |||
| 1183 | plist_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 | |||
| 1193 | plist_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 | |||
| 961 | plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) | 1203 | plist_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 | ||
| 1579 | void plist_set_debug(int debug) | 1821 | void 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); |
