diff options
| -rw-r--r-- | src/bplist.c | 86 | ||||
| -rw-r--r-- | src/bytearray.c | 4 | ||||
| -rw-r--r-- | src/bytearray.h | 2 | ||||
| -rw-r--r-- | src/strbuf.h | 2 | 
4 files changed, 88 insertions, 6 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)          return;      //list of objects -    objects = ptr_array_new(256); +    objects = ptr_array_new(4096);      //hashtable to write only once same nodes      ref_table = hash_table_new(plist_data_hash, plist_data_compare, free); @@ -1201,8 +1201,90 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)      root_object = 0;			//root is first in list      offset_table_index = 0;		//unknown yet +    //figure out the storage size required +    size_t req = 0; +    for (i = 0; i < num_objects; i++) +    { +        node_t* node = ptr_array_index(objects, i); +        plist_data_t data = plist_get_data(node); +        uint64_t size; +        uint8_t bsize; +        switch (data->type) +        { +        case PLIST_BOOLEAN: +            req += 1; +            break; +        case PLIST_KEY: +        case PLIST_STRING: +            req += 1; +            if (data->length >= 15) { +                bsize = get_needed_bytes(data->length); +                if (bsize == 3) bsize = 4; +                req += 1; +                req += bsize; +            } +            if ( is_ascii_string(data->strval, data->length) ) +            { +                req += data->length; +            } +            else +            { +                req += data->length * 2; +            } +            break; +        case PLIST_REAL: +            size = get_real_bytes(data->realval); +            req += 1; +            req += size; +            break; +        case PLIST_DATE: +            req += 9; +            break; +        case PLIST_ARRAY: +            size = node_n_children(node); +            req += 1; +            if (size >= 15) { +                bsize = get_needed_bytes(size); +                if (bsize == 3) bsize = 4; +                req += 1; +                req += bsize; +            } +            req += size * ref_size; +            break; +        case PLIST_DICT: +            size = node_n_children(node) / 2; +            req += 1; +            if (size >= 15) { +                bsize = get_needed_bytes(size); +                if (bsize == 3) bsize = 4; +                req += 1; +                req += bsize; +            } +            req += size * 2 * ref_size; +            break; +        default: +            size = data->length; +            req += 1; +            if (size >= 15) { +                bsize = get_needed_bytes(size); +                if (bsize == 3) bsize = 4; +                req += 1; +                req += bsize; +            } +            req += data->length; +            break; +        } +    } +    // add size of magic +    req += BPLIST_MAGIC_SIZE; +    req += BPLIST_VERSION_SIZE; +    // add size of offset table +    req += get_needed_bytes(req) * num_objects; +    // add size of trailer +    req += sizeof(bplist_trailer_t); +      //setup a dynamic bytes array to store bplist in -    bplist_buff = byte_array_new(); +    bplist_buff = byte_array_new(req);      //set magic number and version      byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); diff --git a/src/bytearray.c b/src/bytearray.c index fff5089..7d0549b 100644 --- a/src/bytearray.c +++ b/src/bytearray.c @@ -23,10 +23,10 @@  #define PAGE_SIZE 4096 -bytearray_t *byte_array_new() +bytearray_t *byte_array_new(size_t initial)  {  	bytearray_t *a = (bytearray_t*)malloc(sizeof(bytearray_t)); -	a->capacity = PAGE_SIZE * 8; +	a->capacity = (initial > PAGE_SIZE) ? (initial+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE;  	a->data = malloc(a->capacity);  	a->len = 0;  	return a; diff --git a/src/bytearray.h b/src/bytearray.h index aae8c31..312e2aa 100644 --- a/src/bytearray.h +++ b/src/bytearray.h @@ -28,7 +28,7 @@ typedef struct bytearray_t {  	size_t capacity;  } bytearray_t; -bytearray_t *byte_array_new(); +bytearray_t *byte_array_new(size_t initial);  void byte_array_free(bytearray_t *ba);  void byte_array_grow(bytearray_t *ba, size_t amount);  void byte_array_append(bytearray_t *ba, void *buf, size_t len); diff --git a/src/strbuf.h b/src/strbuf.h index ba2c909..b805892 100644 --- a/src/strbuf.h +++ b/src/strbuf.h @@ -26,7 +26,7 @@  typedef struct bytearray_t strbuf_t; -#define str_buf_new() byte_array_new() +#define str_buf_new() byte_array_new(32768)  #define str_buf_free(__ba) byte_array_free(__ba)  #define str_buf_grow(__ba, __am) byte_array_grow(__ba, __am)  #define str_buf_append(__ba, __str, __len) byte_array_append(__ba, (void*)(__str), __len) | 
