150 lines
5.4 KiB
C++
150 lines
5.4 KiB
C++
|
#ifndef CASE_CONVERTER_FACTORY_HDR
|
||
|
#define CASE_CONVERTER_FACTORY_HDR
|
||
|
|
||
|
#include <boost/shared_ptr.hpp>
|
||
|
|
||
|
#include "general_case_converter.hpp"
|
||
|
#include "concordia/concordia_exception.hpp"
|
||
|
#include "regular_contextual_case_converter.hpp"
|
||
|
#include "turkish_and_azeri_lower_contextual_case_converter.hpp"
|
||
|
#include "turkish_and_azeri_upper_contextual_case_converter.hpp"
|
||
|
|
||
|
const size_t NUMBER_OF_CASE_TYPES = 3;
|
||
|
|
||
|
template<typename octet_iterator, typename output_iterator>
|
||
|
class CaseConverterFactory {
|
||
|
|
||
|
private:
|
||
|
enum {
|
||
|
LOWER_INDEX = 0,
|
||
|
UPPER_INDEX = 1,
|
||
|
TITLE_INDEX = 2
|
||
|
};
|
||
|
|
||
|
boost::shared_ptr<RangeBasedCaseConverter> rangeBasedCaseConverters_[NUMBER_OF_CASE_TYPES];
|
||
|
boost::shared_ptr<SpecialCasingConverter> specialCasingConverters_[NUMBER_OF_CASE_TYPES];
|
||
|
|
||
|
boost::shared_ptr<ContextualCaseConverter> regularContextualCaseConverter_;
|
||
|
boost::shared_ptr<ContextualCaseConverter> turkishAndAzeriUpperContextualCaseConverter_;
|
||
|
boost::shared_ptr<ContextualCaseConverter> turkishAndAzeriLowerContextualCaseConverter_;
|
||
|
|
||
|
class Exception : public ConcordiaException {
|
||
|
public:
|
||
|
Exception(const std::string& msg): ConcordiaException(msg) {
|
||
|
}
|
||
|
|
||
|
virtual ~Exception() throw() {}
|
||
|
};
|
||
|
|
||
|
void checkRawConverters_(int case_index) {
|
||
|
if (!rangeBasedCaseConverters_[case_index]) {
|
||
|
boost::shared_ptr<RangeBasedCaseConverter> converter;
|
||
|
|
||
|
switch (case_index) {
|
||
|
case LOWER_INDEX: converter.reset(
|
||
|
new RangeBasedCaseConverter(
|
||
|
LOWER_CASE_RANGES_SIZE,
|
||
|
LOWER_CASE_RANGES));
|
||
|
break;
|
||
|
case UPPER_INDEX: converter.reset(
|
||
|
new RangeBasedCaseConverter(
|
||
|
UPPER_CASE_RANGES_SIZE,
|
||
|
UPPER_CASE_RANGES));
|
||
|
break;
|
||
|
case TITLE_INDEX: converter.reset(
|
||
|
new RangeBasedCaseConverter(
|
||
|
TITLE_CASE_RANGES_SIZE,
|
||
|
TITLE_CASE_RANGES));
|
||
|
break;
|
||
|
default:
|
||
|
throw Exception("????");
|
||
|
}
|
||
|
|
||
|
rangeBasedCaseConverters_[case_index] = converter;
|
||
|
}
|
||
|
|
||
|
if (!specialCasingConverters_[case_index]) {
|
||
|
boost::shared_ptr<SpecialCasingConverter> converter;
|
||
|
|
||
|
switch (case_index) {
|
||
|
case LOWER_INDEX: converter.reset(
|
||
|
new SpecialCasingConverter(
|
||
|
LOWER_SPECIAL_CASING_SIZE,
|
||
|
LOWER_SPECIAL_CASING));
|
||
|
break;
|
||
|
case UPPER_INDEX: converter.reset(
|
||
|
new SpecialCasingConverter(
|
||
|
UPPER_SPECIAL_CASING_SIZE,
|
||
|
UPPER_SPECIAL_CASING));
|
||
|
break;
|
||
|
case TITLE_INDEX: converter.reset(
|
||
|
new SpecialCasingConverter(
|
||
|
TITLE_SPECIAL_CASING_SIZE,
|
||
|
TITLE_SPECIAL_CASING));
|
||
|
break;
|
||
|
default:
|
||
|
throw Exception("????");
|
||
|
}
|
||
|
|
||
|
specialCasingConverters_[case_index] = converter;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
boost::shared_ptr<GeneralCaseConverter<octet_iterator, output_iterator> > getCaseConverter_(
|
||
|
int case_index, const std::string& language_code) {
|
||
|
|
||
|
checkRawConverters_(case_index);
|
||
|
|
||
|
return boost::shared_ptr<GeneralCaseConverter<octet_iterator, output_iterator> >(
|
||
|
new GeneralCaseConverter<octet_iterator, output_iterator> (
|
||
|
rangeBasedCaseConverters_[case_index],
|
||
|
specialCasingConverters_[case_index],
|
||
|
getContextualCaseConverterForLanguage_(language_code, case_index)));
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
CaseConverterFactory():
|
||
|
regularContextualCaseConverter_(
|
||
|
boost::shared_ptr<ContextualCaseConverter>(new RegularContextualCaseConverter())),
|
||
|
turkishAndAzeriUpperContextualCaseConverter_(
|
||
|
boost::shared_ptr<ContextualCaseConverter>(
|
||
|
new TurkishAndAzeriUpperContextualCaseConverter())),
|
||
|
turkishAndAzeriLowerContextualCaseConverter_(
|
||
|
boost::shared_ptr<ContextualCaseConverter>(
|
||
|
new TurkishAndAzeriLowerContextualCaseConverter())) {
|
||
|
}
|
||
|
|
||
|
boost::shared_ptr<ContextualCaseConverter> getContextualCaseConverterForLanguage_(
|
||
|
const std::string& languageCode, int caseIndex) {
|
||
|
if (languageCode == "lt")
|
||
|
throw Exception(std::string("language '") + languageCode
|
||
|
+ "' is not handled yet in lower/upper/title-casing");
|
||
|
|
||
|
if (languageCode == "tr" || languageCode == "az")
|
||
|
return
|
||
|
caseIndex == LOWER_INDEX
|
||
|
? turkishAndAzeriLowerContextualCaseConverter_
|
||
|
: turkishAndAzeriUpperContextualCaseConverter_;
|
||
|
|
||
|
return regularContextualCaseConverter_;
|
||
|
}
|
||
|
|
||
|
boost::shared_ptr<GeneralCaseConverter<octet_iterator, output_iterator> >
|
||
|
getLowerCaseConverter(const std::string& language_code) {
|
||
|
return getCaseConverter_(LOWER_INDEX, language_code);
|
||
|
}
|
||
|
|
||
|
boost::shared_ptr<GeneralCaseConverter<octet_iterator, output_iterator> >
|
||
|
getUpperCaseConverter(const std::string& language_code) {
|
||
|
return getCaseConverter_(UPPER_INDEX, language_code);
|
||
|
}
|
||
|
|
||
|
boost::shared_ptr<GeneralCaseConverter<octet_iterator, output_iterator> >
|
||
|
getTitleCaseConverter(const std::string& language_code) {
|
||
|
return getCaseConverter_(TITLE_INDEX, language_code);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif
|