/*!
  \file
  \brief string 用の split 関数

  boost を使わずに実装 \n
  boost を使って良いのならば、boost::algorithm::split を使うべき

  \author Satofumi KAMIMURA

  $Id: split.cpp 927 2009-05-26 13:33:47Z satofumi $
*/

#include "split.h"

using namespace std;


#if 1
size_t qrk::split(vector<string>& tokens,
                  const string& line, const char* split_pattern,
                  bool continious_pattern)
{
  string buffer = line;
  char* q = &buffer[0];
  size_t n = line.size();
  for (size_t i = 0; i < n; ++i, ++q) {
    for (const char* p = split_pattern; *p != '\0'; ++p) {
      if (*q == *p) {
        *q = '\0';
        break;
      }
    }
  }

  for (size_t i = 0; i < n; ++i) {
    if ((buffer[i] != '\0') || (! continious_pattern)) {
      string line = &buffer[i];
      tokens.push_back(line);
      i += line.size();
    }
  }
  return tokens.size();
}

#else
// 区切り文字を、空白に置き換えて分割を行う
size_t qrk::split(vector<string>& tokens,
                  const string& line, const char* split_pattern,
                  bool continious_pattern)
{
  size_t next_first = 0;
  while (true) {

    size_t first_position = line.find_first_not_of(split_pattern, next_first);
    if (first_position == string::npos) {
      // 以降にトークンがないため、中断
      break;
    }

    if (! continious_pattern) {
      int n = static_cast<int>(first_position - next_first);
      // セパレータ分だけ空トークンを追加する
      for (int i = 1; i < n; ++i) {
        tokens.push_back("");
      }
    }

    // トークンの終わりを探す
    size_t last_position = line.find_first_of(split_pattern, first_position);
    size_t length = string::npos;
    if (last_position != string::npos) {
      length = last_position - first_position;
    }
    tokens.push_back(line.substr(first_position, length));

    if (next_first == string::npos) {
      // 最後まで探索したため、中断
      break;
    }

    next_first = last_position;
  }
  return tokens.size();
}
#endif
