Root/src/utilities.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#include "utilities.h"
22
23#include "debug.h"
24
25#include <SDL.h>
26#include <algorithm>
27
28//for browsing the filesystem
29#include <sys/stat.h>
30#include <sys/types.h>
31#include <dirent.h>
32#include <fstream>
33#include <iostream>
34#include <strings.h>
35#include <unistd.h>
36
37using namespace std;
38
39bool case_less::operator()(const string &left, const string &right) const {
40    return strcasecmp(left.c_str(), right.c_str()) < 0;
41}
42
43string trim(const string& s) {
44  auto b = s.find_first_not_of(" \t\r");
45  auto e = s.find_last_not_of(" \t\r");
46  return b == string::npos ? "" : string(s, b, e + 1 - b);
47}
48
49string ltrim(const string& s) {
50  auto b = s.find_first_not_of(" \t\r");
51  return b == string::npos ? "" : string(s, b);
52}
53
54string rtrim(const string& s) {
55  auto e = s.find_last_not_of(" \t\r");
56  return e == string::npos ? "" : string(s, 0, e + 1);
57}
58
59// See this article for a performance comparison of different approaches:
60// http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html
61string readFileAsString(const char *filename) {
62    ifstream in(filename, ios::in | ios::binary);
63    if (!in) {
64        return "<error opening " + string(filename) + ">";
65    }
66
67    // Get file size.
68    in.seekg(0, ios::end);
69    auto size = max(int(in.tellg()), 0); // tellg() returns -1 on errors
70    in.seekg(0, ios::beg);
71
72    string contents(size, '\0');
73    in.read(&contents[0], contents.size());
74    in.close();
75
76    if (in.fail()) {
77        return "<error reading " + string(filename) + ">";
78    } else {
79        contents.shrink_to_fit();
80        return contents;
81    }
82}
83
84bool fileExists(const string &file) {
85    fstream fin;
86    fin.open(file.c_str() ,ios::in);
87    bool exists = fin.is_open();
88    fin.close();
89
90    return exists;
91}
92
93bool rmtree(string path) {
94    DIR *dirp;
95    struct stat st;
96    struct dirent *dptr;
97    string filepath;
98
99    DEBUG("RMTREE: '%s'\n", path.c_str());
100
101    if ((dirp = opendir(path.c_str())) == NULL) return false;
102    if (path[path.length()-1]!='/') path += "/";
103
104    while ((dptr = readdir(dirp))) {
105        filepath = dptr->d_name;
106        if (filepath=="." || filepath=="..") continue;
107        filepath = path+filepath;
108        int statRet = stat(filepath.c_str(), &st);
109        if (statRet == -1) continue;
110        if (S_ISDIR(st.st_mode)) {
111            if (!rmtree(filepath)) return false;
112        } else {
113            if (unlink(filepath.c_str())!=0) return false;
114        }
115    }
116
117    closedir(dirp);
118    return rmdir(path.c_str())==0;
119}
120
121int constrain(int x, int imin, int imax) {
122    return min(imax, max(imin, x));
123}
124
125//Configuration parsing utilities
126int evalIntConf (ConfIntHash& hash, const std::string &key, int def, int imin, int imax) {
127    auto it = hash.find(key);
128    if (it == hash.end()) {
129        return hash[key] = def;
130    } else {
131        return it->second = constrain(it->second, imin, imax);
132    }
133}
134
135bool split (vector<string> &vec, const string &str, const string &delim, bool destructive) {
136    vec.clear();
137
138    if (delim.empty()) {
139        vec.push_back(str);
140        return false;
141    }
142
143    std::string::size_type i = 0;
144    std::string::size_type j = 0;
145
146    while(1) {
147        j = str.find(delim,i);
148        if (j==std::string::npos) {
149            vec.push_back(str.substr(i));
150            break;
151        }
152
153        if (!destructive)
154            j += delim.size();
155
156        vec.push_back(str.substr(i,j-i));
157
158        if (destructive)
159            i = j + delim.size();
160
161        if (i==str.size()) {
162            vec.push_back(std::string());
163            break;
164        }
165    }
166
167    return true;
168}
169
170string strreplace (string orig, const string &search, const string &replace) {
171    string::size_type pos = orig.find( search, 0 );
172    while (pos != string::npos) {
173        orig.replace(pos,search.length(),replace);
174        pos = orig.find( search, pos+replace.length() );
175    }
176    return orig;
177}
178
179string cmdclean (string cmdline) {
180    string spchars = "\\`$();|{}&'\"*?<>[]!^~-#\n\r ";
181    for (uint i=0; i<spchars.length(); i++) {
182        string curchar = spchars.substr(i,1);
183        cmdline = strreplace(cmdline, curchar, "\\"+curchar);
184    }
185    return cmdline;
186}
187
188int intTransition(int from, int to, long tickStart, long duration, long tickNow) {
189    if (tickNow<0) tickNow = SDL_GetTicks();
190    return constrain(((tickNow-tickStart) * (to-from)) / duration, from, to);
191    // elapsed increments
192}
193
194void inject_user_event(enum EventCode code, void *data1, void *data2)
195{
196    SDL_UserEvent e = {
197        .type = SDL_USEREVENT,
198        .code = code,
199        .data1 = data1,
200        .data2 = data2,
201    };
202
203    /* Inject an user event, that will be handled as a "repaint"
204     * event by the InputManager */
205    SDL_PushEvent((SDL_Event *) &e);
206    DEBUG("Injecting event code %i\n", e.code);
207}
208

Archive Download this file



interactive