File: ecl_util.hh

package info (click to toggle)
enigma 1.20-dfsg.1-2.2
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye
  • size: 64,696 kB
  • sloc: xml: 153,614; cpp: 63,581; ansic: 31,088; sh: 4,825; makefile: 1,858; yacc: 288; perl: 84; sed: 16
file content (291 lines) | stat: -rw-r--r-- 8,373 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
 * Copyright (C) 2002,2003,2004,2005 Daniel Heck
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#ifndef ECL_UTIL_HH_INCLUDED
#define ECL_UTIL_HH_INCLUDED

#include <string>
#include <algorithm>

/* hide GNU extensions for non-gnu compilers: */
#ifndef __GNU__
# ifndef __attribute__
// #  define __attribute__(x)
// # error wuah
# endif
#endif

namespace ecl
{

/*
** Base class for classes that may not be copied, neither via copy
** constructor or assignment operator.
*/
    class Nocopy {
        Nocopy(const Nocopy&);            // not implemented to cause compiler error message on usage!
        Nocopy& operator=(const Nocopy&); // not implemented to cause compiler error message on usage!
    public:
        Nocopy() {}
    };

/*
** Some kind of smart pointer.  Almost verbatim from tc++pl3
*/
    template <class X> class Handle {
        X *rep;
        int *cnt;
    public:
        X *operator->() { return rep; }
        X *get() const { return rep; }
        X &operator *() { return *rep; }

        explicit Handle(X *p=0) : rep(p), cnt(new int(1)) {}
        Handle(const Handle<X>& a) : rep(a.rep), cnt(a.cnt) {
            ++(*cnt);
        }
        Handle<X> &operator=(const Handle<X> &a) {
            if (cnt == a.cnt) return *this;
            if (--(*cnt) == 0) {
                delete rep;
                delete cnt;
            }
            rep = a.rep;
            cnt = a.cnt;
            (*cnt)++;
            return *this;
        }
        ~Handle() {
            if (--(*cnt) == 0) {
                delete rep;
                delete cnt;
            }
        }
    };

/*
** More C++ magic.  This class wraps around arbitrary linear
** containers (vector,list), but deletes all stored entries on
** destruction.
**
** Example:
**
**     {   AutoSequence <vector<Image *> > images;
**         images->push_back(new Image("hello.bmp"));
**         // ...
**     }
**
** All images allocated and stored in `images' have by now been freed.
*/
    template <class T>
    class AutoSequence : public ecl::Nocopy {
    public:
        ~AutoSequence() { delete_sequence(seq.begin(), seq.end()); }
        T *operator->() { return &seq; }
        T &operator*() { return seq; }
    private:
        T seq;
    };



    template <class Iter> inline
    Iter next(const Iter i) {
        Iter j=i;
        return ++j;
    }
    template <class Iter> inline
    Iter prev(const Iter i) {
        Iter j=i;
        return --j;
    }

    template <class For> inline
    void
    delete_sequence(For begin, For end)
    {
        while (begin != end)
            delete *begin++;
    }

    template <class For> inline void
    delete_map(For begin, For end)
    {
        while (begin != end)
        {
            delete begin->second;
            ++begin;
        }
    }

    template <class T> inline const T &
    Max(const T &a, const T &b)
    {
        return (a > b) ? a : b;
    }

    template <class T> inline const T &
    Min(const T &a, const T &b)
    {
        return (a < b) ? a : b;
    }

    template <class T> inline const T &
    Clamp (const T& a, const T& min, const T& max)
    {
        if (a < min)
            return min;
        else if (a > max)
            return max;
        else
            return a;
    }

/*
** Split a string at every occurrence of 'sep' and store the
** resulting strings using the iterator 'out'.
**
** Example:
**
**     vector<string> vs;
**     split_copy("/usr/bin/enigma", '/', back_inserter(vs));
*/
    template <class Ch, class OutIt>
    void split_copy(const std::basic_string<Ch> &str, Ch sep, OutIt out)
    {
        typename std::basic_string<Ch>::const_iterator i,j;
        i=str.begin();
        while (true) {
            j = std::find(i, str.end(), sep);
            *out = std::basic_string<Ch>(i,j);
            ++out;
            if (j==str.end())
                break;
            i=j+1;
        }
    }

    template <class Ch, class OutIt>
    size_t split_copy_n (const std::basic_string<Ch> &str, Ch sep, OutIt out, size_t n)
    {
        typename std::basic_string<Ch>::const_iterator i,j;
        i=str.begin();
        size_t cnt=0;
        for (; cnt < n; ++cnt) {
            j = std::find(i, str.end(), sep);
            *out = std::basic_string<Ch>(i,j);
            ++out;
            if (j==str.end())
                break;
            i=j+1;
        }
        return cnt;
    }

/*
** Remove white space at the beginning and end of a string.
*/
    template <class Str>
    Str trim(const Str& str)
    {
        if (str.size() == 0)
            return str;
        typename Str::size_type b = str.find_first_not_of(" \t\n\r");
        typename Str::size_type e = str.find_last_not_of(" \t\n\r");
        if (b == Str::npos)
            return "";
        return Str(str, b, e-b+1);
    }


/*
** Some helper functions for dealing with bit flags.
*/

    template <class E, class I> inline void
    set_flags (E &val, I flags)
    {
        val = static_cast<E> (val | flags);
    }

    template <class E, class I> inline void
    clear_flags (E &val, I flags)
    {
        val = static_cast<E> (val & ~flags);
    }

    template <class E, class I> inline void
    toggle_flags (E &val, I flags)
    {
        val = static_cast<E> (val ^ flags);
    }

    template <class E, class I> inline bool
    has_flags (E val, I flags)
    {
        return (static_cast<int>(val & flags) == static_cast<int>(flags));
    }

    /*
    ** Some helper functions for strings and filenames
    */

    std::string strf(const char *format, ...) __attribute__((format(printf, 1, 2)));
    std::string timeformat(int duration);

    std::string concat_paths(const std::string& path, const std::string& filename);
    
    /**
     * Split a given path into the leading directory part and the last filename
     * part. The path may use unix slash separators as well as windows backlashes.
     * Even mixed usage is allowed. Trailing path separators are skipped.
     * @param path           the path to be split
     * @param dir_part       ptr to a return string where the leading directory 
     *                       part without trailing separators will be stored. 
     *                       The string will not be set if the result is false.
     * @param filename_part  ptr to a return string where the trailing filename 
     *                       part will be stored. 
     *                       The string will not be set if the result is false.
     * @return               success of splitting the path into 2 parts. If no
     *                       path separator was found just false will be returned
     *                       without modification of the return strings.
     */
    bool split_path(const std::string& path, std::string* dir_part, std::string* filename_part);
    
    
    /**
     * Check a string against a given template that may contain wildcards of '*' and
     * '?'. A '?' in the template means 'any single character'. A '*' means '0 or more characters'.
     * @param str     string to be analysed
     * @param templ   template with wildcards
     * @return        true if string matches template, false otherwise
     */
    bool string_match(const char *str, const char *templ);
    
    /**
     * Check a string against a given template that may contain wildcards of '*' and
     * '?'. A '?' in the template means 'any single character'. A '*' means '0 or more characters'.
     * @param str     string to be analysed
     * @param templ   template with wildcards
     * @return        true if string matches template, false otherwise
     */
    bool string_match(std::string str, std::string templ);

}

#endif