OpenShot Library | libopenshot-audio  0.2.0
juce_CharacterFunctions.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 #if JUCE_MSVC
27  #pragma warning (push)
28  #pragma warning (disable: 4514 4996)
29 #endif
30 
31 juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) noexcept
32 {
33  return (juce_wchar) towupper ((wint_t) character);
34 }
35 
36 juce_wchar CharacterFunctions::toLowerCase (const juce_wchar character) noexcept
37 {
38  return (juce_wchar) towlower ((wint_t) character);
39 }
40 
41 bool CharacterFunctions::isUpperCase (const juce_wchar character) noexcept
42 {
43  #if JUCE_WINDOWS
44  return iswupper ((wint_t) character) != 0;
45  #else
46  return toLowerCase (character) != character;
47  #endif
48 }
49 
50 bool CharacterFunctions::isLowerCase (const juce_wchar character) noexcept
51 {
52  #if JUCE_WINDOWS
53  return iswlower ((wint_t) character) != 0;
54  #else
55  return toUpperCase (character) != character;
56  #endif
57 }
58 
59 #if JUCE_MSVC
60  #pragma warning (pop)
61 #endif
62 
63 //==============================================================================
64 bool CharacterFunctions::isWhitespace (const char character) noexcept
65 {
66  return character == ' ' || (character <= 13 && character >= 9);
67 }
68 
69 bool CharacterFunctions::isWhitespace (const juce_wchar character) noexcept
70 {
71  return iswspace ((wint_t) character) != 0;
72 }
73 
74 bool CharacterFunctions::isDigit (const char character) noexcept
75 {
76  return (character >= '0' && character <= '9');
77 }
78 
79 bool CharacterFunctions::isDigit (const juce_wchar character) noexcept
80 {
81  return iswdigit ((wint_t) character) != 0;
82 }
83 
84 bool CharacterFunctions::isLetter (const char character) noexcept
85 {
86  return (character >= 'a' && character <= 'z')
87  || (character >= 'A' && character <= 'Z');
88 }
89 
90 bool CharacterFunctions::isLetter (const juce_wchar character) noexcept
91 {
92  return iswalpha ((wint_t) character) != 0;
93 }
94 
95 bool CharacterFunctions::isLetterOrDigit (const char character) noexcept
96 {
97  return (character >= 'a' && character <= 'z')
98  || (character >= 'A' && character <= 'Z')
99  || (character >= '0' && character <= '9');
100 }
101 
102 bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) noexcept
103 {
104  return iswalnum ((wint_t) character) != 0;
105 }
106 
107 bool CharacterFunctions::isPrintable (const char character) noexcept
108 {
109  return (character >= ' ' && character <= '~');
110 }
111 
112 bool CharacterFunctions::isPrintable (const juce_wchar character) noexcept
113 {
114  return iswprint ((wint_t) character) != 0;
115 }
116 
117 int CharacterFunctions::getHexDigitValue (const juce_wchar digit) noexcept
118 {
119  auto d = (unsigned int) (digit - '0');
120 
121  if (d < (unsigned int) 10)
122  return (int) d;
123 
124  d += (unsigned int) ('0' - 'a');
125 
126  if (d < (unsigned int) 6)
127  return (int) d + 10;
128 
129  d += (unsigned int) ('a' - 'A');
130 
131  if (d < (unsigned int) 6)
132  return (int) d + 10;
133 
134  return -1;
135 }
136 
137 double CharacterFunctions::mulexp10 (const double value, int exponent) noexcept
138 {
139  if (exponent == 0)
140  return value;
141 
142  if (value == 0.0)
143  return 0;
144 
145  const bool negative = (exponent < 0);
146 
147  if (negative)
148  exponent = -exponent;
149 
150  double result = 1.0, power = 10.0;
151 
152  for (int bit = 1; exponent != 0; bit <<= 1)
153  {
154  if ((exponent & bit) != 0)
155  {
156  exponent ^= bit;
157  result *= power;
158 
159  if (exponent == 0)
160  break;
161  }
162 
163  power *= power;
164  }
165 
166  return negative ? (value / result) : (value * result);
167 }
168 
170 {
171  if (c < 0x80 || c >= 0xa0)
172  return (juce_wchar) c;
173 
174  static const uint16 lookup[] = { 0x20AC, 0x0007, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
175  0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0007, 0x017D, 0x0007,
176  0x0007, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
177  0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0007, 0x017E, 0x0178 };
178 
179  return (juce_wchar) lookup[c - 0x80];
180 }
181 
182 //==============================================================================
183 #if JUCE_UNIT_TESTS
184 
185 #define QUOTE(x) #x
186 #define STR(value) QUOTE(value)
187 #define ASYM_STRING_DOUBLE_PAIR(str, value) std::pair<String, double> (STR(str), value)
188 #define STRING_DOUBLE_PAIR(value) ASYM_STRING_DOUBLE_PAIR(value, value)
189 #define STRING_DOUBLE_PAIR_COMBOS(value) \
190  STRING_DOUBLE_PAIR(value), \
191  STRING_DOUBLE_PAIR(-value), \
192  ASYM_STRING_DOUBLE_PAIR(+value, value), \
193  ASYM_STRING_DOUBLE_PAIR(000000 ## value, value), \
194  ASYM_STRING_DOUBLE_PAIR(+000 ## value, value), \
195  ASYM_STRING_DOUBLE_PAIR(-0 ## value, -value)
196 
197 class CharacterFunctionsTests : public UnitTest
198 {
199 public:
200  CharacterFunctionsTests() : UnitTest ("CharacterFunctions", "Text") {}
201 
202  void runTest() override
203  {
204  beginTest ("readDoubleValue");
205 
206  static const std::pair<String, double> testValues[] =
207  {
208  // Integers
209  STRING_DOUBLE_PAIR_COMBOS (0),
210  STRING_DOUBLE_PAIR_COMBOS (3),
211  STRING_DOUBLE_PAIR_COMBOS (4931),
212  STRING_DOUBLE_PAIR_COMBOS (5000),
213  STRING_DOUBLE_PAIR_COMBOS (9862097),
214 
215  // Floating point numbers
216  STRING_DOUBLE_PAIR_COMBOS (7.000),
217  STRING_DOUBLE_PAIR_COMBOS (0.2),
218  STRING_DOUBLE_PAIR_COMBOS (.298630),
219  STRING_DOUBLE_PAIR_COMBOS (1.118),
220  STRING_DOUBLE_PAIR_COMBOS (0.9000),
221  STRING_DOUBLE_PAIR_COMBOS (0.0000001),
222  STRING_DOUBLE_PAIR_COMBOS (500.0000001),
223  STRING_DOUBLE_PAIR_COMBOS (9862098.2398604),
224 
225  // Exponents
226  STRING_DOUBLE_PAIR_COMBOS (0e0),
227  STRING_DOUBLE_PAIR_COMBOS (0.e0),
228  STRING_DOUBLE_PAIR_COMBOS (0.00000e0),
229  STRING_DOUBLE_PAIR_COMBOS (.0e7),
230  STRING_DOUBLE_PAIR_COMBOS (0e-5),
231  STRING_DOUBLE_PAIR_COMBOS (2E0),
232  STRING_DOUBLE_PAIR_COMBOS (4.E0),
233  STRING_DOUBLE_PAIR_COMBOS (1.2000000E0),
234  STRING_DOUBLE_PAIR_COMBOS (1.2000000E6),
235  STRING_DOUBLE_PAIR_COMBOS (.398e3),
236  STRING_DOUBLE_PAIR_COMBOS (10e10),
237  STRING_DOUBLE_PAIR_COMBOS (1.4962e+2),
238  STRING_DOUBLE_PAIR_COMBOS (3198693.0973e4),
239  STRING_DOUBLE_PAIR_COMBOS (10973097.2087E-4),
240  STRING_DOUBLE_PAIR_COMBOS (1.3986e00006),
241  STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006),
242  STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006),
243 
244  // Too many sig figs. The parsing routine on MinGW gets the last
245  // significant figure wrong.
246  STRING_DOUBLE_PAIR_COMBOS (17654321098765432.9),
247  STRING_DOUBLE_PAIR_COMBOS (183456789012345678.9),
248  STRING_DOUBLE_PAIR_COMBOS (1934567890123456789.9),
249  STRING_DOUBLE_PAIR_COMBOS (20345678901234567891.9),
250  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000),
251  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e3),
252  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e100),
253  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-5),
254  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-40),
255 
256  STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890),
257  STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111)
258 
259  // Limits. DBL_MAX may not exist on Linux.
260  #if ! JUCE_LINUX
261  , STRING_DOUBLE_PAIR (DBL_MAX),
262  STRING_DOUBLE_PAIR (-DBL_MAX),
263  STRING_DOUBLE_PAIR (DBL_MIN)
264  #endif
265  };
266 
267  for (auto trial : testValues)
268  {
269  auto charPtr = trial.first.getCharPointer();
270  expectEquals (CharacterFunctions::readDoubleValue (charPtr), trial.second);
271  }
272 
273  {
274  String nans[] = { "NaN", "-nan", "+NAN", "1.0E1024", "-1.0E-999", "1.23456789012345678901234567890e123456789"};
275 
276  for (auto nan : nans)
277  {
278  auto charPtr = nan.getCharPointer();
279  expect (std::isnan (CharacterFunctions::readDoubleValue (charPtr)));
280  }
281  }
282 
283  {
284  String infs[] = { "Inf", "-inf", "INF"};
285 
286  for (auto inf : infs)
287  {
288  auto charPtr = inf.getCharPointer();
289  expect (std::isinf (CharacterFunctions::readDoubleValue (charPtr)));
290  }
291  }
292  }
293 };
294 
295 static CharacterFunctionsTests characterFunctionsTests;
296 
297 #endif
298 
299 } // namespace juce
juce::CharacterFunctions::isPrintable
static bool isPrintable(char character) noexcept
Checks whether a character is a printable character, i.e.
Definition: juce_CharacterFunctions.cpp:107
juce::CharacterFunctions::isLowerCase
static bool isLowerCase(juce_wchar character) noexcept
Checks whether a unicode character is lower-case.
Definition: juce_CharacterFunctions.cpp:50
juce::CharacterFunctions::isLetter
static bool isLetter(char character) noexcept
Checks whether a character is alphabetic.
Definition: juce_CharacterFunctions.cpp:84
juce::CharacterFunctions::getHexDigitValue
static int getHexDigitValue(juce_wchar digit) noexcept
Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit.
Definition: juce_CharacterFunctions.cpp:117
juce::CharacterFunctions::getUnicodeCharFromWindows1252Codepage
static juce_wchar getUnicodeCharFromWindows1252Codepage(uint8 windows1252Char) noexcept
Converts a byte of Windows 1252 codepage to unicode.
Definition: juce_CharacterFunctions.cpp:169
juce::CharacterFunctions::isUpperCase
static bool isUpperCase(juce_wchar character) noexcept
Checks whether a unicode character is upper-case.
Definition: juce_CharacterFunctions.cpp:41
juce::CharacterFunctions::readDoubleValue
static double readDoubleValue(CharPointerType &text) noexcept
Parses a character string to read a floating-point number.
Definition: juce_CharacterFunctions.h:151
juce::CharacterFunctions::isDigit
static bool isDigit(char character) noexcept
Checks whether a character is a digit.
Definition: juce_CharacterFunctions.cpp:74
juce::CharacterFunctions::isLetterOrDigit
static bool isLetterOrDigit(char character) noexcept
Checks whether a character is alphabetic or numeric.
Definition: juce_CharacterFunctions.cpp:95
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::CharacterFunctions::isWhitespace
static bool isWhitespace(char character) noexcept
Checks whether a character is whitespace.
Definition: juce_CharacterFunctions.cpp:64
juce::CharacterFunctions::toUpperCase
static juce_wchar toUpperCase(juce_wchar character) noexcept
Converts a character to upper-case.
Definition: juce_CharacterFunctions.cpp:31
juce::CharacterFunctions::toLowerCase
static juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
Definition: juce_CharacterFunctions.cpp:36