OpenShot Library | libopenshot-audio
0.2.0
|
35 case '{':
return parseObject (t, result);
36 case '[':
return parseArray (t, result);
39 return createFail (
"Expected '{' or '['", &t);
64 case 'a': c =
'\a';
break;
65 case 'b': c =
'\b';
break;
66 case 'f': c =
'\f';
break;
67 case 'n': c =
'\n';
break;
68 case 'r': c =
'\r';
break;
69 case 't': c =
'\t';
break;
75 for (
int i = 4; --i >= 0;)
80 return createFail (
"Syntax error in unicode escape sequence");
82 c = (juce_wchar) ((c << 4) +
static_cast<juce_wchar
> (digitValue));
91 return createFail (
"Unexpected end-of-input in string constant");
105 switch (t2.getAndAdvance())
107 case '{': t = t2;
return parseObject (t, result);
108 case '[': t = t2;
return parseArray (t, result);
109 case '"': t = t2;
return parseString (
'"', t, result);
110 case '\'': t = t2;
return parseString (
'\'', t, result);
113 t2 = t2.findEndOfWhitespace();
118 return parseNumber (t, result,
true);
120 case '0':
case '1':
case '2':
case '3':
case '4':
121 case '5':
case '6':
case '7':
case '8':
case '9':
122 return parseNumber (t, result,
false);
125 if (t2.getAndAdvance() ==
'r' && t2.getAndAdvance() ==
'u' && t2.getAndAdvance() ==
'e')
134 if (t2.getAndAdvance() ==
'a' && t2.getAndAdvance() ==
'l'
135 && t2.getAndAdvance() ==
's' && t2.getAndAdvance() ==
'e')
138 result =
var (
false);
144 if (t2.getAndAdvance() ==
'u' && t2.getAndAdvance() ==
'l' && t2.getAndAdvance() ==
'l')
156 return createFail (
"Syntax error", &t);
163 if (location !=
nullptr)
164 m <<
": \"" <<
String (*location, 20) <<
'"';
174 jassert (intValue >= 0 && intValue < 10);
178 auto previousChar = t;
180 auto digit = ((int) c) -
'0';
182 if (isPositiveAndBelow (digit, 10))
184 intValue = intValue * 10 + digit;
188 if (c ==
'e' || c ==
'E' || c ==
'.')
192 result = isNegative ? -asDouble : asDouble;
197 || c ==
',' || c ==
'}' || c ==
']' || c == 0)
203 return createFail (
"Syntax error in number", &oldT);
206 auto correctedValue = isNegative ? -intValue : intValue;
208 if ((intValue >> 31) != 0)
209 result = correctedValue;
211 result = (int) correctedValue;
219 result = resultObject;
220 auto& resultProperties = resultObject->getProperties();
233 return createFail (
"Unexpected end-of-input in object declaration");
238 auto r = parseString (
'"', t, propertyNameVar);
243 const Identifier propertyName (propertyNameVar.toString());
253 return createFail (
"Expected ':', but found", &oldT);
255 resultProperties.set (propertyName,
var());
256 var* propertyValue = resultProperties.getVarPointer (propertyName);
258 auto r2 = parseAny (t, *propertyValue);
276 return createFail (
"Expected object member declaration, but found", &oldT);
285 auto* destArray = result.
getArray();
298 return createFail (
"Unexpected end-of-input in array declaration");
301 destArray->add (
var());
302 auto r = parseAny (t, destArray->getReference (destArray->size() - 1));
318 return createFail (
"Expected object array item, but found", &oldT);
329 int indentLevel,
bool allOnOneLine,
int maximumDecimalPlaces)
341 else if (v.isUndefined())
347 out << (static_cast<bool> (v) ?
"true" :
"false");
349 else if (v.isDouble())
351 auto d =
static_cast<double> (v);
353 if (juce_isfinite (d))
355 out << serialiseDouble (d);
362 else if (v.isArray())
364 writeArray (out, *v.
getArray(), indentLevel, allOnOneLine, maximumDecimalPlaces);
366 else if (v.isObject())
368 if (
auto*
object = v.getDynamicObject())
369 object->writeAsJSON (out, indentLevel, allOnOneLine, maximumDecimalPlaces);
376 jassert (! (v.isMethod() || v.isBinaryData()));
382 static void writeEscapedChar (
OutputStream& out,
const unsigned short value)
397 case '\"': out <<
"\\\"";
break;
398 case '\\': out <<
"\\\\";
break;
399 case '\a': out <<
"\\a";
break;
400 case '\b': out <<
"\\b";
break;
401 case '\f': out <<
"\\f";
break;
402 case '\t': out <<
"\\t";
break;
403 case '\r': out <<
"\\r";
break;
404 case '\n': out <<
"\\n";
break;
407 if (c >= 32 && c < 127)
415 CharPointer_UTF16::CharType chars[2];
419 for (
int i = 0; i < 2; ++i)
420 writeEscapedChar (out, (
unsigned short) chars[i]);
424 writeEscapedChar (out, (
unsigned short) c);
433 static void writeSpaces (
OutputStream& out,
int numSpaces)
439 int indentLevel,
bool allOnOneLine,
int maximumDecimalPlaces)
448 for (
int i = 0; i < array.
size(); ++i)
451 writeSpaces (out, indentLevel + indentSize);
453 write (out, array.
getReference(i), indentLevel + indentSize, allOnOneLine, maximumDecimalPlaces);
455 if (i < array.
size() - 1)
460 out <<
',' << newLine;
462 else if (! allOnOneLine)
467 writeSpaces (out, indentLevel);
473 enum { indentSize = 2 };
481 if (!
parse (text, result))
491 if (! JSONParser::parseAny (text.
text, result))
509 return JSONParser::parseObjectOrArray (text.
getCharPointer(), result);
515 JSONFormatter::write (mo, data, 0, allOnOneLine, maximumDecimalPlaces);
521 JSONFormatter::write (output, data, 0, allOnOneLine, maximumDecimalPlaces);
527 JSONFormatter::writeString (mo, s.
text);
535 if (quote ==
'"' || quote ==
'\'')
536 return JSONParser::parseString (quote, t, result);
548 JSONTests() :
UnitTest (
"JSON",
"JSON") {}
550 static String createRandomWideCharString (Random& r)
552 juce_wchar buffer[40] = { 0 };
554 for (
int i = 0; i < numElementsInArray (buffer) - 1; ++i)
560 buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
565 buffer[i] = (juce_wchar) (1 + r.nextInt (0xff));
568 return CharPointer_UTF32 (buffer);
571 static String createRandomIdentifier (Random& r)
573 char buffer[30] = { 0 };
575 for (
int i = 0; i < numElementsInArray (buffer) - 1; ++i)
577 static const char chars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:";
578 buffer[i] = chars [r.nextInt (
sizeof (chars) - 1)];
581 return CharPointer_ASCII (buffer);
586 static var createRandomDouble (Random& r)
588 return var ((r.nextDouble() * 1000.0) + 0.1);
591 static var createRandomVar (Random& r,
int depth)
593 switch (r.nextInt (depth > 3 ? 6 : 8))
596 case 1:
return r.nextInt();
597 case 2:
return r.nextInt64();
598 case 3:
return r.nextBool();
599 case 4:
return createRandomDouble (r);
600 case 5:
return createRandomWideCharString (r);
604 var v (createRandomVar (r, depth + 1));
606 for (
int i = 1 + r.nextInt (30); --i >= 0;)
607 v.append (createRandomVar (r, depth + 1));
614 DynamicObject* o =
new DynamicObject();
616 for (
int i = r.nextInt (30); --i >= 0;)
617 o->setProperty (createRandomIdentifier (r), createRandomVar (r, depth + 1));
627 void runTest()
override
632 Random r = getRandom();
638 expect (
JSON::parse (
"[ 12345678901234 ]")[0].isInt64());
639 expect (
JSON::parse (
"[ 1.123e3 ]")[0].isDouble());
641 expect (
JSON::parse (
"[-12345678901234]")[0].isInt64());
644 for (
int i = 100; --i >= 0;)
649 v = createRandomVar (r, 0);
651 const bool oneLine = r.nextBool();
653 var parsed =
JSON::parse (
"[" + asString +
"]")[0];
655 expect (asString.isNotEmpty() && parsedString == asString);
660 beginTest (
"Float formatting");
662 std::map<double, String> tests;
665 tests[1.01] =
"1.01";
666 tests[0.76378] =
"0.76378";
667 tests[-10] =
"-10.0";
668 tests[10.01] =
"10.01";
669 tests[0.0123] =
"0.0123";
670 tests[-3.7e-27] =
"-3.7e-27";
671 tests[1e+40] =
"1.0e40";
672 tests[-12345678901234567.0] =
"-1.234567890123457e16";
673 tests[192000] =
"192000.0";
674 tests[1234567] =
"1.234567e6";
675 tests[0.00006] =
"0.00006";
676 tests[0.000006] =
"6.0e-6";
678 for (
auto& test : tests)
684 static JSONTests JSONUnitTests;
String loadFileAsString() const
Reads a file into memory as a string.
static size_t getBytesRequiredFor(juce_wchar charToWrite) noexcept
Returns the number of bytes that would be needed to represent the given unicode character in this enc...
A simple class for holding temporary references to a string literal or String.
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.
Represents the 'success' or 'failure' of an operation, and holds an associated error message to descr...
int size() const noexcept
Returns the current number of elements in the array.
Writes data to an internal memory buffer, which grows as required.
CharPointerType getCharPointer() const noexcept
Returns the character pointer currently being used to store this string.
Represents a dynamically implemented object.
Holds a resizable array of primitive or copy-by-value objects.
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
Wraps a pointer to a null-terminated UTF-16 character string, and provides various methods to operate...
static double readDoubleValue(CharPointerType &text) noexcept
Parses a character string to read a floating-point number.
String::CharPointerType text
The text that is referenced.
static bool canRepresent(juce_wchar character) noexcept
Returns true if the given unicode character can be represented in this encoding.
The base class for streams that write data to some kind of destination.
Represents a local file or directory.
bool isValid() const noexcept
Returns true if this Identifier is not null.
String toUTF8() const
Returns a String created from the (UTF8) data that has been written to the stream.
static Result parse(const String &text, var &parsedResult)
Parses a string of JSON-formatted text, and returns a result code containing any parse errors.
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Returns the first non-whitespace character in the string.
A variant class, that can be used to hold a range of primitive values.
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat)
Writes a byte to the output stream a given number of times.
static String toString(const var &objectToFormat, bool allOnOneLine=false, int maximumDecimalPlaces=15)
Returns a string which contains a JSON-formatted representation of the var object.
static bool isDigit(char character) noexcept
Checks whether a character is a digit.
Array< var > * getArray() const noexcept
If this variant holds an array, this provides access to it.
static Result parseQuotedString(String::CharPointerType &text, var &result)
Parses a quoted string-literal in JSON format, returning the un-escaped result in the result paramete...
Represents a string identifier, designed for accessing properties by name.
String paddedLeft(juce_wchar padCharacter, int minimumLength) const
Returns a copy of this string with the specified character repeatedly added to its beginning until th...
static String escapeString(StringRef)
Returns a version of a string with any extended characters escaped.
String toString() const
Attempts to detect the encoding of the data and convert it to a string.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
This is a base class for classes that perform a unit test.
static bool isWhitespace(char character) noexcept
Checks whether a character is whitespace.
void write(juce_wchar charToWrite) noexcept
Writes a unicode character to this string, and advances this pointer to point to the next position.
static void writeToStream(OutputStream &output, const var &objectToFormat, bool allOnOneLine=false, int maximumDecimalPlaces=15)
Writes a JSON-formatted representation of the var object to the given stream.
static Result ok() noexcept
Creates and returns a 'successful' result.
juce_wchar getAndAdvance() noexcept
Returns the character that this pointer is currently pointing to, and then advances the pointer to po...
static var fromString(StringRef)
Parses a string that was created with the toString() method.
ElementType & getReference(int index) const noexcept
Returns a direct reference to one of the elements in the array, without checking the index passed in.
bool appendUTF8Char(juce_wchar character)
Appends the utf-8 bytes for a unicode character.
static Result fail(const String &errorMessage) noexcept
Creates a 'failure' result.
bool isEmpty() const noexcept
Returns true if the array is empty, false otherwise.