00001 #include "osl/record/ki2.h"
00002 #include "osl/record/ki2IOError.h"
00003 #include "osl/misc/sjis2euc.h"
00004 #include <boost/algorithm/string/trim.hpp>
00005 #include <fstream>
00006 #include <iostream>
00007
00008 namespace osl
00009 {
00010 namespace record
00011 {
00012 namespace
00013 {
00014 enum ParseResult
00015 {
00016 OK = 0,
00017 KOMAOCHI,
00018 };
00019
00020 ParseResult ki2ParseLine(RecordVisitor& rv,
00021 std::string line,
00022 const osl::record::KanjiMove& kmove)
00023 {
00024 boost::algorithm::trim(line);
00025
00026 if (line.empty() || line.at(0) == '*')
00027 return OK;
00028 else if (line.size() > 6 && line.substr(0,6) == "ꡧ")
00029 {
00030 Record *record = rv.getRecord();
00031 const std::string player_name(line.substr(7));
00032 record->setPlayer(osl::BLACK, player_name);
00033 return OK;
00034 }
00035 else if (line.size() > 6 && line.substr(0,6) == "ꡧ")
00036 {
00037 Record *record = rv.getRecord();
00038 const std::string player_name(line.substr(7));
00039 record->setPlayer(osl::WHITE, player_name);
00040 return OK;
00041 }
00042 else if (line.size() > 8 && line.substr(0,8) == "䡧")
00043 return KOMAOCHI;
00044 else if (line.substr(0,2) != "" && line.substr(0,2) != "")
00045 return OK;
00046
00047 std::string move_str;
00048 for (size_t i = 0; ; )
00049 {
00050 if (i < line.size() &&
00051 (line.at(i) == ' ' || line.at(i) == '\t'))
00052 {
00053 ++i;
00054 continue;
00055 }
00056
00057 if ( (line.substr(i,2) == "" ||
00058 line.substr(i,2) == "" ||
00059 i+1 >= line.size())
00060 && !move_str.empty())
00061 {
00062
00063 Move last_move;
00064 if (rv.getLastMove())
00065 last_move = rv.getLastMove()->getMove();
00066 const NumEffectState state(*rv.getState());
00067 const Move move = kmove.strToMove(move_str, state, last_move);
00068 rv.addMoveAndAdvance(move);
00069 move_str.clear();
00070 }
00071 if (i+1 >= line.size())
00072 return OK;
00073 move_str.append(line.substr(i,2));
00074 i += 2;
00075 }
00076 }
00077
00078 }
00079 }
00080 }
00081
00082
00083 osl::record::ki2::
00084 InputStream::InputStream(std::istream& is, bool verbose)
00085 : is(is), state(SimpleState(HIRATE))
00086 {
00087 if (! is)
00088 {
00089 std::cerr << "InputStream::InputStream cannot read \n";
00090 abort();
00091 }
00092 kmove.setVerbose(verbose);
00093 }
00094
00095 osl::record::ki2::
00096 InputStream::~InputStream(){}
00097
00098 void osl::record::ki2::
00099 InputStream::load(Record* rec)
00100 {
00101 rv.setState(&state);
00102 rv.setRecord(rec);
00103 std::string line;
00104 while (std::getline(is, line))
00105 {
00106 osl::misc::sjis2euc(line);
00107 const ParseResult result = ki2ParseLine(rv, line, kmove);
00108 switch (result)
00109 {
00110 case OK:
00111 continue;
00112 case KOMAOCHI:
00113 {
00114 const std::string msg = "ERROR: Komaochi (handicapped game) records are not available: ";
00115 std::cerr << msg << "\n";
00116 throw Ki2IOError(msg);
00117 }
00118 default:
00119 assert(false);
00120 }
00121 }
00122 }
00123
00124 osl::record::ki2::
00125 Ki2File::Ki2File(const std::string& fileName, bool verbose)
00126 : verbose(verbose)
00127 {
00128 std::ifstream ifs(fileName.c_str());
00129 if (! ifs)
00130 {
00131 const std::string msg = "Ki2File::Ki2File file cannot read ";
00132 std::cerr << msg << fileName << "\n";
00133 throw Ki2IOError(msg + fileName);
00134 }
00135 InputStream irs(ifs, verbose);
00136 irs.load(&rec);
00137 }
00138
00139 const osl::record::Record& osl::record::ki2::
00140 Ki2File::getRecord() const
00141 {
00142 return rec;
00143 }
00144
00145 const osl::SimpleState& osl::record::ki2::
00146 Ki2File::getInitialState() const
00147 {
00148 return rec.getInitialState();
00149 }