X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fconvert.cc;h=1787d3b70d9f33f5b95f945bcfd7f14aae039e96;hb=2ba2a50decb4b2f8b6b688dea495a2898124cc4f;hp=60d39c91e2d675eff6825a3fd9931b9b2cf35c92;hpb=22c20ab6f215c0ab24702a479aa6821c25a7d058;p=ardour.git diff --git a/libs/pbd/convert.cc b/libs/pbd/convert.cc index 60d39c91e2..1787d3b70d 100644 --- a/libs/pbd/convert.cc +++ b/libs/pbd/convert.cc @@ -19,6 +19,16 @@ #include #include +#include +#include +#include +#include +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include + +#include #include "pbd/convert.h" @@ -26,9 +36,21 @@ using std::string; using std::vector; +using Glib::ustring; namespace PBD { +string +capitalize (const string& str) +{ + string ret = str; + if (!str.empty()) { + /* XXX not unicode safe */ + ret[0] = toupper (str[0]); + } + return ret; +} + string short_version (string orig, string::size_type target_length) { @@ -96,22 +118,34 @@ short_version (string orig, string::size_type target_length) int atoi (const string& s) { - return std::atoi (s.c_str()); + return ::atoi (s.c_str()); +} + +int32_t +atol (const string& s) +{ + return (int32_t) ::atol (s.c_str()); +} + +int64_t +atoll (const string& s) +{ + return (int64_t) ::atoll (s.c_str()); } double atof (const string& s) { - return std::atof (s.c_str()); + return ::atof (s.c_str()); } vector -internationalize (const char **array) +internationalize (const char *package_name, const char **array) { vector v; for (uint32_t i = 0; array[i]; ++i) { - v.push_back (_(array[i])); + v.push_back (dgettext(package_name, array[i])); } return v; @@ -146,67 +180,119 @@ int_from_hex (char hic, char loc) return lo + (16 * hi); } -void -url_decode (string& url) +string +url_decode (string const & url) { - string::iterator last; - string::iterator next; - - for (string::iterator i = url.begin(); i != url.end(); ++i) { - if ((*i) == '+') { - *i = ' '; - } - } - - if (url.length() <= 3) { - return; - } - - last = url.end(); - - --last; /* points at last char */ - --last; /* points at last char - 1 */ - - for (string::iterator i = url.begin(); i != last; ) { - - if (*i == '%') { - - next = i; - - url.erase (i); - - i = next; - ++next; - - if (isxdigit (*i) && isxdigit (*next)) { - /* replace first digit with char */ - *i = int_from_hex (*i,*next); - ++i; /* points at 2nd of 2 digits */ - url.erase (i); - } + string decoded; + + for (string::size_type i = 0; i < url.length(); ++i) { + if (url[i] == '+') { + decoded += ' '; + } else if (url[i] == '%' && i <= url.length() - 3) { + decoded += char (int_from_hex (url[i + 1], url[i + 2])); + i += 2; } else { - ++i; + decoded += url[i]; } } + + return decoded; } +#if 0 string length2string (const int32_t frames, const float sample_rate) { - int secs = (int) (frames / sample_rate); - int hrs = secs / 3600; + int32_t secs = (int32_t) (frames / sample_rate); + int32_t hrs = secs / 3600; secs -= (hrs * 3600); - int mins = secs / 60; + int32_t mins = secs / 60; secs -= (mins * 60); - int total_secs = (hrs * 3600) + (mins * 60) + secs; - int frames_remaining = (int) floor (frames - (total_secs * sample_rate)); + int32_t total_secs = (hrs * 3600) + (mins * 60) + secs; + int32_t frames_remaining = (int) floor (frames - (total_secs * sample_rate)); float fractional_secs = (float) frames_remaining / sample_rate; char duration_str[32]; - sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs); + sprintf (duration_str, "%02" PRIi32 ":%02" PRIi32 ":%05.2f", hrs, mins, (float) secs + fractional_secs); return duration_str; } +#endif + +string +length2string (const int64_t frames, const double sample_rate) +{ + int64_t secs = (int64_t) floor (frames / sample_rate); + int64_t hrs = secs / 3600LL; + secs -= (hrs * 3600LL); + int64_t mins = secs / 60LL; + secs -= (mins * 60LL); + + int64_t total_secs = (hrs * 3600LL) + (mins * 60LL) + secs; + int64_t frames_remaining = (int64_t) floor (frames - (total_secs * sample_rate)); + float fractional_secs = (float) frames_remaining / sample_rate; + + char duration_str[64]; + sprintf (duration_str, "%02" PRIi64 ":%02" PRIi64 ":%05.2f", hrs, mins, (float) secs + fractional_secs); + + return duration_str; +} + +static bool +chars_equal_ignore_case(char x, char y) +{ + /* app should have called setlocale() if its wants this comparison to be + locale sensitive. + */ + return toupper (x) == toupper (y); +} + +bool +strings_equal_ignore_case (const string& a, const string& b) +{ + if (a.length() == b.length()) { + return std::equal (a.begin(), a.end(), b.begin(), chars_equal_ignore_case); + } + return false; +} + +bool +string_is_affirmative (const std::string& str) +{ + /* to be used only with XML data - not intended to handle user input */ + + if (str.empty ()) { + return false; + } + + /* the use of g_ascii_strncasecmp() is solely to get around issues with + * charsets posed by trying to use C++ for the same + * comparison. switching a std::string to its lower- or upper-case + * version has several issues, but handled by default + * in the way we desire when doing it in C. + */ + + return str == "1" || str == "y" || str == "Y" || (!g_ascii_strncasecmp(str.c_str(), "yes", str.length())) || + (!g_ascii_strncasecmp(str.c_str(), "true", str.length())); +} + +/** A wrapper for dgettext that takes a msgid of the form Context|Text. + * If Context|Text is translated, the translation is returned, otherwise + * just Text is returned. Useful for getting translations of words or phrases + * that have different meanings in different contexts. + */ +const char * +sgettext (const char* domain_name, const char* msgid) +{ + const char * msgval = dgettext (domain_name, msgid); + if (msgval == msgid) { + const char * p = strrchr (msgid, '|'); + if (p) { + msgval = p + 1; + } + } + return msgval; +} } // namespace PBD