X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fpbd%2Fconvert.cc;h=660891076d1c908390bb9c4b0e07293ff48d7447;hb=a7df009de73ad38026ff97d9aeafb8e2aa22e627;hp=832c54acd84c186eb1cc21b55c01b87ee51cb2f3;hpb=ef6b25432d9c46d71b08c0f7d5f2686df428c4e8;p=ardour.git diff --git a/libs/pbd/convert.cc b/libs/pbd/convert.cc index 832c54acd8..660891076d 100644 --- a/libs/pbd/convert.cc +++ b/libs/pbd/convert.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2006 Paul Davis + Copyright (C) 2006 Paul Davis 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 @@ -18,21 +18,60 @@ */ #include +#include +#include + #include +#include +#include +#include +#include #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS #endif #include +#include + #include "pbd/convert.h" #include "i18n.h" 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 +downcase (const string& str) +{ + string copy (str); + std::transform (copy.begin(), copy.end(), copy.begin(), ::tolower); + return copy; +} + +const char* +downcase (const char* str) +{ + char *copy = strdup (str); + for (char* p = copy; *p; ++p) { + *p = tolower (*p); + } + return copy; +} + string short_version (string orig, string::size_type target_length) { @@ -93,20 +132,32 @@ short_version (string orig, string::size_type target_length) } /* whatever the length is now, use it */ - + return orig; } 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 @@ -121,8 +172,8 @@ internationalize (const char *package_name, const char **array) return v; } -static int32_t -int_from_hex (char hic, char loc) +static int32_t +int_from_hex (char hic, char loc) { int hi; /* hi byte */ int lo; /* low byte */ @@ -136,9 +187,9 @@ int_from_hex (char hic, char loc) } else if( ('A'<=hi) && (hi<='F') ) { hi -= ('A'-10); } - + lo = (int) loc; - + if( ('0'<=lo) && (lo<='9') ) { lo -= '0'; } else if( ('a'<=lo) && (lo<='f') ) { @@ -150,48 +201,23 @@ 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 @@ -223,15 +249,71 @@ length2string (const int64_t frames, const double sample_rate) 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