~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/pbd/convert.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2006 Paul Davis 
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
*/
 
19
 
 
20
#include <cmath>
 
21
#include <stdint.h>
 
22
#include <stdlib.h>
 
23
#include <cstdio>
 
24
#include <ctype.h>
 
25
#include <cstring>
 
26
#ifndef __STDC_FORMAT_MACROS
 
27
#define __STDC_FORMAT_MACROS
 
28
#endif
 
29
#include <inttypes.h>
 
30
 
 
31
#include <glib.h>
 
32
 
 
33
#include "pbd/convert.h"
 
34
 
 
35
#include "i18n.h"
 
36
 
 
37
using std::string;
 
38
using std::vector;
 
39
using Glib::ustring;
 
40
 
 
41
namespace PBD {
 
42
 
 
43
string
 
44
capitalize (const string& str)
 
45
{
 
46
        string ret = str;
 
47
        if (!str.empty()) {
 
48
                /* XXX not unicode safe */
 
49
                ret[0] = toupper (str[0]);
 
50
        }
 
51
        return ret;
 
52
}
 
53
 
 
54
string
 
55
short_version (string orig, string::size_type target_length)
 
56
{
 
57
        /* this tries to create a recognizable abbreviation
 
58
           of "orig" by removing characters until we meet
 
59
           a certain target length.
 
60
 
 
61
           note that we deliberately leave digits in the result
 
62
           without modification.
 
63
        */
 
64
 
 
65
 
 
66
        string::size_type pos;
 
67
 
 
68
        /* remove white-space and punctuation, starting at end */
 
69
 
 
70
        while (orig.length() > target_length) {
 
71
                if ((pos = orig.find_last_of (_("\"\n\t ,<.>/?:;'[{}]~`!@#$%^&*()_-+="))) == string::npos) {
 
72
                        break;
 
73
                }
 
74
                orig.replace (pos, 1, "");
 
75
        }
 
76
 
 
77
        /* remove lower-case vowels, starting at end */
 
78
 
 
79
        while (orig.length() > target_length) {
 
80
                if ((pos = orig.find_last_of (_("aeiou"))) == string::npos) {
 
81
                        break;
 
82
                }
 
83
                orig.replace (pos, 1, "");
 
84
        }
 
85
 
 
86
        /* remove upper-case vowels, starting at end */
 
87
 
 
88
        while (orig.length() > target_length) {
 
89
                if ((pos = orig.find_last_of (_("AEIOU"))) == string::npos) {
 
90
                        break;
 
91
                }
 
92
                orig.replace (pos, 1, "");
 
93
        }
 
94
 
 
95
        /* remove lower-case consonants, starting at end */
 
96
 
 
97
        while (orig.length() > target_length) {
 
98
                if ((pos = orig.find_last_of (_("bcdfghjklmnpqrtvwxyz"))) == string::npos) {
 
99
                        break;
 
100
                }
 
101
                orig.replace (pos, 1, "");
 
102
        }
 
103
 
 
104
        /* remove upper-case consonants, starting at end */
 
105
 
 
106
        while (orig.length() > target_length) {
 
107
                if ((pos = orig.find_last_of (_("BCDFGHJKLMNPQRTVWXYZ"))) == string::npos) {
 
108
                        break;
 
109
                }
 
110
                orig.replace (pos, 1, "");
 
111
        }
 
112
 
 
113
        /* whatever the length is now, use it */
 
114
        
 
115
        return orig;
 
116
}
 
117
 
 
118
int
 
119
atoi (const string& s)
 
120
{
 
121
        return ::atoi (s.c_str());
 
122
}
 
123
 
 
124
int32_t
 
125
atol (const string& s)
 
126
{
 
127
        return (int32_t) ::atol (s.c_str());
 
128
}
 
129
 
 
130
int64_t
 
131
atoll (const string& s)
 
132
{
 
133
        return (int64_t) ::atoll (s.c_str());
 
134
}
 
135
 
 
136
double
 
137
atof (const string& s)
 
138
{
 
139
        return ::atof (s.c_str());
 
140
}
 
141
 
 
142
vector<string>
 
143
internationalize (const char *package_name, const char **array)
 
144
{
 
145
        vector<string> v;
 
146
 
 
147
        for (uint32_t i = 0; array[i]; ++i) {
 
148
                v.push_back (dgettext(package_name, array[i]));
 
149
        }
 
150
 
 
151
        return v;
 
152
}
 
153
 
 
154
static int32_t 
 
155
int_from_hex (char hic, char loc) 
 
156
{
 
157
        int hi;         /* hi byte */
 
158
        int lo;         /* low byte */
 
159
 
 
160
        hi = (int) hic;
 
161
 
 
162
        if( ('0'<=hi) && (hi<='9') ) {
 
163
                hi -= '0';
 
164
        } else if( ('a'<= hi) && (hi<= 'f') ) {
 
165
                hi -= ('a'-10);
 
166
        } else if( ('A'<=hi) && (hi<='F') ) {
 
167
                hi -= ('A'-10);
 
168
        }
 
169
        
 
170
        lo = (int) loc;
 
171
        
 
172
        if( ('0'<=lo) && (lo<='9') ) {
 
173
                lo -= '0';
 
174
        } else if( ('a'<=lo) && (lo<='f') ) {
 
175
                lo -= ('a'-10);
 
176
        } else if( ('A'<=lo) && (lo<='F') ) {
 
177
                lo -= ('A'-10);
 
178
        }
 
179
 
 
180
        return lo + (16 * hi);
 
181
}
 
182
 
 
183
string
 
184
url_decode (string const & url)
 
185
{
 
186
        string decoded;
 
187
 
 
188
        for (string::size_type i = 0; i < url.length(); ++i) {
 
189
                if (url[i] == '+') {
 
190
                        decoded += ' ';
 
191
                } else if (url[i] == '%' && i <= url.length() - 3) {
 
192
                        decoded += char (int_from_hex (url[i + 1], url[i + 2]));
 
193
                        i += 2;
 
194
                } else {
 
195
                        decoded += url[i];
 
196
                }
 
197
        }
 
198
 
 
199
        return decoded;
 
200
}
 
201
 
 
202
#if 0
 
203
string
 
204
length2string (const int32_t frames, const float sample_rate)
 
205
{
 
206
    int32_t secs = (int32_t) (frames / sample_rate);
 
207
    int32_t hrs =  secs / 3600;
 
208
    secs -= (hrs * 3600);
 
209
    int32_t mins = secs / 60;
 
210
    secs -= (mins * 60);
 
211
 
 
212
    int32_t total_secs = (hrs * 3600) + (mins * 60) + secs;
 
213
    int32_t frames_remaining = (int) floor (frames - (total_secs * sample_rate));
 
214
    float fractional_secs = (float) frames_remaining / sample_rate;
 
215
 
 
216
    char duration_str[32];
 
217
    sprintf (duration_str, "%02" PRIi32 ":%02" PRIi32 ":%05.2f", hrs, mins, (float) secs + fractional_secs);
 
218
 
 
219
    return duration_str;
 
220
}
 
221
#endif
 
222
 
 
223
string
 
224
length2string (const int64_t frames, const double sample_rate)
 
225
{
 
226
        int64_t secs = (int64_t) floor (frames / sample_rate);
 
227
        int64_t hrs =  secs / 3600LL;
 
228
        secs -= (hrs * 3600LL);
 
229
        int64_t mins = secs / 60LL;
 
230
        secs -= (mins * 60LL);
 
231
        
 
232
        int64_t total_secs = (hrs * 3600LL) + (mins * 60LL) + secs;
 
233
        int64_t frames_remaining = (int64_t) floor (frames - (total_secs * sample_rate));
 
234
        float fractional_secs = (float) frames_remaining / sample_rate;
 
235
        
 
236
        char duration_str[64];
 
237
        sprintf (duration_str, "%02" PRIi64 ":%02" PRIi64 ":%05.2f", hrs, mins, (float) secs + fractional_secs);
 
238
        
 
239
        return duration_str;
 
240
}
 
241
 
 
242
static bool 
 
243
chars_equal_ignore_case(char x, char y)
 
244
{
 
245
        /* app should have called setlocale() if its wants this comparison to be
 
246
           locale sensitive.
 
247
        */
 
248
        return toupper (x) == toupper (y);
 
249
}
 
250
 
 
251
bool 
 
252
strings_equal_ignore_case (const string& a, const string& b)
 
253
{
 
254
        if (a.length() == b.length()) {
 
255
                return std::equal (a.begin(), a.end(), b.begin(), chars_equal_ignore_case);
 
256
        }
 
257
        return false;
 
258
}
 
259
 
 
260
bool
 
261
string_is_affirmative (const std::string& str)
 
262
{
 
263
        /* to be used only with XML data - not intended to handle user input */
 
264
 
 
265
        if (str.empty ()) {
 
266
                return false;
 
267
        }
 
268
 
 
269
        /* the use of g_ascii_strncasecmp() is solely to get around issues with
 
270
         * charsets posed by trying to use C++ for the same
 
271
         * comparison. switching a std::string to its lower- or upper-case
 
272
         * version has several issues, but handled by default
 
273
         * in the way we desire when doing it in C.
 
274
         */
 
275
 
 
276
        return str == "1" || str == "y" || str == "Y" || (!g_ascii_strncasecmp(str.c_str(), "yes", str.length())) ||
 
277
                (!g_ascii_strncasecmp(str.c_str(), "true", str.length()));
 
278
}
 
279
 
 
280
/** A wrapper for dgettext that takes a msgid of the form Context|Text.
 
281
 *  If Context|Text is translated, the translation is returned, otherwise
 
282
 *  just Text is returned.  Useful for getting translations of words or phrases
 
283
 *  that have different meanings in different contexts.
 
284
 */
 
285
const char *
 
286
sgettext (const char* domain_name, const char* msgid)
 
287
{
 
288
        const char * msgval = dgettext (domain_name, msgid);
 
289
        if (msgval == msgid) {
 
290
                const char * p = strrchr (msgid, '|');
 
291
                if (p) {
 
292
                        msgval = p + 1;
 
293
                }
 
294
        }
 
295
        return msgval;
 
296
}
 
297
 
 
298
} // namespace PBD