diff options
| author | 2009-02-15 17:15:29 +0100 | |
|---|---|---|
| committer | 2009-02-15 17:15:29 +0100 | |
| commit | bb3097cb2266b55719b955c93d09a0e2d6f8eccb (patch) | |
| tree | 478a6dd7b31b1640d79bc645052fc9843cc74ca1 | |
| parent | 8e9eb83c2a8cd3b6a6d1943043f1d3b674e82de4 (diff) | |
| download | libplist-bb3097cb2266b55719b955c93d09a0e2d6f8eccb.tar.gz libplist-bb3097cb2266b55719b955c93d09a0e2d6f8eccb.tar.bz2  | |
Add more regression test and fix Integer and Real type handling.
| -rw-r--r-- | include/plist/plist.h | 8 | ||||
| -rw-r--r-- | src/bplist.c | 80 | ||||
| -rw-r--r-- | src/plist.c | 67 | ||||
| -rw-r--r-- | src/plist.h | 2 | ||||
| -rw-r--r-- | src/xplist.c | 4 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | test/data/2.plist | 2 | ||||
| -rw-r--r-- | test/data/3.plist | 2 | ||||
| -rw-r--r-- | test/data/4.plist | 2 | ||||
| -rw-r--r-- | test/data/5.plist | 2 | ||||
| -rw-r--r-- | test/plist_cmp.c | 138 | 
11 files changed, 246 insertions, 72 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index df30ac4..4547f18 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -394,6 +394,14 @@ extern "C" {   */  	PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); +/** + * Compare two node values + * + * @param node_l left node to compare + * @param node_r rigth node to compare + * @return TRUE is type and value match, FALSE otherwise. + */ +	PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r);  /*@}*/ diff --git a/src/bplist.c b/src/bplist.c index 95070d7..cf9b9c6 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -87,7 +87,7 @@ static uint32_t uint24_from_be(char *buff)  #define UINT_TO_HOST(x, n) \  		(n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \  		(n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \ -		(n == 3 ? uint24_from_be( x ) : \ +		(n == 3 ? uint24_from_be( (char*)x ) : \  		(n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \  		*(uint8_t *)(x) )))) @@ -99,10 +99,7 @@ static uint32_t uint24_from_be(char *buff)  		( ((uint64_t)x) < (1ULL << 24) ? 3 : \  		( ((uint64_t)x) < (1ULL << 32) ? 4 : 8)))) -#define get_real_bytes(x) (x >> 32 ? 4 : 8) - - - +#define get_real_bytes(x) (x == (float) x ? 4 : 8)  static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object) @@ -133,12 +130,18 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)  static plist_t parse_real_node(char *bnode, uint8_t size)  {  	plist_data_t data = plist_new_plist_data(); +	float floatval = 0.0;  	size = 1 << size;			// make length less misleading  	switch (size) {  	case sizeof(float): +		floatval = *(float*)bnode; +		byte_convert((uint8_t*)&floatval, sizeof(float)); +		data->realval = floatval; +		break;  	case sizeof(double): -		data->intval = UINT_TO_HOST(bnode, size);	//use the fact that we have an union to cheat byte swapping +		data->realval = *(double*)bnode; +		byte_convert((uint8_t*)&(data->realval), sizeof(double));  		break;  	default:  		free(data); @@ -187,7 +190,7 @@ static plist_t parse_unicode_node(char *bnode, uint64_t size)  	data->unicodeval[sizeof(gunichar2) * size] = '\0';  	data->length = size;  	for (i = 0; i <= size; i++) -		byte_convert(data->unicodeval + i, sizeof(gunichar2)); +		byte_convert((uint8_t*)(data->unicodeval + i), sizeof(gunichar2));  	return g_node_new(data);  } @@ -543,63 +546,7 @@ static guint plist_data_hash(gconstpointer key)  	return hash;  } -static gboolean plist_data_compare(gconstpointer a, gconstpointer b) -{ -	plist_data_t val_a = NULL; -	plist_data_t val_b = NULL; -	if (!a || !b) -		return FALSE; - -	if (!((GNode *) a)->data || !((GNode *) b)->data) -		return FALSE; - -	val_a = plist_get_data((plist_t) a); -	val_b = plist_get_data((plist_t) b); - -	if (val_a->type != val_b->type) -		return FALSE; - -	switch (val_a->type) { -	case PLIST_BOOLEAN: -	case PLIST_UINT: -	case PLIST_REAL: -		if (val_a->intval == val_b->intval)	//it is an union so this is sufficient -			return TRUE; -		else -			return FALSE; - -	case PLIST_KEY: -	case PLIST_STRING: -		if (!strcmp(val_a->strval, val_b->strval)) -			return TRUE; -		else -			return FALSE; -	case PLIST_UNICODE: -		if (!memcmp(val_a->unicodeval, val_b->unicodeval, val_a->length)) -			return TRUE; -		else -			return FALSE; - -	case PLIST_DATA: -	case PLIST_ARRAY: -	case PLIST_DICT: -		//compare pointer -		if (a == b) -			return TRUE; -		else -			return FALSE; -		break; -	case PLIST_DATE: -		if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal))) -			return TRUE; -		else -			return FALSE; -	default: -		break; -	} -	return FALSE; -}  struct serialize_s {  	GPtrArray *objects; @@ -655,7 +602,12 @@ static void write_real(GByteArray * bplist, double val)  	uint64_t size = get_real_bytes(*((uint64_t *) & val));	//cheat to know used space  	uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);  	buff[0] = BPLIST_REAL | Log2(size); -	memcpy(buff + 1, &val, size); +	if (size == sizeof(double)) { +		memcpy(buff + 1, &val, size); +	} else if (size == sizeof(float)) { +		float tmpval = (float) val; +		memcpy(buff + 1, &tmpval, size); +	}  	byte_convert(buff + 1, size);  	g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);  	free(buff); diff --git a/src/plist.c b/src/plist.c index 0e73c4b..e800b5c 100644 --- a/src/plist.c +++ b/src/plist.c @@ -414,3 +414,70 @@ void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)  	*sec = val.tv_sec;  	*usec = val.tv_usec;  } + +gboolean plist_data_compare(gconstpointer a, gconstpointer b) +{ +	plist_data_t val_a = NULL; +	plist_data_t val_b = NULL; + +	if (!a || !b) +		return FALSE; + +	if (!((GNode *) a)->data || !((GNode *) b)->data) +		return FALSE; + +	val_a = plist_get_data((plist_t) a); +	val_b = plist_get_data((plist_t) b); + +	if (val_a->type != val_b->type) +		return FALSE; + +	switch (val_a->type) { +	case PLIST_BOOLEAN: +	case PLIST_UINT: +	case PLIST_REAL: +		if (val_a->intval == val_b->intval)	//it is an union so this is sufficient +			return TRUE; +		else +			return FALSE; + +	case PLIST_KEY: +	case PLIST_STRING: +		if (!strcmp(val_a->strval, val_b->strval)) +			return TRUE; +		else +			return FALSE; +	case PLIST_UNICODE: +		if (!memcmp(val_a->unicodeval, val_b->unicodeval, val_a->length)) +			return TRUE; +		else +			return FALSE; + +	case PLIST_DATA: +		if (!memcmp(val_a->buff, val_b->buff, val_a->length)) +			return TRUE; +		else +			return FALSE; +	case PLIST_ARRAY: +	case PLIST_DICT: +		//compare pointer +		if (a == b) +			return TRUE; +		else +			return FALSE; +		break; +	case PLIST_DATE: +		if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal))) +			return TRUE; +		else +			return FALSE; +	default: +		break; +	} +	return FALSE; +} + +char plist_compare_node_value(plist_t node_l, plist_t node_r) +{ +	return plist_data_compare( node_l , node_r ); +} diff --git a/src/plist.h b/src/plist.h index 4bb97e3..83c63bf 100644 --- a/src/plist.h +++ b/src/plist.h @@ -49,7 +49,7 @@ typedef struct plist_data_s *plist_data_t;  plist_t plist_new_node(plist_data_t data);  plist_data_t plist_get_data(const plist_t node);  plist_data_t plist_new_plist_data(); - +gboolean plist_data_compare(gconstpointer a, gconstpointer b);  #endif diff --git a/src/xplist.c b/src/xplist.c index e281b4f..c0849b6 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -152,12 +152,12 @@ static void node_to_xml(GNode * node, gpointer xml_struct)  	case PLIST_UINT:  		tag = XPLIST_INT; -		val = g_strdup_printf("%lu", (long unsigned int) node_data->intval); +		val = g_strdup_printf("%llu", node_data->intval);  		break;  	case PLIST_REAL:  		tag = XPLIST_REAL; -		val = g_strdup_printf("%Lf", (long double) node_data->realval); +		val = g_strdup_printf("%f", node_data->realval);  		break;  	case PLIST_STRING: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b499018..40dc640 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,9 +3,12 @@  SET(plist_test_SRC  	plist_test.c) +SET(plist_cmp_SRC +	plist_cmp.c)  ADD_EXECUTABLE(plist_test ${plist_test_SRC})  TARGET_LINK_LIBRARIES(plist_test plist) - +ADD_EXECUTABLE(plist_cmp ${plist_cmp_SRC}) +TARGET_LINK_LIBRARIES(plist_cmp plist)  INCLUDE(CTest) @@ -16,3 +19,9 @@ ADD_TEST(Large plist_test data/4.plist)  ADD_TEST(Huge plist_test data/5.plist)  ADD_TEST(Big_Array plist_test data/6.plist) +ADD_TEST(EmptyCmp plist_cmp data/1.plist data/1.plist.out) +ADD_TEST(SmallCmp plist_cmp data/2.plist data/2.plist.out) +ADD_TEST(MediumCmp plist_cmp data/3.plist data/3.plist.out) +ADD_TEST(LargeCmp plist_cmp data/4.plist data/4.plist.out) +ADD_TEST(HugeCmp plist_cmp data/5.plist data/5.plist.out) +ADD_TEST(Big_ArrayCmp plist_cmp data/6.plist data/6.plist.out) diff --git a/test/data/2.plist b/test/data/2.plist index 7586de0..169b822 100644 --- a/test/data/2.plist +++ b/test/data/2.plist @@ -23,7 +23,7 @@  	<key>Some Int</key>  	<integer>32434543632</integer>  	<key>Some Real</key> -	<real>58654.3476563</real> +	<real>58654.347656</real>  	<key>Some Date</key>  	<date>2009-02-12T22:23:00Z</date>  	<key>Some Data</key> diff --git a/test/data/3.plist b/test/data/3.plist index 30d5b3e..6d16191 100644 --- a/test/data/3.plist +++ b/test/data/3.plist @@ -23,7 +23,7 @@  	<key>Some Int</key>  	<integer>32434543632</integer>  	<key>Some Real</key> -	<real>58654.3476563</real> +	<real>58654.347656</real>  	<key>Some Date</key>  	<date>2009-02-12T22:23:00Z</date>  	<key>Some Data</key> diff --git a/test/data/4.plist b/test/data/4.plist index 87d6e4c..de7c488 100644 --- a/test/data/4.plist +++ b/test/data/4.plist @@ -23,7 +23,7 @@  	<key>Some Int</key>  	<integer>32434543632</integer>  	<key>Some Real</key> -	<real>58654.3476563</real> +	<real>58654.347656</real>  	<key>Some Date</key>  	<date>2009-02-12T22:23:00Z</date>  	<key>Some Data</key> diff --git a/test/data/5.plist b/test/data/5.plist index 388ff85..647c648 100644 --- a/test/data/5.plist +++ b/test/data/5.plist @@ -23,7 +23,7 @@  	<key>Some Int</key>  	<integer>32434543632</integer>  	<key>Some Real</key> -	<real>58654.3476563</real> +	<real>58654.347656</real>  	<key>Some Date</key>  	<date>2009-02-12T22:23:00Z</date>  	<key>Some Data</key> diff --git a/test/plist_cmp.c b/test/plist_cmp.c new file mode 100644 index 0000000..1a66119 --- /dev/null +++ b/test/plist_cmp.c @@ -0,0 +1,138 @@ +/* + * backup_test.c + * source libplist regression test + * + * Copyright (c) 2009 Jonathan Beck All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ + + +#include "plist/plist.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +char compare_plist(plist_t node_l, plist_t node_r) +{ +	plist_t cur_l = NULL; +	plist_t cur_r = NULL; +	int res = 1; + +	cur_l = plist_get_first_child(node_l); +	cur_r = plist_get_first_child(node_r); + +	if ( (!cur_l && cur_r) || (cur_l && !cur_r)) +		return 0; + +	if ( !cur_l && !cur_r ) +		return plist_compare_node_value( node_l, node_r ); + +	while(cur_l && cur_r && res) { + +		if (!(res = compare_plist(cur_l, cur_r))) +			return res; + +		cur_l = plist_get_next_sibling(cur_l); +		cur_r = plist_get_next_sibling(cur_r); +		if ( (!cur_l && cur_r) || (cur_l && !cur_r)) +			return 0; +	} + +	return res; +} + +int main(int argc, char *argv[]) +{ +	FILE *iplist1 = NULL; +	FILE *iplist2 = NULL; +	plist_t root_node1 = NULL; +	plist_t root_node2 = NULL; +	char *plist_1 = NULL; +	char *plist_2 = NULL; +	int size_in1 = 0; +	int size_in2 = 0; +	char *file_in1 = NULL; +	char *file_in2 = NULL; +	int res = 0; + +	struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat)); +	struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat)); + +	if (argc!= 3) { +		printf("Wrong input\n"); +		return 1; +	} + +	file_in1 = argv[1]; +	file_in2 = argv[2]; + +	//read input file +	iplist1 = fopen(file_in1, "rb"); +	iplist2 = fopen(file_in2, "rb"); + +	if (!iplist1 || !iplist2) { +		printf("File does not exists\n"); +		return 2; +	} + +	stat(file_in1, filestats1); +	stat(file_in2, filestats2); + +	size_in1 = filestats1->st_size; +	size_in2 = filestats2->st_size; + +	plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1)); +	plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1)); + +	fread(plist_1, sizeof(char), size_in1, iplist1); +	fread(plist_2, sizeof(char), size_in2, iplist2); + +	fclose(iplist1); +	fclose(iplist2); + +	if (memcmp(plist_1, "bplist00", 8) == 0) +		plist_from_bin(plist_1, size_in1, &root_node1); +	else +		plist_from_xml(plist_1, size_in1, &root_node1); + +	if (memcmp(plist_2, "bplist00", 8) == 0) +		plist_from_bin(plist_2, size_in2, &root_node2); +	else +		plist_from_xml(plist_2, size_in2, &root_node2); + +	if (!root_node1 || !root_node2) { +		printf("PList parsing failed\n"); +		return 3; +	} +	else +		printf("PList parsing succeeded\n"); + +	res = compare_plist(root_node1, root_node2); + + +	plist_free(root_node1); +	plist_free(root_node2); + +	free(plist_1); +	free(plist_2); +	free(filestats1); +	free(filestats2); + +	return !res; +} +   | 
