diff options
Diffstat (limited to 'src/bplist.c')
| -rw-r--r-- | src/bplist.c | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/src/bplist.c b/src/bplist.c index c4fe3df..69f3dca 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -1184,7 +1184,7 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1184 | return; | 1184 | return; |
| 1185 | 1185 | ||
| 1186 | //list of objects | 1186 | //list of objects |
| 1187 | objects = ptr_array_new(256); | 1187 | objects = ptr_array_new(4096); |
| 1188 | //hashtable to write only once same nodes | 1188 | //hashtable to write only once same nodes |
| 1189 | ref_table = hash_table_new(plist_data_hash, plist_data_compare, free); | 1189 | ref_table = hash_table_new(plist_data_hash, plist_data_compare, free); |
| 1190 | 1190 | ||
| @@ -1201,8 +1201,90 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) | |||
| 1201 | root_object = 0; //root is first in list | 1201 | root_object = 0; //root is first in list |
| 1202 | offset_table_index = 0; //unknown yet | 1202 | offset_table_index = 0; //unknown yet |
| 1203 | 1203 | ||
| 1204 | //figure out the storage size required | ||
| 1205 | size_t req = 0; | ||
| 1206 | for (i = 0; i < num_objects; i++) | ||
| 1207 | { | ||
| 1208 | node_t* node = ptr_array_index(objects, i); | ||
| 1209 | plist_data_t data = plist_get_data(node); | ||
| 1210 | uint64_t size; | ||
| 1211 | uint8_t bsize; | ||
| 1212 | switch (data->type) | ||
| 1213 | { | ||
| 1214 | case PLIST_BOOLEAN: | ||
| 1215 | req += 1; | ||
| 1216 | break; | ||
| 1217 | case PLIST_KEY: | ||
| 1218 | case PLIST_STRING: | ||
| 1219 | req += 1; | ||
| 1220 | if (data->length >= 15) { | ||
| 1221 | bsize = get_needed_bytes(data->length); | ||
| 1222 | if (bsize == 3) bsize = 4; | ||
| 1223 | req += 1; | ||
| 1224 | req += bsize; | ||
| 1225 | } | ||
| 1226 | if ( is_ascii_string(data->strval, data->length) ) | ||
| 1227 | { | ||
| 1228 | req += data->length; | ||
| 1229 | } | ||
| 1230 | else | ||
| 1231 | { | ||
| 1232 | req += data->length * 2; | ||
| 1233 | } | ||
| 1234 | break; | ||
| 1235 | case PLIST_REAL: | ||
| 1236 | size = get_real_bytes(data->realval); | ||
| 1237 | req += 1; | ||
| 1238 | req += size; | ||
| 1239 | break; | ||
| 1240 | case PLIST_DATE: | ||
| 1241 | req += 9; | ||
| 1242 | break; | ||
| 1243 | case PLIST_ARRAY: | ||
| 1244 | size = node_n_children(node); | ||
| 1245 | req += 1; | ||
| 1246 | if (size >= 15) { | ||
| 1247 | bsize = get_needed_bytes(size); | ||
| 1248 | if (bsize == 3) bsize = 4; | ||
| 1249 | req += 1; | ||
| 1250 | req += bsize; | ||
| 1251 | } | ||
| 1252 | req += size * ref_size; | ||
| 1253 | break; | ||
| 1254 | case PLIST_DICT: | ||
| 1255 | size = node_n_children(node) / 2; | ||
| 1256 | req += 1; | ||
| 1257 | if (size >= 15) { | ||
| 1258 | bsize = get_needed_bytes(size); | ||
| 1259 | if (bsize == 3) bsize = 4; | ||
| 1260 | req += 1; | ||
| 1261 | req += bsize; | ||
| 1262 | } | ||
| 1263 | req += size * 2 * ref_size; | ||
| 1264 | break; | ||
| 1265 | default: | ||
| 1266 | size = data->length; | ||
| 1267 | req += 1; | ||
| 1268 | if (size >= 15) { | ||
| 1269 | bsize = get_needed_bytes(size); | ||
| 1270 | if (bsize == 3) bsize = 4; | ||
| 1271 | req += 1; | ||
| 1272 | req += bsize; | ||
| 1273 | } | ||
| 1274 | req += data->length; | ||
| 1275 | break; | ||
| 1276 | } | ||
| 1277 | } | ||
| 1278 | // add size of magic | ||
| 1279 | req += BPLIST_MAGIC_SIZE; | ||
| 1280 | req += BPLIST_VERSION_SIZE; | ||
| 1281 | // add size of offset table | ||
| 1282 | req += get_needed_bytes(req) * num_objects; | ||
| 1283 | // add size of trailer | ||
| 1284 | req += sizeof(bplist_trailer_t); | ||
| 1285 | |||
| 1204 | //setup a dynamic bytes array to store bplist in | 1286 | //setup a dynamic bytes array to store bplist in |
| 1205 | bplist_buff = byte_array_new(); | 1287 | bplist_buff = byte_array_new(req); |
| 1206 | 1288 | ||
| 1207 | //set magic number and version | 1289 | //set magic number and version |
| 1208 | byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); | 1290 | byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); |
