/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-7 by Raw Material Software ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License, as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JUCE; if not, visit www.gnu.org/licenses or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------ If you'd like to release a closed-source product which uses JUCE, commercial licenses are also available: visit www.rawmaterialsoftware.com/juce for more information. ============================================================================== */ #ifdef _MSC_VER #pragma warning (disable: 4514 4996) #pragma warning (push) #endif #include "../basics/juce_StandardHeader.h" #include #include #include #ifdef _MSC_VER #pragma warning (pop) #endif BEGIN_JUCE_NAMESPACE #include "juce_CharacterFunctions.h" #include "juce_String.h" //============================================================================== int CharacterFunctions::length (const char* const s) throw() { return (int) strlen (s); } int CharacterFunctions::length (const juce_wchar* const s) throw() { #if MACOS_10_2_OR_EARLIER int n = 0; while (s[n] != 0) ++n; return n; #else return (int) wcslen (s); #endif } void CharacterFunctions::copy (char* dest, const char* src, const int maxChars) throw() { strncpy (dest, src, maxChars); } void CharacterFunctions::copy (juce_wchar* dest, const juce_wchar* src, int maxChars) throw() { #if MACOS_10_2_OR_EARLIER while (--maxChars >= 0 && *src != 0) *dest++ = *src++; *dest = 0; #else wcsncpy (dest, src, maxChars); #endif } void CharacterFunctions::copy (juce_wchar* dest, const char* src, const int maxChars) throw() { mbstowcs (dest, src, maxChars); } void CharacterFunctions::copy (char* dest, const juce_wchar* src, const int maxChars) throw() { wcstombs (dest, src, maxChars); } int CharacterFunctions::bytesRequiredForCopy (const juce_wchar* src) throw() { return (int) wcstombs (0, src, 0); } void CharacterFunctions::append (char* dest, const char* src) throw() { strcat (dest, src); } void CharacterFunctions::append (juce_wchar* dest, const juce_wchar* src) throw() { #if MACOS_10_2_OR_EARLIER while (*dest != 0) ++dest; while (*src != 0) *dest++ = *src++; *dest = 0; #else wcscat (dest, src); #endif } int CharacterFunctions::compare (const char* const s1, const char* const s2) throw() { return strcmp (s1, s2); } int CharacterFunctions::compare (const juce_wchar* s1, const juce_wchar* s2) throw() { jassert (s1 != 0 && s2 != 0); #if MACOS_10_2_OR_EARLIER for (;;) { if (*s1 != *s2) { const int diff = *s1 - *s2; if (diff != 0) return diff < 0 ? -1 : 1; } else if (*s1 == 0) break; ++s1; ++s2; } return 0; #else return wcscmp (s1, s2); #endif } int CharacterFunctions::compare (const char* const s1, const char* const s2, const int maxChars) throw() { jassert (s1 != 0 && s2 != 0); return strncmp (s1, s2, maxChars); } int CharacterFunctions::compare (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw() { jassert (s1 != 0 && s2 != 0); #if MACOS_10_2_OR_EARLIER while (--maxChars >= 0) { if (*s1 != *s2) return (*s1 < *s2) ? -1 : 1; else if (*s1 == 0) break; ++s1; ++s2; } return 0; #else return wcsncmp (s1, s2, maxChars); #endif } int CharacterFunctions::compareIgnoreCase (const char* const s1, const char* const s2) throw() { jassert (s1 != 0 && s2 != 0); #if JUCE_WIN32 return stricmp (s1, s2); #else return strcasecmp (s1, s2); #endif } int CharacterFunctions::compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2) throw() { jassert (s1 != 0 && s2 != 0); #if JUCE_WIN32 return _wcsicmp (s1, s2); #else for (;;) { if (*s1 != *s2) { const int diff = toUpperCase (*s1) - toUpperCase (*s2); if (diff != 0) return diff < 0 ? -1 : 1; } else if (*s1 == 0) break; ++s1; ++s2; } return 0; #endif } int CharacterFunctions::compareIgnoreCase (const char* const s1, const char* const s2, const int maxChars) throw() { jassert (s1 != 0 && s2 != 0); #if JUCE_WIN32 return strnicmp (s1, s2, maxChars); #else return strncasecmp (s1, s2, maxChars); #endif } int CharacterFunctions::compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw() { jassert (s1 != 0 && s2 != 0); #if JUCE_WIN32 return _wcsnicmp (s1, s2, maxChars); #else while (--maxChars >= 0) { if (*s1 != *s2) { const int diff = toUpperCase (*s1) - toUpperCase (*s2); if (diff != 0) return diff < 0 ? -1 : 1; } else if (*s1 == 0) break; ++s1; ++s2; } return 0; #endif } const char* CharacterFunctions::find (const char* const haystack, const char* const needle) throw() { return strstr (haystack, needle); } const juce_wchar* CharacterFunctions::find (const juce_wchar* haystack, const juce_wchar* const needle) throw() { #if MACOS_10_2_OR_EARLIER while (*haystack != 0) { const juce_wchar* s1 = haystack; const juce_wchar* s2 = needle; for (;;) { if (*s2 == 0) return haystack; if (*s1 != *s2 || *s2 == 0) break; ++s1; ++s2; } ++haystack; } return 0; #else return wcsstr (haystack, needle); #endif } int CharacterFunctions::indexOfChar (const char* const haystack, const char needle, const bool ignoreCase) throw() { if (haystack != 0) { int i = 0; if (ignoreCase) { const char n1 = toLowerCase (needle); const char n2 = toUpperCase (needle); if (n1 != n2) // if the char is the same in upper/lower case, fall through to the normal search { while (haystack[i] != 0) { if (haystack[i] == n1 || haystack[i] == n2) return i; ++i; } return -1; } jassert (n1 == needle); } while (haystack[i] != 0) { if (haystack[i] == needle) return i; ++i; } } return -1; } int CharacterFunctions::indexOfChar (const juce_wchar* const haystack, const juce_wchar needle, const bool ignoreCase) throw() { if (haystack != 0) { int i = 0; if (ignoreCase) { const juce_wchar n1 = toLowerCase (needle); const juce_wchar n2 = toUpperCase (needle); if (n1 != n2) // if the char is the same in upper/lower case, fall through to the normal search { while (haystack[i] != 0) { if (haystack[i] == n1 || haystack[i] == n2) return i; ++i; } return -1; } jassert (n1 == needle); } while (haystack[i] != 0) { if (haystack[i] == needle) return i; ++i; } } return -1; } int CharacterFunctions::indexOfCharFast (const char* const haystack, const char needle) throw() { jassert (haystack != 0); int i = 0; while (haystack[i] != 0) { if (haystack[i] == needle) return i; ++i; } return -1; } int CharacterFunctions::indexOfCharFast (const juce_wchar* const haystack, const juce_wchar needle) throw() { jassert (haystack != 0); int i = 0; while (haystack[i] != 0) { if (haystack[i] == needle) return i; ++i; } return -1; } int CharacterFunctions::getIntialSectionContainingOnly (const char* const text, const char* const allowedChars) throw() { return allowedChars == 0 ? 0 : (int) strspn (text, allowedChars); } int CharacterFunctions::getIntialSectionContainingOnly (const juce_wchar* const text, const juce_wchar* const allowedChars) throw() { if (allowedChars == 0) return 0; int i = 0; for (;;) { if (indexOfCharFast (allowedChars, text[i]) < 0) break; ++i; } return i; } int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* const format, const struct tm* const tm) throw() { return (int) strftime (dest, maxChars, format, tm); } int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() { #if MACOS_10_2_OR_EARLIER const String formatTemp (format); size_t num = strftime ((char*) dest, maxChars, (const char*) formatTemp, tm); String temp ((char*) dest); temp.copyToBuffer (dest, num); dest [num] = 0; return (int) num; #else return (int) wcsftime (dest, maxChars, format, tm); #endif } int CharacterFunctions::getIntValue (const char* const s) throw() { return atoi (s); } int CharacterFunctions::getIntValue (const juce_wchar* s) throw() { #if JUCE_WIN32 return _wtoi (s); #else int v = 0; while (isWhitespace (*s)) ++s; const bool isNeg = *s == T('-'); if (isNeg) ++s; for (;;) { const wchar_t c = *s++; if (c >= T('0') && c <= T('9')) v = v * 10 + (int) (c - T('0')); else break; } return isNeg ? -v : v; #endif } int64 CharacterFunctions::getInt64Value (const char* s) throw() { #if JUCE_LINUX return atoll (s); #elif defined (JUCE_WIN32) return _atoi64 (s); #else int64 v = 0; while (isWhitespace (*s)) ++s; const bool isNeg = *s == T('-'); if (isNeg) ++s; for (;;) { const char c = *s++; if (c >= '0' && c <= '9') v = v * 10 + (int64) (c - '0'); else break; } return isNeg ? -v : v; #endif } int64 CharacterFunctions::getInt64Value (const juce_wchar* s) throw() { #if JUCE_WIN32 return _wtoi64 (s); #else int64 v = 0; while (isWhitespace (*s)) ++s; const bool isNeg = *s == T('-'); if (isNeg) ++s; for (;;) { const juce_wchar c = *s++; if (c >= T('0') && c <= T('9')) v = v * 10 + (int64) (c - T('0')); else break; } return isNeg ? -v : v; #endif } double CharacterFunctions::getDoubleValue (const char* const s) throw() { return atof (s); } double CharacterFunctions::getDoubleValue (const juce_wchar* const s) throw() { #if MACOS_10_2_OR_EARLIER String temp (s); return atof ((const char*) temp); #else wchar_t* endChar; return wcstod (s, &endChar); #endif } //============================================================================== char CharacterFunctions::toUpperCase (const char character) throw() { return (char) toupper (character); } juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return toupper ((char) character); #else return towupper (character); #endif } void CharacterFunctions::toUpperCase (char* s) throw() { #if JUCE_WIN32 strupr (s); #else while (*s != 0) { *s = toUpperCase (*s); ++s; } #endif } void CharacterFunctions::toUpperCase (juce_wchar* s) throw() { #if JUCE_WIN32 _wcsupr (s); #else while (*s != 0) { *s = toUpperCase (*s); ++s; } #endif } bool CharacterFunctions::isUpperCase (const char character) throw() { return isupper (character) != 0; } bool CharacterFunctions::isUpperCase (const juce_wchar character) throw() { #if JUCE_WIN32 return iswupper (character) != 0; #else return toLowerCase (character) != character; #endif } //============================================================================== char CharacterFunctions::toLowerCase (const char character) throw() { return (char) tolower (character); } juce_wchar CharacterFunctions::toLowerCase (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return tolower ((char) character); #else return towlower (character); #endif } void CharacterFunctions::toLowerCase (char* s) throw() { #if JUCE_WIN32 strlwr (s); #else while (*s != 0) { *s = toLowerCase (*s); ++s; } #endif } void CharacterFunctions::toLowerCase (juce_wchar* s) throw() { #if JUCE_WIN32 _wcslwr (s); #else while (*s != 0) { *s = toLowerCase (*s); ++s; } #endif } bool CharacterFunctions::isLowerCase (const char character) throw() { return islower (character) != 0; } bool CharacterFunctions::isLowerCase (const juce_wchar character) throw() { #if JUCE_WIN32 return iswlower (character) != 0; #else return toUpperCase (character) != character; #endif } //============================================================================== bool CharacterFunctions::isWhitespace (const char character) throw() { return character == T(' ') || (character <= 13 && character >= 9); } bool CharacterFunctions::isWhitespace (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return isWhitespace ((char) character); #else return iswspace (character) != 0; #endif } bool CharacterFunctions::isDigit (const char character) throw() { return (character >= '0' && character <= '9'); } bool CharacterFunctions::isDigit (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return isdigit ((char) character) != 0; #else return iswdigit (character) != 0; #endif } bool CharacterFunctions::isLetter (const char character) throw() { return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z'); } bool CharacterFunctions::isLetter (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return isLetter ((char) character); #else return iswalpha (character) != 0; #endif } bool CharacterFunctions::isLetterOrDigit (const char character) throw() { return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9'); } bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw() { #if MACOS_10_2_OR_EARLIER return isLetterOrDigit ((char) character); #else return iswalnum (character) != 0; #endif } int CharacterFunctions::getHexDigitValue (const tchar digit) throw() { if (digit >= T('0') && digit <= T('9')) return digit - T('0'); else if (digit >= T('a') && digit <= T('f')) return digit - (T('a') - 10); else if (digit >= T('A') && digit <= T('F')) return digit - (T('A') - 10); return -1; } //============================================================================== int CharacterFunctions::printf (char* const dest, const int maxLength, const char* const format, ...) throw() { va_list list; va_start (list, format); return vprintf (dest, maxLength, format, list); } int CharacterFunctions::printf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, ...) throw() { va_list list; va_start (list, format); return vprintf (dest, maxLength, format, list); } int CharacterFunctions::vprintf (char* const dest, const int maxLength, const char* const format, va_list& args) throw() { #if JUCE_WIN32 return (int) _vsnprintf (dest, maxLength, format, args); #else return (int) vsnprintf (dest, maxLength, format, args); #endif } int CharacterFunctions::vprintf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, va_list& args) throw() { #if MACOS_10_3_OR_EARLIER const String formatTemp (format); size_t num = vprintf ((char*) dest, maxLength, formatTemp, args); String temp ((char*) dest); temp.copyToBuffer (dest, num); dest [num] = 0; return (int) num; #elif defined (JUCE_WIN32) return (int) _vsnwprintf (dest, maxLength, format, args); #else return (int) vswprintf (dest, maxLength, format, args); #endif } END_JUCE_NAMESPACE