diff options
| author | Remko Tronçon <git@el-tramo.be> | 2012-06-04 17:15:34 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2012-06-05 07:32:01 (GMT) | 
| commit | e43999d275ff27970ba973edd2be68fb6b998aaf (patch) | |
| tree | b3442e40a221b19f60535028e04712396dabe7ed /Swiften/IDN/StringPrep.cpp | |
| parent | 1514e787b28ee09ea28d75828bf41049696fd5c7 (diff) | |
| download | swift-e43999d275ff27970ba973edd2be68fb6b998aaf.zip swift-e43999d275ff27970ba973edd2be68fb6b998aaf.tar.bz2  | |
Added ICU support.
Diffstat (limited to 'Swiften/IDN/StringPrep.cpp')
| -rw-r--r-- | Swiften/IDN/StringPrep.cpp | 89 | 
1 files changed, 85 insertions, 4 deletions
diff --git a/Swiften/IDN/StringPrep.cpp b/Swiften/IDN/StringPrep.cpp index 9085569..dfaba06 100644 --- a/Swiften/IDN/StringPrep.cpp +++ b/Swiften/IDN/StringPrep.cpp @@ -1,23 +1,101 @@  /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2012 Remko Tronçon   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */  #include <Swiften/IDN/StringPrep.h> -extern "C" -{ +#if defined(HAVE_ICU) +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include <Swiften/IDN/ICUConverter.h> +#include <unicode/usprep.h> +#include <unicode/ucnv.h> +#elif defined(HAVE_LIBIDN) +extern "C" {  	#include <stringprep.h>  }; +#endif  #include <vector>  #include <cassert>  #include <Swiften/Base/SafeAllocator.h> +#include <boost/shared_ptr.hpp>  using namespace Swift; -	namespace { +#if defined(HAVE_ICU) + +namespace { +	static UStringPrepProfileType getICUProfileType(StringPrep::Profile profile) { +		switch(profile) { +			case StringPrep::NamePrep: return USPREP_RFC3491_NAMEPREP; break; +			case StringPrep::XMPPNodePrep: return USPREP_RFC3920_NODEPREP; break; +			case StringPrep::XMPPResourcePrep: return USPREP_RFC3920_RESOURCEPREP; break; +			case StringPrep::SASLPrep: return USPREP_RFC4013_SASLPREP; break; +		} +		assert(false); +		return USPREP_RFC3491_NAMEPREP; +	} + +	template<typename StringType> +	std::vector<char, SafeAllocator<char> > getStringPrepared(const StringType& s, StringPrep::Profile profile) { +		UErrorCode status = U_ZERO_ERROR; +		ICUConverter converter; + +		boost::shared_ptr<UStringPrepProfile> icuProfile(usprep_openByType(getICUProfileType(profile), &status), usprep_close); +		assert(U_SUCCESS(status)); + +		ICUConverter::ICUString icuInput = converter.convertToICUString(s); +		ICUConverter::ICUString icuResult; +		UParseError parseError; +		icuResult.resize(icuInput.size()); +		int icuResultLength = usprep_prepare(icuProfile.get(), vecptr(icuInput), icuInput.size(), vecptr(icuResult), icuResult.size(), USPREP_ALLOW_UNASSIGNED, &parseError, &status); icuResult.resize(icuResultLength); +		if (status == U_BUFFER_OVERFLOW_ERROR) { +			status = U_ZERO_ERROR; +			icuResult.resize(icuResultLength); +			icuResultLength = usprep_prepare(icuProfile.get(), vecptr(icuInput), icuInput.size(), vecptr(icuResult), icuResult.size(), USPREP_ALLOW_UNASSIGNED, &parseError, &status); icuResult.resize(icuResultLength); +		} +		if (U_FAILURE(status)) { +			return std::vector<char, SafeAllocator<char> >(); +		} +		icuResult.resize(icuResultLength); + +		return converter.convertToArray(icuResult); +	} +} + +namespace Swift { + +std::string StringPrep::getPrepared(const std::string& s, Profile profile) { +	if (s.empty()) { +		return ""; +	} +	std::vector<char, SafeAllocator<char> > preparedData = getStringPrepared(s, profile); +	if (preparedData.empty()) { +		throw std::exception(); +	} +	return std::string(vecptr(preparedData)); +} + +SafeByteArray StringPrep::getPrepared(const SafeByteArray& s, Profile profile) { +	if (s.empty()) { +		return SafeByteArray(); +	} +	std::vector<char, SafeAllocator<char> > preparedData = getStringPrepared(s, profile); +	if (preparedData.empty()) { +		throw std::exception(); +	} +	return createSafeByteArray(reinterpret_cast<const char*>(vecptr(preparedData))); +} + +} + +//////////////////////////////////////////////////////////////////////////////// + +#elif defined(HAVE_LIBIDN) + +namespace {  	static const int MAX_STRINGPREP_SIZE = 1024;  	const Stringprep_profile* getLibIDNProfile(StringPrep::Profile profile) { @@ -63,3 +141,6 @@ SafeByteArray StringPrep::getPrepared(const SafeByteArray& s, Profile profile) {  }  } + +#endif +  | 
 Swift