diff options
| author | 2017-01-28 04:44:05 +0100 | |
|---|---|---|
| committer | 2017-01-28 04:44:05 +0100 | |
| commit | 458341fcc360db6e0bac0619e2512e6050f4e8c7 (patch) | |
| tree | 5be7f4399c4f676a8c5bd8998682a2e02897bbe0 /src | |
| parent | 6bf56a7cb5e98a4afe4e969d343b9a50681afd97 (diff) | |
| download | libplist-458341fcc360db6e0bac0619e2512e6050f4e8c7.tar.gz libplist-458341fcc360db6e0bac0619e2512e6050f4e8c7.tar.bz2 | |
bplist: Improve real/date node de/serialization
Diffstat (limited to 'src')
| -rw-r--r-- | src/bplist.c | 121 |
1 files changed, 56 insertions, 65 deletions
diff --git a/src/bplist.c b/src/bplist.c index 9e6e261..a2fb9be 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -75,25 +75,6 @@ enum | |||
| 75 | BPLIST_MASK = 0xF0 | 75 | BPLIST_MASK = 0xF0 |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | static void float_byte_convert(uint8_t * address, size_t size) | ||
| 79 | { | ||
| 80 | #if (defined(__LITTLE_ENDIAN__) \ | ||
| 81 | && !defined(__FLOAT_WORD_ORDER__)) \ | ||
| 82 | || (defined(__FLOAT_WORD_ORDER__) \ | ||
| 83 | && __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||
| 84 | uint8_t i = 0, j = 0; | ||
| 85 | uint8_t tmp = 0; | ||
| 86 | |||
| 87 | for (i = 0; i < (size / 2); i++) | ||
| 88 | { | ||
| 89 | tmp = address[i]; | ||
| 90 | j = ((size - 1) + 0) - i; | ||
| 91 | address[i] = address[j]; | ||
| 92 | address[j] = tmp; | ||
| 93 | } | ||
| 94 | #endif | ||
| 95 | } | ||
| 96 | |||
| 97 | union plist_uint_ptr | 78 | union plist_uint_ptr |
| 98 | { | 79 | { |
| 99 | const void *src; | 80 | const void *src; |
| @@ -128,11 +109,33 @@ static void byte_convert(uint8_t * address, size_t size) | |||
| 128 | #endif | 109 | #endif |
| 129 | } | 110 | } |
| 130 | 111 | ||
| 112 | #ifndef bswap16 | ||
| 113 | #define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) | ||
| 114 | #endif | ||
| 115 | |||
| 116 | #ifndef bswap32 | ||
| 117 | #define bswap32(x) ((((x) & 0xFF000000) >> 24) \ | ||
| 118 | | (((x) & 0x00FF0000) >> 8) \ | ||
| 119 | | (((x) & 0x0000FF00) << 8) \ | ||
| 120 | | (((x) & 0x000000FF) << 24)) | ||
| 121 | #endif | ||
| 122 | |||
| 123 | #ifndef bswap64 | ||
| 124 | #define bswap64(x) ((((x) & 0xFF00000000000000ull) >> 56) \ | ||
| 125 | | (((x) & 0x00FF000000000000ull) >> 40) \ | ||
| 126 | | (((x) & 0x0000FF0000000000ull) >> 24) \ | ||
| 127 | | (((x) & 0x000000FF00000000ull) >> 8) \ | ||
| 128 | | (((x) & 0x00000000FF000000ull) << 8) \ | ||
| 129 | | (((x) & 0x0000000000FF0000ull) << 24) \ | ||
| 130 | | (((x) & 0x000000000000FF00ull) << 40) \ | ||
| 131 | | (((x) & 0x00000000000000FFull) << 56)) | ||
| 132 | #endif | ||
| 133 | |||
| 131 | #ifndef be16toh | 134 | #ifndef be16toh |
| 132 | #ifdef __BIG_ENDIAN__ | 135 | #ifdef __BIG_ENDIAN__ |
| 133 | #define be16toh(x) (x) | 136 | #define be16toh(x) (x) |
| 134 | #else | 137 | #else |
| 135 | #define be16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) | 138 | #define be16toh(x) bswap16(x) |
| 136 | #endif | 139 | #endif |
| 137 | #endif | 140 | #endif |
| 138 | 141 | ||
| @@ -140,10 +143,7 @@ static void byte_convert(uint8_t * address, size_t size) | |||
| 140 | #ifdef __BIG_ENDIAN__ | 143 | #ifdef __BIG_ENDIAN__ |
| 141 | #define be32toh(x) (x) | 144 | #define be32toh(x) (x) |
| 142 | #else | 145 | #else |
| 143 | #define be32toh(x) ((((x) & 0xFF000000) >> 24) \ | 146 | #define be32toh(x) bswap32(x) |
| 144 | | (((x) & 0x00FF0000) >> 8) \ | ||
| 145 | | (((x) & 0x0000FF00) << 8) \ | ||
| 146 | | (((x) & 0x000000FF) << 24)) | ||
| 147 | #endif | 147 | #endif |
| 148 | #endif | 148 | #endif |
| 149 | 149 | ||
| @@ -151,14 +151,7 @@ static void byte_convert(uint8_t * address, size_t size) | |||
| 151 | #ifdef __BIG_ENDIAN__ | 151 | #ifdef __BIG_ENDIAN__ |
| 152 | #define be64toh(x) (x) | 152 | #define be64toh(x) (x) |
| 153 | #else | 153 | #else |
| 154 | #define be64toh(x) ((((x) & 0xFF00000000000000ull) >> 56) \ | 154 | #define be64toh(x) bswap64(x) |
| 155 | | (((x) & 0x00FF000000000000ull) >> 40) \ | ||
| 156 | | (((x) & 0x0000FF0000000000ull) >> 24) \ | ||
| 157 | | (((x) & 0x000000FF00000000ull) >> 8) \ | ||
| 158 | | (((x) & 0x00000000FF000000ull) << 8) \ | ||
| 159 | | (((x) & 0x0000000000FF0000ull) << 24) \ | ||
| 160 | | (((x) & 0x000000000000FF00ull) << 40) \ | ||
| 161 | | (((x) & 0x00000000000000FFull) << 56)) | ||
| 162 | #endif | 155 | #endif |
| 163 | #endif | 156 | #endif |
| 164 | 157 | ||
| @@ -186,7 +179,19 @@ static void byte_convert(uint8_t * address, size_t size) | |||
| 186 | ( ((uint64_t)x) < (1ULL << 24) ? 3 : \ | 179 | ( ((uint64_t)x) < (1ULL << 24) ? 3 : \ |
| 187 | ( ((uint64_t)x) < (1ULL << 32) ? 4 : 8)))) | 180 | ( ((uint64_t)x) < (1ULL << 32) ? 4 : 8)))) |
| 188 | 181 | ||
| 189 | #define get_real_bytes(x) (x == (float) x ? 4 : 8) | 182 | #define get_real_bytes(x) (x == (float) x ? sizeof(float) : sizeof(double)) |
| 183 | |||
| 184 | #if (defined(__LITTLE_ENDIAN__) \ | ||
| 185 | && !defined(__FLOAT_WORD_ORDER__)) \ | ||
| 186 | || (defined(__FLOAT_WORD_ORDER__) \ | ||
| 187 | && __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) | ||
| 188 | #define float_bswap64(x) bswap64(x) | ||
| 189 | #define float_bswap32(x) bswap32(x) | ||
| 190 | #else | ||
| 191 | #define float_bswap64(x) (x) | ||
| 192 | #define float_bswap32(x) (x) | ||
| 193 | #endif | ||
| 194 | |||
| 190 | 195 | ||
| 191 | #define NODE_IS_ROOT(x) (((node_t*)x)->isRoot) | 196 | #define NODE_IS_ROOT(x) (((node_t*)x)->isRoot) |
| 192 | 197 | ||
| @@ -235,29 +240,23 @@ static plist_t parse_uint_node(const char **bnode, uint8_t size) | |||
| 235 | static plist_t parse_real_node(const char **bnode, uint8_t size) | 240 | static plist_t parse_real_node(const char **bnode, uint8_t size) |
| 236 | { | 241 | { |
| 237 | plist_data_t data = plist_new_plist_data(); | 242 | plist_data_t data = plist_new_plist_data(); |
| 238 | float floatval = 0.0; | 243 | uint8_t buf[8]; |
| 239 | uint8_t* buf; | ||
| 240 | 244 | ||
| 241 | size = 1 << size; // make length less misleading | 245 | size = 1 << size; // make length less misleading |
| 242 | buf = malloc (size); | ||
| 243 | memcpy (buf, *bnode, size); | ||
| 244 | switch (size) | 246 | switch (size) |
| 245 | { | 247 | { |
| 246 | case sizeof(float): | 248 | case sizeof(uint32_t): |
| 247 | float_byte_convert(buf, size); | 249 | *(uint32_t*)buf = float_bswap32(*(uint32_t*)*bnode); |
| 248 | floatval = *(float *) buf; | 250 | data->realval = *(float *) buf; |
| 249 | data->realval = floatval; | ||
| 250 | break; | 251 | break; |
| 251 | case sizeof(double): | 252 | case sizeof(uint64_t): |
| 252 | float_byte_convert(buf, size); | 253 | *(uint64_t*)buf = float_bswap64(*(uint64_t*)*bnode); |
| 253 | data->realval = *(double *) buf; | 254 | data->realval = *(double *) buf; |
| 254 | break; | 255 | break; |
| 255 | default: | 256 | default: |
| 256 | free(buf); | ||
| 257 | free(data); | 257 | free(data); |
| 258 | return NULL; | 258 | return NULL; |
| 259 | } | 259 | } |
| 260 | free (buf); | ||
| 261 | data->type = PLIST_REAL; | 260 | data->type = PLIST_REAL; |
| 262 | data->length = sizeof(double); | 261 | data->length = sizeof(double); |
| 263 | 262 | ||
| @@ -872,32 +871,24 @@ static void write_uint(bytearray_t * bplist, uint64_t val) | |||
| 872 | 871 | ||
| 873 | static void write_real(bytearray_t * bplist, double val) | 872 | static void write_real(bytearray_t * bplist, double val) |
| 874 | { | 873 | { |
| 875 | uint64_t size = get_real_bytes(val); //cheat to know used space | 874 | int size = get_real_bytes(val); //cheat to know used space |
| 876 | uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); | 875 | uint8_t buff[9]; |
| 877 | buff[0] = BPLIST_REAL | Log2(size); | 876 | buff[0] = BPLIST_REAL | Log2(size); |
| 878 | if (size == sizeof(double)) | 877 | if (size == sizeof(float)) { |
| 879 | { | 878 | float floatval = (float)val; |
| 880 | memcpy(buff + 1, &val, size); | 879 | *(uint32_t*)(buff+1) = float_bswap32(*(uint32_t*)&floatval); |
| 881 | } | 880 | } else { |
| 882 | else if (size == sizeof(float)) | 881 | *(uint64_t*)(buff+1) = float_bswap64(*(uint64_t*)&val); |
| 883 | { | ||
| 884 | float tmpval = (float) val; | ||
| 885 | memcpy(buff + 1, &tmpval, size); | ||
| 886 | } | 882 | } |
| 887 | float_byte_convert(buff + 1, size); | 883 | byte_array_append(bplist, buff, size+1); |
| 888 | byte_array_append(bplist, buff, sizeof(uint8_t) + size); | ||
| 889 | free(buff); | ||
| 890 | } | 884 | } |
| 891 | 885 | ||
| 892 | static void write_date(bytearray_t * bplist, double val) | 886 | static void write_date(bytearray_t * bplist, double val) |
| 893 | { | 887 | { |
| 894 | uint64_t size = 8; //dates always use 8 bytes | 888 | uint8_t buff[9]; |
| 895 | uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); | 889 | buff[0] = BPLIST_DATE | 3; |
| 896 | buff[0] = BPLIST_DATE | Log2(size); | 890 | *(uint64_t*)(buff+1) = float_bswap64(*(uint64_t*)&val); |
| 897 | memcpy(buff + 1, &val, size); | 891 | byte_array_append(bplist, buff, sizeof(buff)); |
| 898 | float_byte_convert(buff + 1, size); | ||
| 899 | byte_array_append(bplist, buff, sizeof(uint8_t) + size); | ||
| 900 | free(buff); | ||
| 901 | } | 892 | } |
| 902 | 893 | ||
| 903 | static void write_raw_data(bytearray_t * bplist, uint8_t mark, uint8_t * val, uint64_t size) | 894 | static void write_raw_data(bytearray_t * bplist, uint8_t mark, uint8_t * val, uint64_t size) |
