#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include <boost/exception/all.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/lexical_cast.hpp>
#include "Serialization.hpp"
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
struct SSentence
{
std::vector<unsigned short> Words;
unsigned char* Save(unsigned char* pFile);
unsigned char* Load(unsigned char* pFile);
};
unsigned char* SSentence::Save(unsigned char* pFile)
{
return pFile;
}
unsigned char* SSentence::Load(unsigned char* pFile)
{
return pFile;
}
struct SWord
{
std::string Text;
std::vector<SSentence> Usages;
unsigned char* Save(unsigned char* pFile);
unsigned char* Load(unsigned char* pFile);
};
unsigned char* SWord::Save(unsigned char* pFile)
{
return pFile;
}
unsigned char* SWord::Load(unsigned char* pFile)
{
return pFile;
}
// 2 byte unsigned 0 to 65,535
// 1 byte unsigned 0 to 255
struct SPermutation
{
std::vector<unsigned short> WordIndices;
std::vector<unsigned char> UsageIndices;
unsigned char* Save(unsigned char* pFile);
unsigned char* Load(unsigned char* pFile);
};
unsigned char* SPermutation::Save(unsigned char* pFile)
{
return pFile;
}
unsigned char* SPermutation::Load(unsigned char* pFile)
{
return pFile;
}
std::vector<SWord> g_words;
std::vector<SPermutation> g_sentences;
void SaveAll(std::string strFileName)
{
std::ofstream ofs(strFileName.c_str());
if(!ofs)
{
return;
}
unsigned int nWords = g_words.size();
ofs.write((char*)&nWords, sizeof(unsigned int));
for (unsigned int iii = 0; iii < nWords; ++iii)
{
SWord& refWord = g_words[iii];
unsigned int nWordLength = refWord.Text.size();
ofs.write((char*)&nWordLength, sizeof(unsigned int));
ofs.write((char*)refWord.Text.c_str(), sizeof(unsigned char) * nWordLength);
unsigned int nUsages = refWord.Usages.size();
ofs.write((char*)&nUsages, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nUsages; ++jjj)
{
SSentence& refSentence = refWord.Usages[jjj];
unsigned int nSentenceWords = refSentence.Words.size();
ofs.write((char*)&nSentenceWords, sizeof(unsigned int));
for (unsigned int lll = 0; lll < nSentenceWords; ++lll)
{
ofs.write((char*)&refSentence.Words[lll], sizeof(unsigned short));
}
}
}
unsigned int nPermutations = g_sentences.size();
ofs.write((char*)&nPermutations, sizeof(unsigned int));
for (unsigned int iii = 0; iii < nPermutations; ++iii)
{
SPermutation& refPerm = g_sentences[iii];
unsigned int nWordIndices = refPerm.WordIndices.size();
ofs.write((char*)&nWordIndices, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nWordIndices; ++jjj)
{
ofs.write((char*)&refPerm.WordIndices[jjj], sizeof(unsigned short));
}
unsigned int nUsageIndices = refPerm.UsageIndices.size();
ofs.write((char*)&nUsageIndices, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nUsageIndices; ++jjj)
{
ofs.write((char*)&refPerm.UsageIndices[jjj], sizeof(unsigned char));
}
}
ofs.close();
}
void LoadAll(std::string strFileName)
{
std::ifstream ifs(strFileName.c_str());
if(!ifs)
{
return;
}
unsigned int nWords = 0;
ifs.read((char*)&nWords, sizeof(unsigned int));
for (unsigned int iii = 0; iii < nWords; ++iii)
{
SWord word ;
unsigned int nWordLength = 0;
ifs.read((char*)&nWordLength, sizeof(unsigned int));
unsigned char *pWord = new unsigned char[nWordLength + 1];
pWord[nWordLength] = '\0';
ifs.read((char*)pWord, sizeof(unsigned char) * nWordLength);
word.Text.append((char*)pWord);
delete [] pWord;
unsigned int nUsages = 0;
ifs.read((char*)&nUsages, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nUsages; ++jjj)
{
SSentence sentence ;
unsigned int nSentenceWords = 0;
ifs.read((char*)&nSentenceWords, sizeof(unsigned int));
for (unsigned int lll = 0; lll < nSentenceWords; ++lll)
{
unsigned short shWord = 0;
ifs.read((char*)&shWord, sizeof(unsigned short));
sentence.Words.push_back(shWord);
}
word.Usages.push_back(sentence);
}
g_words.push_back(word);
}
unsigned int nPermutations = 0;
ifs.read((char*)&nPermutations, sizeof(unsigned int));
for (unsigned int iii = 0; iii < nPermutations; ++iii)
{
SPermutation perm = g_sentences[iii];
unsigned int nWordIndices = 0;
ifs.read((char*)&nWordIndices, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nWordIndices; ++jjj)
{
unsigned short shWordIndex = 0;
ifs.read((char*)&shWordIndex, sizeof(unsigned short));
perm.WordIndices.push_back(shWordIndex);
}
unsigned int nUsageIndices = 0;
ifs.read((char*)&nUsageIndices, sizeof(unsigned int));
for (unsigned int jjj = 0; jjj < nUsageIndices; ++jjj)
{
unsigned char chUsageIndex = 0;
ifs.read((char*)&chUsageIndex, sizeof(unsigned char));
perm.UsageIndices.push_back(chUsageIndex);
}
}
ifs.close();
}
bool WordExists(std::string strName)
{
bool bVal = false;
for (unsigned int iii = 0; iii < g_words.size(); ++iii)
{
if (g_words[iii].Text == strName)
{
bVal = true;
break;
}
}
return bVal;
}
unsigned short GetWordIndex(std::string strName)
{
unsigned short shVal = 0;
for (unsigned int iii = 0; iii < g_words.size(); ++iii)
{
if (g_words[iii].Text == strName)
{
shVal = iii;
break;
}
}
return shVal;
}
std::string GetInput();
void Test();
int main()
{
Test();
return 0;
}
std::string GetInput()
{
std::string strInput;
getline(cin, strInput);
return strInput;
}
void Test()
{
LoadAll("language.bin");
unsigned short nCurrentPermutation = 0;
unsigned short nCurrentWord = 0 ;
std::string strInput;
while (strInput != "exit")
{
strInput.clear();
cout << "Waiting for input: " << endl;
strInput = GetInput();
std::vector<std::string> chunks = split(strInput, ' ');
if (chunks[0] == "help")
{
cout << "help helps." << endl;
cout << "create word textForNameHere" << endl;
cout << "create permutation word word word word etc. " << endl;
cout << "add word usage word word word word etc." << endl;
cout << "add permutation usages index index index index etc." << endl;
cout << "set word textForNameHere" << endl;
cout << "set permutation word word word word etc." << endl;
cout << "edit word name textForNewName" << endl;
cout << "edit word usage usageIndex word word word word etc." << endl;
cout << "list word" << endl;
}
else if (chunks[0] == "create")
{
if (chunks.size() < 2)
{
continue;
}
if (chunks[1] == "word")
{
if (chunks.size() < 3)
{
continue;
}
if (WordExists(chunks[2]) == true)
{
cout << "That word exists already." << endl;
continue;
}
SWord word;
word.Text = chunks[2];
g_words.push_back(word);
nCurrentWord = g_words.size() - 1;
}
else if(chunks[1] == "permutation")
{
if (chunks.size() < 3)
{
continue;
}
SPermutation permutation;
for (unsigned int iii = 2; iii < chunks.size(); ++iii)
{
unsigned short wordIndex = GetWordIndex(chunks[iii]);
permutation.WordIndices.push_back(wordIndex);
}
g_sentences.push_back(permutation);
nCurrentPermutation = g_sentences.size() - 1;
}
}
else if (chunks[0] == "add")
{
if (chunks.size() < 3)
{
continue;
}
if (chunks[1] == "word")
{
if (chunks[2] == "usage")
{
if (chunks.size() < 4)
{
continue;
}
SSentence sentence;
for (unsigned int iii = 3; iii < chunks.size(); ++iii)
{
unsigned short wordIndex = GetWordIndex(chunks[iii]);
sentence.Words.push_back(wordIndex);
}
g_words[nCurrentWord].Usages.push_back(sentence);
}
}
else if (chunks[1] == "permutation")
{
if (chunks.size() < 3)
{
continue;
}
if (chunks[2] == "usages")
{
if (chunks.size() < 4)
{
continue;
}
for (unsigned int iii = 3; iii < chunks.size(); ++iii)
{
unsigned char chVal = boost::lexical_cast<unsigned char>(chunks[iii]);
g_sentences[nCurrentPermutation].UsageIndices.push_back(chVal);
}
}
}
}
else if (chunks[0] == "set")
{
if (chunks.size() < 3)
{
continue;
}
if (chunks[1] == "word")
{
nCurrentWord = GetWordIndex(chunks[2]);
}
else if (chunks[1] == "permutation")
{
std::vector<unsigned short> indices;
for (unsigned int iii = 2; iii < chunks.size(); ++iii)
{
unsigned short wordIndex = GetWordIndex(chunks[iii]);
indices.push_back(wordIndex);
}
for (unsigned int iii = 0; iii < g_sentences.size(); ++iii)
{
SPermutation& refPermutation = g_sentences[iii];
if (refPermutation.WordIndices == indices)
{
nCurrentPermutation = iii;
break;
}
}
}
}
else if (chunks[0] == "edit")
{
if (chunks.size() < 3)
{
continue;
}
if (chunks[1] == "word")
{
if (chunks[2] == "name")
{
if (chunks.size() < 4)
{
continue;
}
g_words[nCurrentWord].Text = chunks[3];
}
else if (chunks[2] == "usage")
{
if (chunks.size() < 5)
{
continue;
}
unsigned int nUsageIndex = boost::lexical_cast<unsigned int>(chunks[3]);
if (nUsageIndex >= g_words[nCurrentWord].Usages.size())
{
continue;
}
SSentence sentence;
for (unsigned int iii = 4; iii < chunks.size(); ++iii)
{
unsigned short wordIndex = GetWordIndex(chunks[iii]);
sentence.Words.push_back(wordIndex);
}
g_words[nCurrentWord].Usages[nUsageIndex] = sentence;
}
}
}
else if (chunks[0] == "list")
{
if (chunks.size() < 2)
{
continue;
}
if (chunks[1] == "word")
{
cout << "Name: " << g_words[nCurrentWord].Text << endl;
cout << "Sentences:" << endl;
for (unsigned int iii = 0; iii < g_words[nCurrentWord].Usages.size(); ++iii)
{
cout << "#: " << iii << endl;
SSentence& refSentence = g_words[nCurrentWord].Usages[iii];
unsigned int nUsageWords = refSentence.Words.size();
for (unsigned int jjj = 0; jjj < nUsageWords; ++jjj)
{
cout << " " << g_words[refSentence.Words[jjj]].Text;
}
cout << endl;
}
}
}
}
SaveAll("language.bin");
}