r269@gandalf: fugalh | 2006-08-03 20:18:05 -0600
[ardour.git] / libs / pbd / convert.cc
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
23 #include "pbd/convert.h"
24
25 #include "i18n.h"
26
27 using std::string;
28 using std::vector;
29
30 namespace PBD {
31
32 string
33 short_version (string orig, string::size_type target_length)
34 {
35         /* this tries to create a recognizable abbreviation
36            of "orig" by removing characters until we meet
37            a certain target length.
38
39            note that we deliberately leave digits in the result
40            without modification.
41         */
42
43
44         string::size_type pos;
45
46         /* remove white-space and punctuation, starting at end */
47
48         while (orig.length() > target_length) {
49                 if ((pos = orig.find_last_of (_("\"\n\t ,<.>/?:;'[{}]~`!@#$%^&*()_-+="))) == string::npos) {
50                         break;
51                 }
52                 orig.replace (pos, 1, "");
53         }
54
55         /* remove lower-case vowels, starting at end */
56
57         while (orig.length() > target_length) {
58                 if ((pos = orig.find_last_of (_("aeiou"))) == string::npos) {
59                         break;
60                 }
61                 orig.replace (pos, 1, "");
62         }
63
64         /* remove upper-case vowels, starting at end */
65
66         while (orig.length() > target_length) {
67                 if ((pos = orig.find_last_of (_("AEIOU"))) == string::npos) {
68                         break;
69                 }
70                 orig.replace (pos, 1, "");
71         }
72
73         /* remove lower-case consonants, starting at end */
74
75         while (orig.length() > target_length) {
76                 if ((pos = orig.find_last_of (_("bcdfghjklmnpqrtvwxyz"))) == string::npos) {
77                         break;
78                 }
79                 orig.replace (pos, 1, "");
80         }
81
82         /* remove upper-case consonants, starting at end */
83
84         while (orig.length() > target_length) {
85                 if ((pos = orig.find_last_of (_("BCDFGHJKLMNPQRTVWXYZ"))) == string::npos) {
86                         break;
87                 }
88                 orig.replace (pos, 1, "");
89         }
90
91         /* whatever the length is now, use it */
92         
93         return orig;
94 }
95
96 int
97 atoi (const string& s)
98 {
99         return std::atoi (s.c_str());
100 }
101
102 double
103 atof (const string& s)
104 {
105         return std::atof (s.c_str());
106 }
107
108 vector<string>
109 internationalize (const char **array)
110 {
111         vector<string> v;
112
113         for (uint32_t i = 0; array[i]; ++i) {
114                 v.push_back (_(array[i]));
115         }
116
117         return v;
118 }
119
120 static int32_t 
121 int_from_hex (char hic, char loc) 
122 {
123         int hi;         /* hi byte */
124         int lo;         /* low byte */
125
126         hi = (int) hic;
127
128         if( ('0'<=hi) && (hi<='9') ) {
129                 hi -= '0';
130         } else if( ('a'<= hi) && (hi<= 'f') ) {
131                 hi -= ('a'-10);
132         } else if( ('A'<=hi) && (hi<='F') ) {
133                 hi -= ('A'-10);
134         }
135         
136         lo = (int) loc;
137         
138         if( ('0'<=lo) && (lo<='9') ) {
139                 lo -= '0';
140         } else if( ('a'<=lo) && (lo<='f') ) {
141                 lo -= ('a'-10);
142         } else if( ('A'<=lo) && (lo<='F') ) {
143                 lo -= ('A'-10);
144         }
145
146         return lo + (16 * hi);
147 }
148
149 void
150 url_decode (string& url)
151 {
152         string::iterator last;
153         string::iterator next;
154
155         for (string::iterator i = url.begin(); i != url.end(); ++i) {
156                 if ((*i) == '+') {
157                         *i = ' ';
158                 }
159         }
160
161         if (url.length() <= 3) {
162                 return;
163         }
164
165         last = url.end();
166
167         --last; /* points at last char */
168         --last; /* points at last char - 1 */
169
170         for (string::iterator i = url.begin(); i != last; ) {
171
172                 if (*i == '%') {
173
174                         next = i;
175
176                         url.erase (i);
177                         
178                         i = next;
179                         ++next;
180                         
181                         if (isxdigit (*i) && isxdigit (*next)) {
182                                 /* replace first digit with char */
183                                 *i = int_from_hex (*i,*next);
184                                 ++i; /* points at 2nd of 2 digits */
185                                 url.erase (i);
186                         }
187                 } else {
188                         ++i;
189                 }
190         }
191 }
192
193 string
194 length2string (const int32_t frames, const float sample_rate)
195 {
196     int secs = (int) (frames / sample_rate);
197     int hrs =  secs / 3600;
198     secs -= (hrs * 3600);
199     int mins = secs / 60;
200     secs -= (mins * 60);
201
202     int total_secs = (hrs * 3600) + (mins * 60) + secs;
203     int frames_remaining = (int) floor (frames - (total_secs * sample_rate));
204     float fractional_secs = (float) frames_remaining / sample_rate;
205
206     char duration_str[32];
207     sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs);
208
209     return duration_str;
210 }
211
212 } // namespace PBD