1 /*
2   ==============================================================================
3 
4    This file is part of the Water library.
5    Copyright (c) 2016 ROLI Ltd.
6    Copyright (C) 2017 Filipe Coelho <falktx@falktx.com>
7 
8    Permission is granted to use this software under the terms of the ISC license
9    http://www.isc.org/downloads/software-support-policy/isc-license/
10 
11    Permission to use, copy, modify, and/or distribute this software for any
12    purpose with or without fee is hereby granted, provided that the above
13    copyright notice and this permission notice appear in all copies.
14 
15    THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16    TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17    FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18    OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19    USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20    TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21    OF THIS SOFTWARE.
22 
23   ==============================================================================
24 */
25 
26 #include "CharacterFunctions.h"
27 
28 #include <locale>
29 
30 namespace water {
31 
32 //==============================================================================
33 
toUpperCase(const water_uchar character)34 water_uchar CharacterFunctions::toUpperCase (const water_uchar character) noexcept
35 {
36     return (water_uchar) towupper ((wint_t) character);
37 }
38 
toLowerCase(const water_uchar character)39 water_uchar CharacterFunctions::toLowerCase (const water_uchar character) noexcept
40 {
41     return (water_uchar) towlower ((wint_t) character);
42 }
43 
isUpperCase(const water_uchar character)44 bool CharacterFunctions::isUpperCase (const water_uchar character) noexcept
45 {
46    #ifdef CARLA_OS_WIN
47     return iswupper ((wint_t) character) != 0;
48    #else
49     return toLowerCase (character) != character;
50    #endif
51 }
52 
isLowerCase(const water_uchar character)53 bool CharacterFunctions::isLowerCase (const water_uchar character) noexcept
54 {
55    #ifdef CARLA_OS_WIN
56     return iswlower ((wint_t) character) != 0;
57    #else
58     return toUpperCase (character) != character;
59    #endif
60 }
61 
62 //==============================================================================
isWhitespace(const char character)63 bool CharacterFunctions::isWhitespace (const char character) noexcept
64 {
65     return character == ' ' || (character <= 13 && character >= 9);
66 }
67 
isWhitespace(const water_uchar character)68 bool CharacterFunctions::isWhitespace (const water_uchar character) noexcept
69 {
70     return iswspace ((wint_t) character) != 0;
71 }
72 
isDigit(const char character)73 bool CharacterFunctions::isDigit (const char character) noexcept
74 {
75     return (character >= '0' && character <= '9');
76 }
77 
isDigit(const water_uchar character)78 bool CharacterFunctions::isDigit (const water_uchar character) noexcept
79 {
80     return iswdigit ((wint_t) character) != 0;
81 }
82 
isLetter(const char character)83 bool CharacterFunctions::isLetter (const char character) noexcept
84 {
85     return (character >= 'a' && character <= 'z')
86         || (character >= 'A' && character <= 'Z');
87 }
88 
isLetter(const water_uchar character)89 bool CharacterFunctions::isLetter (const water_uchar character) noexcept
90 {
91     return iswalpha ((wint_t) character) != 0;
92 }
93 
isLetterOrDigit(const char character)94 bool CharacterFunctions::isLetterOrDigit (const char character) noexcept
95 {
96     return (character >= 'a' && character <= 'z')
97         || (character >= 'A' && character <= 'Z')
98         || (character >= '0' && character <= '9');
99 }
100 
isLetterOrDigit(const water_uchar character)101 bool CharacterFunctions::isLetterOrDigit (const water_uchar character) noexcept
102 {
103     return iswalnum ((wint_t) character) != 0;
104 }
105 
isPrintable(const char character)106 bool CharacterFunctions::isPrintable (const char character) noexcept
107 {
108     return (character >= ' ' && character <= '~');
109 }
110 
isPrintable(const water_uchar character)111 bool CharacterFunctions::isPrintable (const water_uchar character) noexcept
112 {
113     return iswprint ((wint_t) character) != 0;
114 }
115 
getHexDigitValue(const water_uchar digit)116 int CharacterFunctions::getHexDigitValue (const water_uchar digit) noexcept
117 {
118     unsigned int d = (unsigned int) digit - '0';
119     if (d < (unsigned int) 10)
120         return (int) d;
121 
122     d += (unsigned int) ('0' - 'a');
123     if (d < (unsigned int) 6)
124         return (int) d + 10;
125 
126     d += (unsigned int) ('a' - 'A');
127     if (d < (unsigned int) 6)
128         return (int) d + 10;
129 
130     return -1;
131 }
132 
mulexp10(const double value,int exponent)133 double CharacterFunctions::mulexp10 (const double value, int exponent) noexcept
134 {
135     if (exponent == 0)
136         return value;
137 
138     if (value == 0)
139         return 0;
140 
141     const bool negative = (exponent < 0);
142     if (negative)
143         exponent = -exponent;
144 
145     double result = 1.0, power = 10.0;
146     for (int bit = 1; exponent != 0; bit <<= 1)
147     {
148         if ((exponent & bit) != 0)
149         {
150             exponent ^= bit;
151             result *= power;
152             if (exponent == 0)
153                 break;
154         }
155         power *= power;
156     }
157 
158     return negative ? (value / result) : (value * result);
159 }
160 
getUnicodeCharFromWindows1252Codepage(const uint8 c)161 water_uchar CharacterFunctions::getUnicodeCharFromWindows1252Codepage (const uint8 c) noexcept
162 {
163     if (c < 0x80 || c >= 0xa0)
164         return (water_uchar) c;
165 
166     static const uint16 lookup[] = { 0x20AC, 0x0007, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
167                                      0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0007, 0x017D, 0x0007,
168                                      0x0007, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
169                                      0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0007, 0x017E, 0x0178 };
170 
171     return (water_uchar) lookup[c - 0x80];
172 }
173 
174 }
175