1 /*
2   Copyright (C) 2009 Facundo Domínguez
3 
4   This file is part of Spacejunk.
5 
6   Spacejunk is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10 
11   Foobar is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "scorelist.h"
21 #include "resourcemanager.h"
22 #include "parsercombinators.h"
23 #include <iostream>
24 #include <SDL.h>
25 #include <unistd.h>
26 #include <fstream>
27 #include <sstream>
28 #include <iterator>
29 #include <assert.h>
30 
31 using namespace std;
32 
ScoreList()33 ScoreList::ScoreList() {
34     if (access((GetResourcePath()+"scores.hi").c_str(),F_OK)) return;
35 
36     ifstream f((GetResourcePath()+"scores.hi").c_str());
37     if (f.fail()) {
38         SDL_SetError("Error reading score list: Could not open file scores.hi");
39         exit(1);
40     }
41     f>>*this;
42     if (f.fail()) {
43         cout<<"On file \""<<(GetResourcePath()+"scores.hi").c_str()<<"\": "<<SDL_GetError()<<endl;
44         exit(1);
45     };
46 };
47 
~ScoreList()48 ScoreList::~ScoreList() {
49     ofstream f((GetResourcePath()+"scores.hi").c_str());
50     if (f.fail()) {
51         cerr<<"Error writing score list: Could not open file "<<(GetResourcePath()+"scores.hi").c_str()<<"\n";
52     }
53     f<<*this;
54     if (f.fail()) {
55         cout<<"Writting file \""<<(GetResourcePath()+"scores.hi").c_str()<<"\": "<<SDL_GetError()<<endl;
56     };
57 }
58 
inside(int points)59 bool ScoreList::inside(int points) {
60     return scores.upper_bound(points)!=scores.end();
61 };
62 
size() const63 int ScoreList::size() const {
64     return scores.size();
65 };
position(iterator i)66 int ScoreList::position(iterator i) {
67     return distance(scores.begin(),i);
68 };
erase(iterator i)69 void ScoreList::erase(iterator i) {
70     scores.erase(i);
71 };
setName(const std::string & name,iterator i)72 void ScoreList::setName(const std::string & name,iterator i) {
73     i->second=name;
74 };
erase_last()75 void ScoreList::erase_last() {
76     assert(!scores.empty());
77     scores.erase(--scores.end());
78 };
79 
setScore(const string & name,int points)80 ScoreList::iterator ScoreList::setScore(const string & name,int points) {
81     return scores.insert(make_pair(points,name));
82 };
83 
getNames() const84 string ScoreList::getNames() const {
85     ostringstream temp;
86     for (Map::const_iterator i=scores.begin();i!=scores.end();i++)
87         temp<<i->second<<"\n";
88     return temp.str();
89 };
getPoints() const90 string ScoreList::getPoints() const {
91     ostringstream temp;
92     for (Map::const_iterator i=scores.begin();i!=scores.end();i++)
93         temp<<i->first<<"\n";
94     return temp.str();
95 };
96 
97 
operator <<(ostream & o,const ScoreList & s)98 ostream & operator << (ostream & o,const ScoreList & s) {
99     STDStreamPrinter sp(o);
100     OStreamUTF8Encoder sc(&sp);
101     for (ScoreList::Map::const_iterator i=s.scores.begin();i!=s.scores.end();i++)
102         sc<<'"'<<stows(i->second)<<"\" "<<i->first<<'\n';
103     return o;
104 };
105 
operator >>(istream & i,ScoreList & s)106 istream & operator >> (istream & i,ScoreList & s) {
107     StreamTokenizer t(i);
108     basic_string<wchar_t> wname;
109     Lexer p=&t;
110     PARSEbegin(Lexer,p);
111     MANYbegin
112     int points;
113     LATTTEXT(&wname);
114     LINT(&points);
115     s.setScore(wstos(wname),points);
116     MANYend
117     PARSEend;
118 
119     if (p.error()) {
120         SDL_SetError((string("Reading ScoreList: "+p.errorMessage()).c_str()));
121         i.setstate(ios::failbit);
122     } else if (i.eof()) i.clear(ios::eofbit);
123 
124     return i;
125 };
126 
127