#include <MiX.h>
#include <extern/STLxx.h>
#include <extern/compose.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <utility>
typedef MiX::Element<char> Person;
typedef std::map<std::string,Person*> Index;
class PhoneBook {
MiX::Document<char>& doc_;
Index index_;
MiX::Document<char>& loadDocument(std::string fname){
std::ifstream fin(fname.c_str());
if(!fin){
MiX::Document<char>& ret = MiX::Document<char>::create("PhoneBook");
MiX::Attribute<char>::create("version","1.0",ret);
MiX::Attribute<char>::create("encoding","UTF-8",ret);
return ret;
}else{
std::string ln,data;
std::getline(fin,ln);
while(!fin.eof()){
data+=ln;
std::getline(fin,ln);
}
fin.close();
MiX::DomParser<char> parser;
parser.setIgnoreSpace(true);
return parser.parse(data.c_str());
}
}
Index loadIndex(MiX::Document<char>& doc){
Index ret;
MiX::NodeList<char>::iterator it = doc.getRoot().getChildren().begin();
MiX::NodeList<char>::iterator last = doc.getRoot().getChildren().end();
for( ;it!=last;++it){
if((*it)->getType()==MiX::Node_Element){
Person* p = dynamic_cast<Person*>(*it);
ret.insert(std::make_pair((*p)("Name").getText(),p));
std::cout << (*p)("Name").getText() << " Loaded." << std::endl;
}
}
return ret;
}
public:
PhoneBook(std::string fname)
: doc_(loadDocument(fname)),index_(loadIndex(doc_)){
}
void store(std::string fname){
std::ofstream fout(fname.c_str());
fout << doc_.toString(true) << std::endl;
fout.close();
}
void createPerson(std::string name,std::string phone){
MiX::Element<char>& e=MiX::Element<char>::create("Person",doc_.getRoot());
MiX::Element<char>& n=MiX::Element<char>::create("Name",e);
MiX::Element<char>& p=MiX::Element<char>::create("Phone",e);
n.setText(name);
p.setText(phone);
index_.insert(std::make_pair(name,&e));
}
Index& getIndex(){
return index_;
}
};
void outputPerson(std::ostream& os,Person& p){
os << p("Name").getText() << " : " << p("Phone").getText() << std::endl;
}
std::string input(const char* prompt){
std::string ret;
std::cout << prompt << ": " << std::flush;
std::cin >> ret;
return ret;
}
char prompt(){
std::string s = input("add/delete/find/list/clear/quit [a,d,f,l,c,q]");
return s.at(0);
}
void error(const char* errmsg){
std::cout << "Error: " << errmsg << std::endl;
}
int main(){
PhoneBook pb("phonebook.xml");
char cmd = '\0';
while(cmd!='q'){
cmd = prompt();
switch(cmd){
case 'a' : case 'A' : {
std::string name = input("Name");
Index::iterator it = pb.getIndex().find(name);
if(it!=pb.getIndex().end()) error("already exists.");
else {
std::string phone = input("Phone");
pb.createPerson(name,phone);
}
break;
}
case 'd' : case 'D' : {
std::string name = input("Name");
Index::iterator it =pb.getIndex().find(name);
if(it==pb.getIndex().end()){
error("not found!");
}else{
it->second->destroy();
pb.getIndex().erase(it);
}
break;
}
case 'f' : case 'F' : {
std::string name = input("Name");
Index::iterator it=pb.getIndex().find(name);
if(it!=pb.getIndex().end())
outputPerson(std::cout,*(it->second));
else error("not found.");
break;
}
case 'l' : case 'L' : {
std::cout << pb.getIndex().size() <<"entries:" << std::endl;
Index::iterator it = pb.getIndex().begin();
Index::iterator last = pb.getIndex().end();
for( ;it!=last;++it) outputPerson(std::cout,*(it->second));
break;
}
case 'c' : case 'C' : {
Index index = pb.getIndex();
Index::iterator it = index.begin();
Index::iterator last = index.end();
for( ;it!=last;++it){
it->second->destroy();
pb.getIndex().erase(it);
}
break;
}
case 'q' : case 'Q' :
default :
break;
}
}
pb.store("phonebook.xml");
}