#include "range_based_case_converter.hpp" uint32_t RangeBasedCaseConverter::convert(uint32_t code_point) const { const CaseConversionRecord* conversionRecord = findRecord_(code_point); return conversionRecord == 0 ? code_point : applyRecord_(conversionRecord, code_point); } const CaseConversionRecord* RangeBasedCaseConverter::findRecord_(uint32_t code_point) const { for (size_t i = 0; i < tableSize_; ++i) { const CaseConversionRecord* currentRecord = &conversionTable_[i]; if (code_point < currentRecord->lo_code_point) return 0; if (code_point <= currentRecord->hi_code_point) return currentRecord; } return 0; } uint32_t RangeBasedCaseConverter::applyRecord_( const CaseConversionRecord* conversionRecord, uint32_t code_point) const { if (shouldBeSkipped_(conversionRecord, code_point)) return code_point; return applyDelta_(conversionRecord->delta, code_point); } bool RangeBasedCaseConverter::shouldBeSkipped_( const CaseConversionRecord* conversionRecord, uint32_t code_point) const { return isSkipRecord_(conversionRecord) && code_point % 2 != conversionRecord->lo_code_point % 2; } bool RangeBasedCaseConverter::isSkipRecord_(const CaseConversionRecord* conversionRecord) const { return conversionRecord->delta == EVEN_ODD_SKIP || conversionRecord->delta == ODD_EVEN_SKIP; } uint32_t RangeBasedCaseConverter::applyDelta_(int32_t delta, uint32_t code_point) const { switch (delta) { case EVEN_ODD: case EVEN_ODD_SKIP: return code_point % 2 == 0 ? code_point+1 : code_point-1; case ODD_EVEN: case ODD_EVEN_SKIP: return code_point % 2 == 1 ? code_point+1 : code_point-1; default: return code_point + delta; } }