diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugixml.cpp | 77 | 
1 files changed, 43 insertions, 34 deletions
| diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 56d7c75..4bc971b 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -127,6 +127,16 @@ using std::memset;  #	define PUGI__MSVC_CRT_VERSION _MSC_VER  #endif +// Not all platforms have snprintf; we define a wrapper that uses snprintf if possible. This only works with buffers with a known size. +#if __cplusplus >= 201103 +#	define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) +#elif defined(_MSC_VER) && _MSC_VER >= 1400 +#	define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, sizeof(buf), _TRUNCATE, __VA_ARGS__) +#else +#	define PUGI__SNPRINTF sprintf +#endif + +// We put implementation details into an anonymous namespace in source mode, but have to keep it in non-anonymous namespace in header-only mode to prevent binary bloat.  #ifdef PUGIXML_HEADER_ONLY  #	define PUGI__NS_BEGIN namespace pugi { namespace impl {  #	define PUGI__NS_END } } @@ -353,7 +363,7 @@ PUGI__NS_BEGIN  				bucket = (bucket + probe + 1) & hashmod;  			} -			assert(false && "Hash table is full"); +			assert(false && "Hash table is full"); // unreachable  			return 0;  		} @@ -2144,7 +2154,7 @@ PUGI__NS_BEGIN  		if (encoding == encoding_latin1)  			return convert_buffer_generic(out_buffer, out_length, contents, size, latin1_decoder()); -		assert(false && "Invalid encoding"); +		assert(false && "Invalid encoding"); // unreachable  		return false;  	}  #else @@ -2249,7 +2259,7 @@ PUGI__NS_BEGIN  		if (encoding == encoding_latin1)  			return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); -		assert(false && "Invalid encoding"); +		assert(false && "Invalid encoding"); // unreachable  		return false;  	}  #endif @@ -2696,7 +2706,7 @@ PUGI__NS_BEGIN  		case 5: return strconv_pcdata_impl<opt_true, opt_false, opt_true>::parse;  		case 6: return strconv_pcdata_impl<opt_true, opt_true, opt_false>::parse;  		case 7: return strconv_pcdata_impl<opt_true, opt_true, opt_true>::parse; -		default: assert(false); return 0; // should not get here +		default: assert(false); return 0; // unreachable  		}  	} @@ -2873,7 +2883,7 @@ PUGI__NS_BEGIN  		case 13: return strconv_attribute_impl<opt_true>::parse_wnorm;  		case 14: return strconv_attribute_impl<opt_false>::parse_wnorm;  		case 15: return strconv_attribute_impl<opt_true>::parse_wnorm; -		default: assert(false); return 0; // should not get here +		default: assert(false); return 0; // unreachable  		}  	} @@ -3622,7 +3632,7 @@ PUGI__NS_BEGIN  		if (encoding == encoding_latin1)  			return convert_buffer_output_generic(r_u8, data, length, wchar_decoder(), latin1_writer()); -		assert(false && "Invalid encoding"); +		assert(false && "Invalid encoding"); // unreachable  		return 0;  	}  #else @@ -3661,7 +3671,7 @@ PUGI__NS_BEGIN  		if (encoding == encoding_latin1)  			return convert_buffer_output_generic(r_u8, data, length, utf8_decoder(), latin1_writer()); -		assert(false && "Invalid encoding"); +		assert(false && "Invalid encoding"); // unreachable  		return 0;  	}  #endif @@ -4188,7 +4198,7 @@ PUGI__NS_BEGIN  				break;  			default: -				assert(false && "Invalid node type"); +				assert(false && "Invalid node type"); // unreachable  		}  	} @@ -4632,7 +4642,7 @@ PUGI__NS_BEGIN  	PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value)  	{  		char buf[128]; -		sprintf(buf, "%.9g", value); +		PUGI__SNPRINTF(buf, "%.9g", value);  		return set_value_ascii(dest, header, header_mask, buf);  	} @@ -4641,7 +4651,7 @@ PUGI__NS_BEGIN  	PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value)  	{  		char buf[128]; -		sprintf(buf, "%.17g", value); +		PUGI__SNPRINTF(buf, "%.17g", value);  		return set_value_ascii(dest, header, header_mask, buf);  	} @@ -6290,7 +6300,7 @@ namespace pugi  			return _root->value && (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0 ? _root->value - doc.buffer : -1;  		default: -			assert(false && "Invalid node type"); +			assert(false && "Invalid node type"); // unreachable  			return -1;  		}  	} @@ -7252,7 +7262,7 @@ PUGI__NS_BEGIN  		return middle;  	} -	template <typename T, typename Pred> void partition(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend) +	template <typename T, typename Pred> void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend)  	{  		// invariant: array is split into 4 groups: = < ? > (each variable denotes the boundary between the groups)  		T* eq = begin; @@ -7290,7 +7300,7 @@ PUGI__NS_BEGIN  			// partition in three chunks (< = >)  			I eqbeg, eqend; -			partition(begin, end, *median, pred, &eqbeg, &eqend); +			partition3(begin, end, *median, pred, &eqbeg, &eqend);  			// loop on larger half  			if (eqbeg - begin > end - eqend) @@ -7980,11 +7990,11 @@ PUGI__NS_BEGIN  	// gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent  #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) -	PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) +	PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent)  	{  		// get base values  		int sign, exponent; -		_ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign); +		_ecvt_s(buffer, sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign);  		// truncate redundant zeros  		truncate_zeros(buffer, buffer + strlen(buffer)); @@ -7994,12 +8004,10 @@ PUGI__NS_BEGIN  		*out_exponent = exponent;  	}  #else -	PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) +	PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent)  	{  		// get a scientific notation value with IEEE DBL_DIG decimals -		sprintf(buffer, "%.*e", DBL_DIG, value); -		assert(strlen(buffer) < buffer_size); -		(void)!buffer_size; +		PUGI__SNPRINTF(buffer, "%.*e", DBL_DIG, value);  		// get the exponent (possibly negative)  		char* exponent_string = strchr(buffer, 'e'); @@ -8036,7 +8044,7 @@ PUGI__NS_BEGIN  		char* mantissa;  		int exponent; -		convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); +		convert_number_to_mantissa_exponent(value, mantissa_buffer, &mantissa, &exponent);  		// allocate a buffer of suitable length for the number  		size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4; @@ -8498,7 +8506,7 @@ PUGI__NS_BEGIN  			break;  		default: -			assert(false && "Invalid variable type"); +			assert(false && "Invalid variable type"); // unreachable  		}  	} @@ -8519,7 +8527,7 @@ PUGI__NS_BEGIN  			return lhs->set(static_cast<const xpath_variable_boolean*>(rhs)->value);  		default: -			assert(false && "Invalid variable type"); +			assert(false && "Invalid variable type"); // unreachable  			return false;  		}  	} @@ -8606,7 +8614,7 @@ PUGI__NS_BEGIN  			return *min_element(begin, end, document_order_comparator());  		default: -			assert(false && "Invalid node set type"); +			assert(false && "Invalid node set type"); // unreachable  			return xpath_node();  		}  	} @@ -9336,7 +9344,7 @@ PUGI__NS_BEGIN  				}  			} -			assert(false && "Wrong types"); +			assert(false && "Wrong types"); // unreachable  			return false;  		} @@ -9411,7 +9419,7 @@ PUGI__NS_BEGIN  			}  			else  			{ -				assert(false && "Wrong types"); +				assert(false && "Wrong types"); // unreachable  				return false;  			}  		} @@ -9629,7 +9637,7 @@ PUGI__NS_BEGIN  				break;  			default: -				assert(false && "Unknown axis"); +				assert(false && "Unknown axis"); // unreachable  			}  			return false; @@ -9824,7 +9832,7 @@ PUGI__NS_BEGIN  			}  			default: -				assert(false && "Unimplemented axis"); +				assert(false && "Unimplemented axis"); // unreachable  			}  		} @@ -9905,7 +9913,7 @@ PUGI__NS_BEGIN  			}  			default: -				assert(false && "Unimplemented axis"); +				assert(false && "Unimplemented axis"); // unreachable  			}  		} @@ -10146,7 +10154,7 @@ PUGI__NS_BEGIN  				}  				default: -					assert(false && "Wrong expression for return type boolean"); +					assert(false && "Wrong expression for return type boolean"); // unreachable  					return false;  				}  			} @@ -10281,7 +10289,7 @@ PUGI__NS_BEGIN  				}  				default: -					assert(false && "Wrong expression for return type number"); +					assert(false && "Wrong expression for return type number"); // unreachable  					return 0;  				} @@ -10571,7 +10579,7 @@ PUGI__NS_BEGIN  				}  				default: -					assert(false && "Wrong expression for return type string"); +					assert(false && "Wrong expression for return type string"); // unreachable  					return xpath_string();  				}  			} @@ -10662,7 +10670,7 @@ PUGI__NS_BEGIN  					return step_do(c, stack, eval, axis_to_type<axis_self>());  				default: -					assert(false && "Unknown axis"); +					assert(false && "Unknown axis"); // unreachable  					return xpath_node_set_raw();  				}  			} @@ -10700,7 +10708,7 @@ PUGI__NS_BEGIN  			// fallthrough  			default: -				assert(false && "Wrong expression for return type node set"); +				assert(false && "Wrong expression for return type node set"); // unreachable  				return xpath_node_set_raw();  			}  		} @@ -12042,7 +12050,7 @@ namespace pugi  			return static_cast<const impl::xpath_variable_boolean*>(this)->name;  		default: -			assert(false && "Invalid variable type"); +			assert(false && "Invalid variable type"); // unreachable  			return 0;  		}  	} @@ -12593,6 +12601,7 @@ namespace pugi  #undef PUGI__DMC_VOLATILE  #undef PUGI__UNSIGNED_OVERFLOW  #undef PUGI__MSVC_CRT_VERSION +#undef PUGI__SNPRINTF  #undef PUGI__NS_BEGIN  #undef PUGI__NS_END  #undef PUGI__FN | 
