2 Copyright (C) 2006 Paul Davis
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.
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.
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.
25 #ifndef __STDC_FORMAT_MACROS
26 #define __STDC_FORMAT_MACROS
30 #include "pbd/convert.h"
41 capitalize (const string
& str
)
45 /* XXX not unicode safe */
46 ret
[0] = toupper (str
[0]);
52 short_version (string orig
, string::size_type target_length
)
54 /* this tries to create a recognizable abbreviation
55 of "orig" by removing characters until we meet
56 a certain target length.
58 note that we deliberately leave digits in the result
63 string::size_type pos
;
65 /* remove white-space and punctuation, starting at end */
67 while (orig
.length() > target_length
) {
68 if ((pos
= orig
.find_last_of (_("\"\n\t ,<.>/?:;'[{}]~`!@#$%^&*()_-+="))) == string::npos
) {
71 orig
.replace (pos
, 1, "");
74 /* remove lower-case vowels, starting at end */
76 while (orig
.length() > target_length
) {
77 if ((pos
= orig
.find_last_of (_("aeiou"))) == string::npos
) {
80 orig
.replace (pos
, 1, "");
83 /* remove upper-case vowels, starting at end */
85 while (orig
.length() > target_length
) {
86 if ((pos
= orig
.find_last_of (_("AEIOU"))) == string::npos
) {
89 orig
.replace (pos
, 1, "");
92 /* remove lower-case consonants, starting at end */
94 while (orig
.length() > target_length
) {
95 if ((pos
= orig
.find_last_of (_("bcdfghjklmnpqrtvwxyz"))) == string::npos
) {
98 orig
.replace (pos
, 1, "");
101 /* remove upper-case consonants, starting at end */
103 while (orig
.length() > target_length
) {
104 if ((pos
= orig
.find_last_of (_("BCDFGHJKLMNPQRTVWXYZ"))) == string::npos
) {
107 orig
.replace (pos
, 1, "");
110 /* whatever the length is now, use it */
116 atoi (const string
& s
)
118 return ::atoi (s
.c_str());
122 atol (const string
& s
)
124 return (int32_t) ::atol (s
.c_str());
128 atoll (const string
& s
)
130 return (int64_t) ::atoll (s
.c_str());
134 atof (const string
& s
)
136 return ::atof (s
.c_str());
140 internationalize (const char *package_name
, const char **array
)
144 for (uint32_t i
= 0; array
[i
]; ++i
) {
145 v
.push_back (dgettext(package_name
, array
[i
]));
152 int_from_hex (char hic
, char loc
)
154 int hi
; /* hi byte */
155 int lo
; /* low byte */
159 if( ('0'<=hi
) && (hi
<='9') ) {
161 } else if( ('a'<= hi
) && (hi
<= 'f') ) {
163 } else if( ('A'<=hi
) && (hi
<='F') ) {
169 if( ('0'<=lo
) && (lo
<='9') ) {
171 } else if( ('a'<=lo
) && (lo
<='f') ) {
173 } else if( ('A'<=lo
) && (lo
<='F') ) {
177 return lo
+ (16 * hi
);
181 url_decode (string
& url
)
183 string::iterator last
;
184 string::iterator next
;
186 for (string::iterator i
= url
.begin(); i
!= url
.end(); ++i
) {
192 if (url
.length() <= 3) {
198 --last
; /* points at last char */
199 --last
; /* points at last char - 1 */
201 for (string::iterator i
= url
.begin(); i
!= last
; ) {
212 if (isxdigit (*i
) && isxdigit (*next
)) {
213 /* replace first digit with char */
214 *i
= int_from_hex (*i
,*next
);
215 ++i
; /* points at 2nd of 2 digits */
225 url_decode (ustring
& url
)
227 ustring::iterator last
;
228 ustring::iterator next
;
230 for (ustring::iterator i
= url
.begin(); i
!= url
.end(); ++i
) {
234 url
.replace (i
, next
, 1, ' ');
238 if (url
.length() <= 3) {
244 --last
; /* points at last char */
245 --last
; /* points at last char - 1 */
247 for (ustring::iterator i
= url
.begin(); i
!= last
; ) {
258 if (isxdigit (*i
) && isxdigit (*next
)) {
259 /* replace first digit with char */
260 url
.replace (i
, next
, 1, (gunichar
) int_from_hex (*i
,*next
));
261 ++i
; /* points at 2nd of 2 digits */
272 length2string (const int32_t frames
, const float sample_rate
)
274 int32_t secs
= (int32_t) (frames
/ sample_rate
);
275 int32_t hrs
= secs
/ 3600;
276 secs
-= (hrs
* 3600);
277 int32_t mins
= secs
/ 60;
280 int32_t total_secs
= (hrs
* 3600) + (mins
* 60) + secs
;
281 int32_t frames_remaining
= (int) floor (frames
- (total_secs
* sample_rate
));
282 float fractional_secs
= (float) frames_remaining
/ sample_rate
;
284 char duration_str
[32];
285 sprintf (duration_str
, "%02" PRIi32
":%02" PRIi32
":%05.2f", hrs
, mins
, (float) secs
+ fractional_secs
);
292 length2string (const int64_t frames
, const double sample_rate
)
294 int64_t secs
= (int64_t) floor (frames
/ sample_rate
);
295 int64_t hrs
= secs
/ 3600LL;
296 secs
-= (hrs
* 3600LL);
297 int64_t mins
= secs
/ 60LL;
298 secs
-= (mins
* 60LL);
300 int64_t total_secs
= (hrs
* 3600LL) + (mins
* 60LL) + secs
;
301 int64_t frames_remaining
= (int64_t) floor (frames
- (total_secs
* sample_rate
));
302 float fractional_secs
= (float) frames_remaining
/ sample_rate
;
304 char duration_str
[64];
305 sprintf (duration_str
, "%02" PRIi64
":%02" PRIi64
":%05.2f", hrs
, mins
, (float) secs
+ fractional_secs
);
311 chars_equal_ignore_case(char x
, char y
)
313 /* app should have called setlocale() if its wants this comparison to be
316 return toupper (x
) == toupper (y
);
320 strings_equal_ignore_case (const string
& a
, const string
& b
)
322 if (a
.length() == b
.length()) {
323 return std::equal (a
.begin(), a
.end(), b
.begin(), chars_equal_ignore_case
);