diff options
| -rw-r--r-- | src/pugixml.cpp | 134 | ||||
| -rw-r--r-- | src/pugixml.hpp | 30 | ||||
| -rw-r--r-- | tests/test_dom_modify.cpp | 34 | ||||
| -rw-r--r-- | tests/test_dom_text.cpp | 91 | ||||
| -rw-r--r-- | tests/test_dom_traverse.cpp | 55 | 
5 files changed, 341 insertions, 3 deletions
| diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 78fe50a..874d611 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -3386,6 +3386,34 @@ PUGI__NS_BEGIN  		return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y');  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN long long get_value_llong(const char_t* value, long long def) +	{ +		if (!value) return def; + +		int base = get_integer_base(value); + +	#ifdef PUGIXML_WCHAR_MODE +		return wcstoll(value, 0, base); +	#else +		return strtoll(value, 0, base); +	#endif +	} + +	PUGI__FN unsigned long long get_value_ullong(const char_t* value, unsigned long long def) +	{ +		if (!value) return def; + +		int base = get_integer_base(value); + +	#ifdef PUGIXML_WCHAR_MODE +		return wcstoull(value, 0, base); +	#else +		return strtoull(value, 0, base); +	#endif +	} +#endif +  	// set value with conversion functions  	PUGI__FN bool set_value_buffer(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char (&buf)[128])  	{ @@ -3428,6 +3456,24 @@ PUGI__NS_BEGIN  		return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, long long value) +	{ +		char buf[128]; +		sprintf(buf, "%lld", value); +	 +		return set_value_buffer(dest, header, header_mask, buf); +	} + +	PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned long long value) +	{ +		char buf[128]; +		sprintf(buf, "%llu", value); +	 +		return set_value_buffer(dest, header, header_mask, buf); +	} +#endif +  	// we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick  	PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result)  	{ @@ -3891,6 +3937,18 @@ namespace pugi  		return impl::get_value_bool(_attr ? _attr->value : 0, def);  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN long long xml_attribute::as_llong(long long def) const +	{ +		return impl::get_value_llong(_attr ? _attr->value : 0, def); +	} + +	PUGI__FN unsigned long long xml_attribute::as_ullong(unsigned long long def) const +	{ +		return impl::get_value_ullong(_attr ? _attr->value : 0, def); +	} +#endif +  	PUGI__FN bool xml_attribute::empty() const  	{  		return !_attr; @@ -3946,6 +4004,20 @@ namespace pugi  		return *this;  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN xml_attribute& xml_attribute::operator=(long long rhs) +	{ +		set_value(rhs); +		return *this; +	} + +	PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long long rhs) +	{ +		set_value(rhs); +		return *this; +	} +#endif +  	PUGI__FN bool xml_attribute::set_name(const char_t* rhs)  	{  		if (!_attr) return false; @@ -3988,6 +4060,22 @@ namespace pugi  		return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN bool xml_attribute::set_value(long long rhs) +	{ +		if (!_attr) return false; + +		return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); +	} + +	PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) +	{ +		if (!_attr) return false; + +		return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); +	} +#endif +  #ifdef __BORLANDC__  	PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs)  	{ @@ -4936,6 +5024,22 @@ namespace pugi  		return impl::get_value_bool(d ? d->value : 0, def);  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN long long xml_text::as_llong(long long def) const +	{ +		xml_node_struct* d = _data(); + +		return impl::get_value_llong(d ? d->value : 0, def); +	} + +	PUGI__FN unsigned long long xml_text::as_ullong(unsigned long long def) const +	{ +		xml_node_struct* d = _data(); + +		return impl::get_value_ullong(d ? d->value : 0, def); +	} +#endif +  	PUGI__FN bool xml_text::set(const char_t* rhs)  	{  		xml_node_struct* dn = _data_new(); @@ -4971,6 +5075,22 @@ namespace pugi  		return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN bool xml_text::set(long long rhs) +	{ +		xml_node_struct* dn = _data_new(); + +		return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; +	} + +	PUGI__FN bool xml_text::set(unsigned long long rhs) +	{ +		xml_node_struct* dn = _data_new(); + +		return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; +	} +#endif +  	PUGI__FN xml_text& xml_text::operator=(const char_t* rhs)  	{  		set(rhs); @@ -5001,6 +5121,20 @@ namespace pugi  		return *this;  	} +#ifdef PUGIXML_HAS_LONG_LONG +	PUGI__FN xml_text& xml_text::operator=(long long rhs) +	{ +		set(rhs); +		return *this; +	} + +	PUGI__FN xml_text& xml_text::operator=(unsigned long long rhs) +	{ +		set(rhs); +		return *this; +	} +#endif +  	PUGI__FN xml_node xml_text::data() const  	{  		return xml_node(_data()); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index db1507a..ae43fd2 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -320,6 +320,11 @@ namespace pugi  		double as_double(double def = 0) const;  		float as_float(float def = 0) const; +	#ifdef PUGIXML_HAS_LONG_LONG +		long long as_llong(long long def = 0) const; +		unsigned long long as_ullong(unsigned long long def = 0) const; +	#endif +  		// Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty  		bool as_bool(bool def = false) const; @@ -333,6 +338,11 @@ namespace pugi  		bool set_value(double rhs);  		bool set_value(bool rhs); +	#ifdef PUGIXML_HAS_LONG_LONG +		bool set_value(long long rhs); +		bool set_value(unsigned long long rhs); +	#endif +  		// Set attribute value (equivalent to set_value without error checking)  		xml_attribute& operator=(const char_t* rhs);  		xml_attribute& operator=(int rhs); @@ -340,6 +350,11 @@ namespace pugi  		xml_attribute& operator=(double rhs);  		xml_attribute& operator=(bool rhs); +	#ifdef PUGIXML_HAS_LONG_LONG +		xml_attribute& operator=(long long rhs); +		xml_attribute& operator=(unsigned long long rhs); +	#endif +  		// Get next/previous attribute in the attribute list of the parent node  		xml_attribute next_attribute() const;  		xml_attribute previous_attribute() const; @@ -637,6 +652,11 @@ namespace pugi  		double as_double(double def = 0) const;  		float as_float(float def = 0) const; +	#ifdef PUGIXML_HAS_LONG_LONG +		long long as_llong(long long def = 0) const; +		unsigned long long as_ullong(unsigned long long def = 0) const; +	#endif +  		// Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty  		bool as_bool(bool def = false) const; @@ -649,6 +669,11 @@ namespace pugi  		bool set(double rhs);  		bool set(bool rhs); +	#ifdef PUGIXML_HAS_LONG_LONG +		bool set(long long rhs); +		bool set(unsigned long long rhs); +	#endif +  		// Set text (equivalent to set without error checking)  		xml_text& operator=(const char_t* rhs);  		xml_text& operator=(int rhs); @@ -656,6 +681,11 @@ namespace pugi  		xml_text& operator=(double rhs);  		xml_text& operator=(bool rhs); +	#ifdef PUGIXML_HAS_LONG_LONG +		xml_text& operator=(long long rhs); +		xml_text& operator=(unsigned long long rhs); +	#endif +  		// Get the data node (node_pcdata or node_cdata) for this object  		xml_node data() const;  	}; diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 620504a..c7a3989 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -15,7 +15,7 @@ TEST_XML(dom_attr_assign, "<node/>")  	node.append_attribute(STR("attr4")) = 4294967295u;  	node.append_attribute(STR("attr5")) = 4294967294u; -	xml_attribute() = 2147483647; +	xml_attribute() = 4294967295u;  	node.append_attribute(STR("attr6")) = 0.5;  	xml_attribute() = 0.5; @@ -50,6 +50,38 @@ TEST_XML(dom_attr_set_value, "<node/>")  	CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"true\" />"));  } +#ifdef PUGIXML_HAS_LONG_LONG +TEST_XML(dom_attr_assign_llong, "<node/>") +{ +	xml_node node = doc.child(STR("node")); +	 +	node.append_attribute(STR("attr1")) = -9223372036854775807ll; +	node.append_attribute(STR("attr2")) = -9223372036854775807ll - 1; +	xml_attribute() = -9223372036854775807ll - 1; + +	node.append_attribute(STR("attr3")) = 18446744073709551615ull; +	node.append_attribute(STR("attr4")) = 18446744073709551614ull; +	xml_attribute() = 18446744073709551615ull; + +	CHECK_NODE(node, STR("<node attr1=\"-9223372036854775807\" attr2=\"-9223372036854775808\" attr3=\"18446744073709551615\" attr4=\"18446744073709551614\" />")); +} + +TEST_XML(dom_attr_set_value_llong, "<node/>") +{ +	xml_node node = doc.child(STR("node")); +	 +	CHECK(node.append_attribute(STR("attr1")).set_value(-9223372036854775807ll)); +	CHECK(node.append_attribute(STR("attr2")).set_value(-9223372036854775807ll - 1)); +	CHECK(!xml_attribute().set_value(-9223372036854775807ll - 1)); + +	CHECK(node.append_attribute(STR("attr3")).set_value(18446744073709551615ull)); +	CHECK(node.append_attribute(STR("attr4")).set_value(18446744073709551614ull)); +	CHECK(!xml_attribute().set_value(18446744073709551615ull)); + +	CHECK_NODE(node, STR("<node attr1=\"-9223372036854775807\" attr2=\"-9223372036854775808\" attr3=\"18446744073709551615\" attr4=\"18446744073709551614\" />")); +} +#endif +  TEST_XML(dom_node_set_name, "<node>text</node>")  {  	CHECK(doc.child(STR("node")).set_name(STR("n"))); diff --git a/tests/test_dom_text.cpp b/tests/test_dom_text.cpp index 2e38f29..fb65b03 100644 --- a/tests/test_dom_text.cpp +++ b/tests/test_dom_text.cpp @@ -155,6 +155,56 @@ TEST_XML(dom_text_as_bool, "<node><text1>0</text1><text2>1</text2><text3>true</t  	CHECK(!node.child(STR("text7")).text().as_bool());
  }
 +#ifdef PUGIXML_HAS_LONG_LONG
 +TEST_XML(dom_text_as_llong, "<node><text1>1</text1><text2>-1</text2><text3>-9223372036854775808</text3><text4>9223372036854775807</text4><text5>0</text5></node>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +
 +	CHECK(xml_text().as_llong() == 0);
 +	CHECK(node.child(STR("text1")).text().as_llong() == 1);
 +	CHECK(node.child(STR("text2")).text().as_llong() == -1);
 +	CHECK(node.child(STR("text3")).text().as_llong() == -9223372036854775807ll - 1);
 +	CHECK(node.child(STR("text4")).text().as_llong() == 9223372036854775807ll);
 +	CHECK(node.child(STR("text5")).text().as_llong() == 0);
 +}
 +
 +TEST_XML(dom_text_as_llong_hex, "<node><text1>0777</text1><text2>0x5ab</text2><text3>0XFf</text3><text4>-0x20</text4><text5>-0x8000000000000000</text5><text6>0x</text6></node>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +
 +	CHECK(node.child(STR("text1")).text().as_llong() == 777); // no octal support! intentional
 +	CHECK(node.child(STR("text2")).text().as_llong() == 1451);
 +	CHECK(node.child(STR("text3")).text().as_llong() == 255);
 +	CHECK(node.child(STR("text4")).text().as_llong() == -32);
 +	CHECK(node.child(STR("text5")).text().as_llong() == -9223372036854775807ll - 1);
 +	CHECK(node.child(STR("text6")).text().as_llong() == 0);
 +}
 +
 +TEST_XML(dom_text_as_ullong, "<node><text1>0</text1><text2>1</text2><text3>9223372036854775807</text3><text4>18446744073709551615</text4><text5>0</text5></node>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +
 +	CHECK(xml_text().as_ullong() == 0);
 +	CHECK(node.child(STR("text1")).text().as_ullong() == 0);
 +	CHECK(node.child(STR("text2")).text().as_ullong() == 1);
 +	CHECK(node.child(STR("text3")).text().as_ullong() == 9223372036854775807ll);
 +	CHECK(node.child(STR("text4")).text().as_ullong() == 18446744073709551615ull);
 +	CHECK(node.child(STR("text5")).text().as_ullong() == 0);
 +}
 +
 +TEST_XML(dom_text_as_ullong_hex, "<node><text1>0777</text1><text2>0x5ab</text2><text3>0XFf</text3><text4>0x20</text4><text5>0xFFFFFFFFFFFFFFFF</text5><text6>0x</text6></node>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +
 +	CHECK(node.child(STR("text1")).text().as_ullong() == 777); // no octal support! intentional
 +	CHECK(node.child(STR("text2")).text().as_ullong() == 1451);
 +	CHECK(node.child(STR("text3")).text().as_ullong() == 255);
 +	CHECK(node.child(STR("text4")).text().as_ullong() == 32);
 +	CHECK(node.child(STR("text5")).text().as_ullong() == 18446744073709551615ull);
 +	CHECK(node.child(STR("text6")).text().as_ullong() == 0);
 +}
 +#endif
 +
  TEST_XML(dom_text_get_no_state, "<node/>")
  {
      xml_node node = doc.child(STR("node"));
 @@ -208,7 +258,7 @@ TEST_XML(dom_text_assign, "<node/>")  	node.append_child(STR("text4")).text() = 4294967295u;
  	node.append_child(STR("text5")).text() = 4294967294u;
 -	xml_text() = 2147483647;
 +	xml_text() = 4294967295u;
  	node.append_child(STR("text6")).text() = 0.5;
  	xml_text() = 0.5;
 @@ -232,7 +282,7 @@ TEST_XML(dom_text_set_value, "<node/>")  	CHECK(node.append_child(STR("text4")).text().set(4294967295u));
  	CHECK(node.append_child(STR("text5")).text().set(4294967294u));
 -	CHECK(!xml_text().set(2147483647));
 +	CHECK(!xml_text().set(4294967295u));
  	CHECK(node.append_child(STR("text6")).text().set(0.5));
  	CHECK(!xml_text().set(0.5));
 @@ -243,6 +293,38 @@ TEST_XML(dom_text_set_value, "<node/>")  	CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
  }
 +#ifdef PUGIXML_HAS_LONG_LONG
 +TEST_XML(dom_text_assign_llong, "<node/>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +	
 +	node.append_child(STR("text1")).text() = -9223372036854775807ll;
 +	node.append_child(STR("text2")).text() = -9223372036854775807ll - 1;
 +	xml_text() = -9223372036854775807ll - 1;
 +
 +	node.append_child(STR("text3")).text() = 18446744073709551615ull;
 +	node.append_child(STR("text4")).text() = 18446744073709551614ull;
 +	xml_text() = 18446744073709551615ull;
 +	
 +	CHECK_NODE(node, STR("<node><text1>-9223372036854775807</text1><text2>-9223372036854775808</text2><text3>18446744073709551615</text3><text4>18446744073709551614</text4></node>"));
 +}
 +
 +TEST_XML(dom_text_set_value_llong, "<node/>")
 +{
 +	xml_node node = doc.child(STR("node"));
 +	
 +	CHECK(node.append_child(STR("text1")).text().set(-9223372036854775807ll));
 +	CHECK(node.append_child(STR("text2")).text().set(-9223372036854775807ll - 1));
 +	CHECK(!xml_text().set(-9223372036854775807ll - 1));
 +
 +	CHECK(node.append_child(STR("text3")).text().set(18446744073709551615ull));
 +	CHECK(node.append_child(STR("text4")).text().set(18446744073709551614ull));
 +	CHECK(!xml_text().set(18446744073709551615ull));
 +
 +	CHECK_NODE(node, STR("<node><text1>-9223372036854775807</text1><text2>-9223372036854775808</text2><text3>18446744073709551615</text3><text4>18446744073709551614</text4></node>"));
 +}
 +#endif
 +
  TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
  {
      xml_node node = doc.child(STR("node"));
 @@ -285,4 +367,9 @@ TEST(dom_text_defaults)      CHECK(text.as_double(42) == 42);
      CHECK(text.as_float(42) == 42);
      CHECK(text.as_bool(true) == true);
 +
 +#ifdef PUGIXML_HAS_LONG_LONG
 +    CHECK(text.as_llong(42) == 42);
 +    CHECK(text.as_ullong(42) == 42);
 +#endif
  }
 diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index 9c7c9ec..43fec80 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -179,6 +179,56 @@ TEST_XML(dom_attr_as_bool, "<node attr1='0' attr2='1' attr3='true' attr4='True'  	CHECK(!node.attribute(STR("attr7")).as_bool());  } +#ifdef PUGIXML_HAS_LONG_LONG +TEST_XML(dom_attr_as_llong, "<node attr1='1' attr2='-1' attr3='-9223372036854775808' attr4='9223372036854775807' attr5='0'/>") +{ +	xml_node node = doc.child(STR("node")); + +	CHECK(xml_attribute().as_llong() == 0); +	CHECK(node.attribute(STR("attr1")).as_llong() == 1); +	CHECK(node.attribute(STR("attr2")).as_llong() == -1); +	CHECK(node.attribute(STR("attr3")).as_llong() == -9223372036854775807ll - 1); +	CHECK(node.attribute(STR("attr4")).as_llong() == 9223372036854775807ll); +	CHECK(node.attribute(STR("attr5")).as_llong() == 0); +} + +TEST_XML(dom_attr_as_llong_hex, "<node attr1='0777' attr2='0x5ab' attr3='0XFf' attr4='-0x20' attr5='-0x8000000000000000' attr6='0x'/>") +{ +	xml_node node = doc.child(STR("node")); + +	CHECK(node.attribute(STR("attr1")).as_llong() == 777); // no octal support! intentional +	CHECK(node.attribute(STR("attr2")).as_llong() == 1451); +	CHECK(node.attribute(STR("attr3")).as_llong() == 255); +	CHECK(node.attribute(STR("attr4")).as_llong() == -32); +	CHECK(node.attribute(STR("attr5")).as_llong() == -9223372036854775807ll - 1); +	CHECK(node.attribute(STR("attr6")).as_llong() == 0); +} + +TEST_XML(dom_attr_as_ullong, "<node attr1='0' attr2='1' attr3='9223372036854775807' attr4='18446744073709551615' attr5='0'/>") +{ +	xml_node node = doc.child(STR("node")); + +	CHECK(xml_attribute().as_ullong() == 0); +	CHECK(node.attribute(STR("attr1")).as_ullong() == 0); +	CHECK(node.attribute(STR("attr2")).as_ullong() == 1); +	CHECK(node.attribute(STR("attr3")).as_ullong() == 9223372036854775807ull); +	CHECK(node.attribute(STR("attr4")).as_ullong() == 18446744073709551615ull); +	CHECK(node.attribute(STR("attr5")).as_ullong() == 0); +} + +TEST_XML(dom_attr_as_ullong_hex, "<node attr1='0777' attr2='0x5ab' attr3='0XFf' attr4='0x20' attr5='0xFFFFFFFFFFFFFFFF' attr6='0x'/>") +{ +	xml_node node = doc.child(STR("node")); + +	CHECK(node.attribute(STR("attr1")).as_ullong() == 777); // no octal support! intentional +	CHECK(node.attribute(STR("attr2")).as_ullong() == 1451); +	CHECK(node.attribute(STR("attr3")).as_ullong() == 255); +	CHECK(node.attribute(STR("attr4")).as_ullong() == 32); +	CHECK(node.attribute(STR("attr5")).as_ullong() == 18446744073709551615ull); +	CHECK(node.attribute(STR("attr6")).as_ullong() == 0); +} +#endif +  TEST(dom_attr_defaults)  {      xml_attribute attr; @@ -189,6 +239,11 @@ TEST(dom_attr_defaults)      CHECK(attr.as_double(42) == 42);      CHECK(attr.as_float(42) == 42);      CHECK(attr.as_bool(true) == true); + +#ifdef PUGIXML_HAS_LONG_LONG +    CHECK(attr.as_llong(42) == 42); +    CHECK(attr.as_ullong(42) == 42); +#endif  }  TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>") | 
