RomanCreator.cpp

Go to the documentation of this file.
00001 
00010 #include "RomanCreator.h"
00011 #include "RomanConvertTable.h"
00012 #include "UtfString.h"
00013 #include <string>
00014 
00015 using namespace beego;
00016 
00017 
00018 struct RomanCreator::pImpl {
00019   const Uint16* convert_table;
00020   unsigned int max_length;
00021   std::basic_string<Uint16> converted;
00022   std::vector<Uint16> converted_char;
00023 
00024   pImpl(const Uint16* convertTable, unsigned int maxLength)
00025     : convert_table(convertTable), max_length(maxLength) {
00026   }
00027 
00028   size_t ptnlen(const int index, const Uint16* table) {
00029     int length = 0;
00030     while (table[index + length] != 0x0) {
00031       ++length;
00032     }
00033     return length;
00034   }
00035 
00036   size_t replace(size_t match_index, int table_index) {
00037     size_t ptn_length = ptnlen(table_index, convert_table);
00038     converted.replace(match_index, ptn_length,
00039                       &convert_table[table_index - max_length]);
00040 
00041     return ptn_length - ptnlen(table_index - max_length, convert_table);
00042   }
00043 };
00044 
00045 
00046 RomanCreator::RomanCreator(void)
00047   : pimpl(new pImpl(RomanTable[0][0], ROMAN_CONVERT_SIZE_MAX)) {
00048 }
00049 
00050 
00051 RomanCreator::~RomanCreator(void) {
00052 }
00053 
00054 
00055 void RomanCreator::convert(std::vector<Uint16>& dst, const Uint16* input) {
00056   pimpl->converted.clear();
00057 
00058   // 変換文字列を代入
00059   size_t input_length = ustrlen(input);
00060   for (size_t i = 0; i < input_length; ++i) {
00061     pimpl->converted.push_back(input[i]);
00062   }
00063 
00064   int steps = pimpl->max_length * 2;
00065   for (long i = static_cast<int>(pimpl->converted.size()) -1; i >= 0; --i) {
00066     // 一致したパターンを置換する
00067     for (int j = pimpl->max_length;
00068          pimpl->convert_table[j] != 0x0; j += steps) {
00069       int ptn_length = static_cast<int>(pimpl->ptnlen(j, pimpl->convert_table));
00070       int compare_first = i - (ptn_length -1);
00071       if (compare_first < 0) {
00072         continue;
00073       }
00074       size_t match =
00075         pimpl->converted.compare(compare_first, ptn_length,
00076                                  &pimpl->convert_table[j]);
00077       if (match == 0) {
00078         pimpl->replace(compare_first, j);
00079 
00080         // nba -> んば、といった変換用のために、1文字分戻る
00081         ++i;
00082         break;
00083       }
00084     }
00085   }
00086   pimpl->converted.push_back(0x0);
00087 
00088   pimpl->converted_char.clear();
00089   for (size_t i = 0; i < pimpl->converted.size(); ++i) {
00090     pimpl->converted_char.
00091       push_back(static_cast<unsigned char>(pimpl->converted[i]));
00092   }
00093   dst = pimpl->converted_char;
00094 }
00095 

Generated on Mon Apr 13 22:52:01 2009 by  doxygen 1.5.7.1