From 78d71d2cad6f243c6ff31d41380b8c5b58407de5 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Thu, 17 May 2012 17:37:22 +0000 Subject: added some plugins git-svn-id: http://svn.miranda-ng.org/main/trunk@20 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Boltun/Engine/Mind.cpp | 448 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 plugins/Boltun/Engine/Mind.cpp (limited to 'plugins/Boltun/Engine/Mind.cpp') diff --git a/plugins/Boltun/Engine/Mind.cpp b/plugins/Boltun/Engine/Mind.cpp new file mode 100644 index 0000000000..6260177095 --- /dev/null +++ b/plugins/Boltun/Engine/Mind.cpp @@ -0,0 +1,448 @@ +//*********************************************************** +// Copyright © 2008 Valentin Pavlyuchenko +// +// This file is part of Boltun. +// +// Boltun is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// Boltun is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Boltun. If not, see . +// +//*********************************************************** + +#include "Mind.h" +#include +#include +#include "tstring.h" +#include "assert.h" + +#include + +#ifdef UNICODE +#include "MyCodeCvt.h" +#endif + +using namespace std; + +typedef vector string_vec; +typedef multimap string_mmap; + +Mind::Mind() +{ + data = new MindData(); + data->referenceCount = 1; + data->maxSmileLen = 0; +} + +Mind::~Mind() +{ + if (--data->referenceCount == 0) + delete data; +} + +Mind::Mind(const Mind& mind) +{ + mind.data->referenceCount++; + data = mind.data; +} + +const MindData *Mind::GetData() const +{ + return data; +} + +Mind& Mind::operator= (const Mind& mind) +{ + if (--data->referenceCount == 0) + delete data; + mind.data->referenceCount++; + data = mind.data; + return *this; +} + +inline void format(tstring& s) +{ + int pos = s.length() - 1; + if (s[pos] == _T('\r')) + s.resize(pos); +} + +void toLowerStr(TCHAR* ch) +{ + CharLower(ch); +} + +vector Mind::Parse(tstring s) +{ + int len = s.length() - 1; + vector res; + while (len != -1 && _istspace(s[len])) + len--; + if (len < 0) + return res; + s.resize(len); + int it = 0; + while (it != len) + { + while (it != len && _istspace(s[it])) + it++; + if (it == len) + break; + int start = it; + while (it != len && !_istspace(s[it])) + it++; + res.push_back(s.substr(start, it - start)); + } + return res; +} + +void Mind::Load(tstring filename) +{ + basic_ifstream > file; + setlocale(LC_ALL, ""); +#ifdef UNICODE + locale ulocale(locale(), new MyCodeCvt); + file.imbue(ulocale); +#endif + file.open(filename.c_str(), ios_base::in | ios_base::binary); + tstring s1, st; + TCHAR *c, *co; + size_t count; + int error = 0; + int line = 1; +#ifdef UNICODE + bool start = true; +#endif + try + { + while (file.good()) + { + getline(file, st); + if (st.empty()) + break; + line++; +#ifdef UNICODE + if (start) + { + if (st[0] == 65279) + { + st.erase(0, 1); + fileTypeMark = true; + } + else + fileTypeMark = false; + start = false; + } +#endif + format(st); + count = st.length(); + c = co = new TCHAR[count+1]; + _tcscpy(c, st.c_str()); + size_t pos = 0; + while (pos < count && _istspace(*c)) + { + ++pos; + ++c; + } + count -= pos; + if (count > 2) + { + switch (*c) + { + case '(': + if (c[count - 1] != ')') + abort(); + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + ++c; + count -= 2; + c[count] = '\0'; + toLowerStr(c); + { + WordsList l(c); + if (!l.IsEmpty()) + if (l.IsQuestion()) + data->qkeywords.insert(make_pair(l, s1)); + else + data->keywords.insert(make_pair(l, s1)); + } + break; + case '{': + if (c[count - 1] != '}') + abort(); + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + ++c; + count -= 2; + c[count] = '\0'; + toLowerStr(c); + { + WordsList l(c); + if (!l.IsEmpty()) + if (l.IsQuestion()) + data->qspecialEscapes.insert(make_pair(l, s1)); + else + data->specialEscapes.insert(make_pair(l, s1)); + } + break; + case '[': + if (c[count - 1] != ']') + throw error; + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + ++c; + count -= 2; + c[count] = '\0'; + toLowerStr(c); + data->widelyUsed.insert(make_pair(c, s1)); + break; + case '<': + if (c[count - 1] != '>') + throw error; + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + ++c; + count -= 2; + c[count] = '\0'; + if (_tcscmp(c,_T("QUESTION")) == 0) + { + toLowerStr(c); + data->question.insert(s1); + } + else + if (_tcscmp(c,_T("IGNORED")) == 0) + { + toLowerStr(c); + data->special.insert(s1); + } + else + if (_tcscmp(c,_T("ESCAPE")) == 0) + { + data->escape.push_back(s1); + } + else + if (_tcscmp(c,_T("FAILURE")) == 0) + { + data->failure.push_back(s1); + } + else + if (_tcscmp(c,_T("REPEAT")) == 0) + { + data->repeats.push_back(s1); + } + else + { + if (_tcscmp(c,_T("INITIAL")) != 0) + throw error; + data->initial.push_back(s1); + } + break; + case '@': + { + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + ++c; + count -= 1; + toLowerStr(c); + tstring sc(c); + int count1 = s1.length(); + TCHAR *c = new TCHAR[count1 + 1]; + _tcscpy(c, s1.c_str()); + CharLower(c); + s1 = c; + delete c; + vector strs = Parse(s1); + data->raliases.insert(make_pair(sc, strs)); + for (vector::const_iterator it = strs.begin(); it != strs.end(); it++) + data->aliases.insert(make_pair(*it, sc)); + } + break; + default: + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + toLowerStr(c); + data->study.insert(make_pair(c, s1)); + } + } + else + if (count) + { + if (file.eof()) + throw error; + getline(file, s1); + line++; + format(s1); + data->study.insert(make_pair(c, s1)); + } + } + if (!file.eof()) + { + throw error; + } + delete co; + } + catch(...) + { + throw CorruptedMind(line); + delete co; + } +} + +void Mind::Save(tstring filename) const +{ + basic_ofstream > file; +#ifdef UNICODE + locale ulocale(locale(), new MyCodeCvt); + file.imbue(ulocale); +#endif + file.open(filename.c_str(), ios_base::out | ios_base::binary); +#ifdef UNICODE + if (fileTypeMark) + file << TCHAR(65279); +#endif + for (string_mmap::iterator it = data->study.begin(); it != data->study.end(); it++) + { + file << (*it).first << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (multimap::iterator it = data->keywords.begin(); it != data->keywords.end(); it++) + { + file << _T(" (") << (tstring)(*it).first << _T(")") << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (multimap::iterator it = data->qkeywords.begin(); it != data->qkeywords.end(); it++) + { + file << _T(" (") << (tstring)(*it).first << _T(")") << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (multimap::iterator it = data->specialEscapes.begin(); it != data->specialEscapes.end(); it++) + { + file << _T(" {") << (tstring)(*it).first << _T("}") << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (multimap::iterator it = data->qspecialEscapes.begin(); it != data->qspecialEscapes.end(); it++) + { + file << _T(" {") << (tstring)(*it).first << _T("}") << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (string_mmap::iterator it = data->widelyUsed.begin(); it != data->widelyUsed.end(); it++) + { + file << _T(" [") << (*it).first << _T("]") << _T('\r') << endl; + file << (*it).second << _T('\r') << endl; + } + for (set::iterator it = data->question.begin(); it != data->question.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (set::iterator it = data->special.begin(); it != data->special.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (string_vec::iterator it = data->escape.begin(); it != data->escape.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (string_vec::iterator it = data->initial.begin(); it != data->initial.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (string_vec::iterator it = data->failure.begin(); it != data->failure.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (string_vec::iterator it = data->repeats.begin(); it != data->repeats.end(); it++) + { + file << _T(" ") << _T('\r') << endl; + file << (*it) << _T('\r') << endl; + } + for (map>::const_iterator it = data->raliases.begin(); it != data->raliases.end(); it++) + { + tstring s; + const vector& v = (*it).second; + bool first = true; + for (vector::const_iterator it1 = v.begin(); it1 != v.end(); it1++) + { + if (first) + { + first = false; + s = *it1; + } + else + { + s += _T(" ") + *it1; + } + } + file << _T('@') << (*it).first << _T('\r') << endl; + file << s << _T('\r') << endl; + } +} + +void Mind::LoadSmiles(tstring filename) +{ + basic_ifstream > file; + file.open(filename.c_str()); + data->smiles.clear(); + tstring s; + unsigned int l = 0; + while (!file.eof()) + { + getline(file, s); + if (s.length() > l) + l = s.length(); + data->smiles.insert(s); + } + data->maxSmileLen = l; +} + +void Mind::LoadSmiles(void *smiles, size_t size) +{ + data->smiles.clear(); + TCHAR* buf = (TCHAR*)smiles; + unsigned l = 0; + TCHAR* end = buf + size; + while (buf != end) + { + TCHAR *lend = buf; + while (lend != end && *lend != _T('\r')) + lend++; + tstring s(buf, lend - buf); + if ((unsigned)(lend - buf) > l) + l = s.length(); + data->smiles.insert(s); + if (lend == end) + break; + buf = lend + 2; + } + data->maxSmileLen = l; +} -- cgit v1.2.3