OpenShot Audio Library | OpenShotAudio  0.3.3
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 //==============================================================================
184 //==============================================================================
185 #if JUCE_UNIT_TESTS
186 
187 #define QUOTE(x) #x
188 #define STR(value) QUOTE(value)
189 #define ASYM_STRING_DOUBLE_PAIR(str, value) std::pair<String, double> (STR(str), value)
190 #define STRING_DOUBLE_PAIR(value) ASYM_STRING_DOUBLE_PAIR(value, value)
191 #define STRING_DOUBLE_PAIR_COMBOS(value) \
192  STRING_DOUBLE_PAIR(value), \
193  STRING_DOUBLE_PAIR(-value), \
194  ASYM_STRING_DOUBLE_PAIR(+value, value), \
195  ASYM_STRING_DOUBLE_PAIR(000000 ## value, value), \
196  ASYM_STRING_DOUBLE_PAIR(+000 ## value, value), \
197  ASYM_STRING_DOUBLE_PAIR(-0 ## value, -value)
198 
199 class CharacterFunctionsTests : public UnitTest
200 {
201 public:
202  CharacterFunctionsTests()
203  : UnitTest ("CharacterFunctions", UnitTestCategories::text)
204  {}
205 
206  void runTest() override
207  {
208  beginTest ("readDoubleValue");
209 
210  static const std::pair<String, double> testValues[] =
211  {
212  // Integers
213  STRING_DOUBLE_PAIR_COMBOS (0),
214  STRING_DOUBLE_PAIR_COMBOS (3),
215  STRING_DOUBLE_PAIR_COMBOS (4931),
216  STRING_DOUBLE_PAIR_COMBOS (5000),
217  STRING_DOUBLE_PAIR_COMBOS (9862097),
218 
219  // Floating point numbers
220  STRING_DOUBLE_PAIR_COMBOS (7.000),
221  STRING_DOUBLE_PAIR_COMBOS (0.2),
222  STRING_DOUBLE_PAIR_COMBOS (.298630),
223  STRING_DOUBLE_PAIR_COMBOS (1.118),
224  STRING_DOUBLE_PAIR_COMBOS (0.9000),
225  STRING_DOUBLE_PAIR_COMBOS (0.0000001),
226  STRING_DOUBLE_PAIR_COMBOS (500.0000001),
227  STRING_DOUBLE_PAIR_COMBOS (9862098.2398604),
228 
229  // Exponents
230  STRING_DOUBLE_PAIR_COMBOS (0e0),
231  STRING_DOUBLE_PAIR_COMBOS (0.e0),
232  STRING_DOUBLE_PAIR_COMBOS (0.00000e0),
233  STRING_DOUBLE_PAIR_COMBOS (.0e7),
234  STRING_DOUBLE_PAIR_COMBOS (0e-5),
235  STRING_DOUBLE_PAIR_COMBOS (2E0),
236  STRING_DOUBLE_PAIR_COMBOS (4.E0),
237  STRING_DOUBLE_PAIR_COMBOS (1.2000000E0),
238  STRING_DOUBLE_PAIR_COMBOS (1.2000000E6),
239  STRING_DOUBLE_PAIR_COMBOS (.398e3),
240  STRING_DOUBLE_PAIR_COMBOS (10e10),
241  STRING_DOUBLE_PAIR_COMBOS (1.4962e+2),
242  STRING_DOUBLE_PAIR_COMBOS (3198693.0973e4),
243  STRING_DOUBLE_PAIR_COMBOS (10973097.2087E-4),
244  STRING_DOUBLE_PAIR_COMBOS (1.3986e00006),
245  STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006),
246  STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006),
247 
248  // Too many sig figs. The parsing routine on MinGW gets the last
249  // significant figure wrong.
250  STRING_DOUBLE_PAIR_COMBOS (17654321098765432.9),
251  STRING_DOUBLE_PAIR_COMBOS (183456789012345678.9),
252  STRING_DOUBLE_PAIR_COMBOS (1934567890123456789.9),
253  STRING_DOUBLE_PAIR_COMBOS (20345678901234567891.9),
254  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000),
255  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e3),
256  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752e100),
257  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-5),
258  STRING_DOUBLE_PAIR_COMBOS (10000000000000000303786028427003666890752.000000e-40),
259 
260  STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890),
261  STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111)
262 
263  // Limits. DBL_MAX may not exist on Linux.
264  #if ! JUCE_LINUX
265  , STRING_DOUBLE_PAIR (DBL_MAX),
266  STRING_DOUBLE_PAIR (-DBL_MAX),
267  STRING_DOUBLE_PAIR (DBL_MIN)
268  #endif
269  };
270 
271  for (auto trial : testValues)
272  {
273  auto charPtr = trial.first.getCharPointer();
274  expectEquals (CharacterFunctions::readDoubleValue (charPtr), trial.second);
275  }
276 
277  {
278  String nans[] = { "NaN", "-nan", "+NAN", "1.0E1024", "-1.0E-999", "1.23456789012345678901234567890e123456789"};
279 
280  for (auto nan : nans)
281  {
282  auto charPtr = nan.getCharPointer();
283  expect (std::isnan (CharacterFunctions::readDoubleValue (charPtr)));
284  }
285  }
286 
287  {
288  String infs[] = { "Inf", "-inf", "INF"};
289 
290  for (auto inf : infs)
291  {
292  auto charPtr = inf.getCharPointer();
293  expect (std::isinf (CharacterFunctions::readDoubleValue (charPtr)));
294  }
295  }
296  }
297 };
298 
299 static CharacterFunctionsTests characterFunctionsTests;
300 
301 #endif
302 
303 } // namespace juce
static juce_wchar toLowerCase(juce_wchar character) noexcept
static bool isDigit(char character) noexcept
static bool isLowerCase(juce_wchar character) noexcept
static bool isLetter(char character) noexcept
static double readDoubleValue(CharPointerType &text) noexcept
static int getHexDigitValue(juce_wchar digit) noexcept
static bool isWhitespace(char character) noexcept
static bool isLetterOrDigit(char character) noexcept
static juce_wchar toUpperCase(juce_wchar character) noexcept
static bool isUpperCase(juce_wchar character) noexcept
static bool isPrintable(char character) noexcept
static juce_wchar getUnicodeCharFromWindows1252Codepage(uint8 windows1252Char) noexcept