変換処理のテストと実装

変換のテストは、cppunit を使い、とりあえずこんな感じ。(ローマ字変換のみ抜粋)

void InputConverterTest::romanConverterTest(void) {

  InputConverter roman_converter(&RomanTable[0][0][0], ROMAN_CONVERT_SIZE_MAX);

  // a -> あ
  const Uint16* converted = roman_converter.convert("a");
  CPPUNIT_ASSERT_EQUAL(static_cast<Uint16>(0x3042), converted[0]);
  CPPUNIT_ASSERT_EQUAL(static_cast<Uint16>(0x0), converted[1]);

  // aka -> あか
  converted = roman_converter.convert("aka");
  CPPUNIT_ASSERT_EQUAL(static_cast<Uint16>(0x3042), converted[0]);
  CPPUNIT_ASSERT_EQUAL(static_cast<Uint16>(0x304b), converted[1]);
  CPPUNIT_ASSERT_EQUAL(static_cast<Uint16>(0x0), converted[2]);
} 

いい感じかと。
あとは、これのテストを通過するように、InputConverterconvert() の中身を実装すればよい。

で、実装したプログラム。
#include "inputConverter.h"
#include <vector>


struct InputConverter::pImpl {
  const Uint16* convert_table;
  unsigned int max_length;
  std::vector<Uint16> converted_str;

  pImpl(const Uint16* convertTable, unsigned int maxLength)
    : convert_table(convertTable), max_length(maxLength) {
  }

  int convert(const int index, const char* input, const int input_index) {
    for (int i = 0; ((convert_table[index +i] == input[input_index +i]) ||
                     (convert_table[index +i] == 0x0)); ++i) {
      if (convert_table[index +i] != 0x0) {
        continue;
      }
      Uint16 ch;
      for (int j = 0;(ch = convert_table[index + max_length +j]) != 0x0; ++j) {
        converted_str.push_back(ch);
      }
      return i;
    }
    return -1;
  }
};


InputConverter::InputConverter(const Uint16* convertTable,
                               unsigned int maxLength)
  : pimpl(new pImpl(convertTable, maxLength)) {
}


InputConverter::~InputConverter(void) {
}


const Uint16* InputConverter::convert(const char* input) {
  pimpl->converted_str.clear();

  // 一致したパターンを置き換えていく
  int steps = pimpl->max_length * 2;
  int input_length = strlen(input);
  for (int input_index = 0; input_index < input_length; ++input_index) {
    // 変換候補のマッチング
    for (int index = 0; pimpl->convert_table[index] != 0x0; index += steps) {
      // 入力と変換候補が一致するかの判定
      int n = pimpl->convert(index, input, input_index);
      if (n > 0) {
        input_index += n -1;

        // "か + (濁点)" といった変換のために、返還後の一文字を再評価する
        --index;
        break;
      }
    }
  }
  pimpl->converted_str.push_back(0x0);

  return &pimpl->converted_str[0];
} 

まぁ、こんな感じ?
次は、これを使ってユーザが入力した文字を変換して画面表示するサンプルの予定。

入力を変換して表示するサンプル へ」

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