35 int line = 1, column = 1;
37 String getDescription()
const {
return String (line) +
":" +
String (column) +
": error: " + message; }
44 e.message = std::move (message);
46 for (
auto i = startLocation; i < location && ! i.
isEmpty(); ++i)
49 if (*i ==
'\n') { e.column = 1; e.line++; }
57 juce_wchar peekChar()
const {
return *currentLocation; }
58 bool matchIf (
char c) {
if (peekChar() == (
juce_wchar) c) { ++currentLocation;
return true; }
return false; }
59 bool isEOF()
const {
return peekChar() == 0; }
61 bool matchString (
const char* t)
70 var parseObjectOrArray()
74 if (matchIf (
'{'))
return parseObject();
75 if (matchIf (
'['))
return parseArray();
78 throwError (
"Expected '{' or '['", currentLocation);
85 MemoryOutputStream buffer (256);
106 case 'a': c =
'\a';
break;
107 case 'b': c =
'\b';
break;
108 case 'f': c =
'\f';
break;
109 case 'n': c =
'\n';
break;
110 case 'r': c =
'\r';
break;
111 case 't': c =
'\t';
break;
117 for (
int i = 4; --i >= 0;)
122 throwError (
"Syntax error in unicode escape sequence",
errorLocation);
135 throwError (
"Unexpected EOF in string constant", currentLocation);
137 buffer.appendUTF8Char (c);
140 return buffer.toUTF8();
150 case '{':
return parseObject();
151 case '[':
return parseArray();
152 case '"':
return parseString (
'"');
153 case '\'':
return parseString (
'\'');
157 return parseNumber (
true);
159 case '0':
case '1':
case '2':
case '3':
case '4':
160 case '5':
case '6':
case '7':
case '8':
case '9':
162 return parseNumber (
false);
165 if (matchString (
"rue"))
171 if (matchString (
"alse"))
177 if (matchString (
"ull"))
189 var parseNumber (
bool isNegative)
193 int64 intValue = readChar() -
'0';
194 jassert (intValue >= 0 && intValue < 10);
198 auto lastPos = currentLocation;
204 intValue = intValue * 10 +
digit;
208 if (c ==
'e' || c ==
'E' || c ==
'.')
216 || c ==
',' || c ==
'}' || c ==
']' || c == 0)
222 throwError (
"Syntax error in number",
lastPos);
251 throwError (
"Expected a property name in double-quotes",
errorLocation);
262 if (readChar() !=
':')
268 if (matchIf (
','))
continue;
269 if (matchIf (
'}'))
break;
271 throwError (
"Expected ',' or '}'", currentLocation);
296 if (matchIf (
','))
continue;
297 if (matchIf (
']'))
break;
299 throwError (
"Expected ',' or ']'", currentLocation);
309 static void writeEscapedChar (
OutputStream& out,
const unsigned short value)
324 case '\"': out <<
"\\\"";
break;
325 case '\\': out <<
"\\\\";
break;
326 case '\a': out <<
"\\a";
break;
327 case '\b': out <<
"\\b";
break;
328 case '\f': out <<
"\\f";
break;
329 case '\t': out <<
"\\t";
break;
330 case '\r': out <<
"\\r";
break;
331 case '\n': out <<
"\\n";
break;
334 if (c >= 32 && c < 127)
342 CharPointer_UTF16::CharType
chars[2];
346 for (
int i = 0; i < 2; ++i)
347 writeEscapedChar (out, (
unsigned short)
chars[i]);
351 writeEscapedChar (out, (
unsigned short) c);
374 for (
int i = 0; i < array.
size(); ++i)
377 writeSpaces (out, format.getIndentLevel() + indentSize);
381 if (i < array.
size() - 1)
385 switch (format.getSpacing())
397 writeSpaces (out, format.getIndentLevel());
403 enum { indentSize = 2 };
419 else if (v.isUndefined())
427 else if (v.isDouble())
429 auto d =
static_cast<double> (v);
433 out << serialiseDouble (d);
440 else if (v.isArray())
442 JSONFormatter::writeArray (out, *v.
getArray(), opt);
444 else if (v.isObject())
446 if (
auto*
object = v.getDynamicObject())
447 object->writeAsJSON (out, opt);
454 jassert (! (v.isMethod() || v.isBinaryData()));
472 if (
parse (text, result))
507 return error.getResult();
528 JSONFormatter::writeString (
mo, s.
text);
529 return mo.toString();
543 t =
parser.currentLocation;
547 return error.getResult();
575 buffer[i] = (
juce_wchar) (1 + r.nextInt (0x10ffff - 1));
580 buffer[i] = (
juce_wchar) (1 + r.nextInt (0xff));
583 return CharPointer_UTF32 (buffer);
588 char buffer[30] = { 0 };
592 static const char chars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:";
593 buffer[i] =
chars [r.nextInt (
sizeof (
chars) - 1)];
596 return CharPointer_ASCII (buffer);
603 return var ((r.nextDouble() * 1000.0) + 0.1);
608 switch (r.nextInt (depth > 3 ? 6 : 8))
611 case 1:
return r.nextInt();
612 case 2:
return r.nextInt64();
613 case 3:
return r.nextBool();
621 for (
int i = 1 + r.nextInt (30); --i >= 0;)
629 auto o =
new DynamicObject();
631 for (
int i = r.nextInt (30); --i >= 0;)
642 void runTest()
override
647 auto r = getRandom();
653 expect (
JSON::parse (
"[ 12345678901234 ]")[0].isInt64());
654 expect (
JSON::parse (
"[ 1.123e3 ]")[0].isDouble());
656 expect (
JSON::parse (
"[-12345678901234]")[0].isInt64());
659 for (
int i = 100; --i >= 0;)
666 const auto oneLine = r.nextBool();
670 expect (asString.isNotEmpty() &&
parsedString == asString);
675 beginTest (
"Float formatting");
680 tests[1.01] =
"1.01";
681 tests[0.76378] =
"0.76378";
682 tests[-10] =
"-10.0";
683 tests[10.01] =
"10.01";
684 tests[0.0123] =
"0.0123";
685 tests[-3.7e-27] =
"-3.7e-27";
686 tests[1e+40] =
"1.0e40";
687 tests[-12345678901234567.0] =
"-1.234567890123457e16";
688 tests[192000] =
"192000.0";
689 tests[1234567] =
"1.234567e6";
690 tests[0.00006] =
"0.00006";
691 tests[0.000006] =
"6.0e-6";
693 for (
auto& test :
tests)
694 expectEquals (JSON::
toString (test.first), test.second);
Holds a resizable array of primitive or copy-by-value objects.
bool isEmpty() const noexcept
Returns true if the array is empty, false otherwise.
int size() const noexcept
Returns the current number of elements in the array.
ElementType & getReference(int index) noexcept
Returns a direct reference to one of the elements in the array, without checking the index passed in.
Wraps a pointer to a null-terminated UTF-16 character string, and provides various methods to operate...
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...
static bool canRepresent(juce_wchar character) noexcept
Returns true if the given unicode character can be represented in this encoding.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
juce_wchar getAndAdvance() noexcept
Returns the character that this pointer is currently pointing to, and then advances the pointer to po...
bool isEmpty() const noexcept
Returns true if this pointer is pointing to a null character.
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Returns the first non-whitespace character in the string.
static bool isWhitespace(char character) noexcept
Checks whether a character is whitespace.
static double readDoubleValue(CharPointerType &text) noexcept
Parses a character string to read a floating-point number.
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 a local file or directory.
String loadFileAsString() const
Reads a file into memory as a string.
static var fromString(StringRef)
Parses a string that was created with the toString() method.
static Result parse(const String &text, var &parsedResult)
Parses a string of JSON-formatted text, and returns a result code containing any parse errors.
static String escapeString(StringRef)
Returns a version of a string with any extended characters escaped.
@ none
All optional whitespace should be omitted.
@ multiLine
Newlines and spaces will be included in the output, in order to make it easy to read for humans.
@ singleLine
All output should be on a single line, but with some additional spacing, e.g. after commas and colons...
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 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 parseQuotedString(String::CharPointerType &text, var &result)
Parses a quoted string-literal in JSON format, returning the un-escaped result in the result paramete...
Writes data to an internal memory buffer, which grows as required.
The base class for streams that write data to some kind of destination.
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat)
Writes a byte to the output stream a given number of times.
Represents the 'success' or 'failure' of an operation, and holds an associated error message to descr...
static Result fail(const String &errorMessage) noexcept
Creates a 'failure' result.
static Result ok() noexcept
Creates and returns a 'successful' result.
A simple class for holding temporary references to a string literal or String.
String::CharPointerType text
The text that is referenced.
CharPointerType getCharPointer() const noexcept
Returns the character pointer currently being used to store this string.
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 toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
This is a base class for classes that perform a unit test.
A variant class, that can be used to hold a range of primitive values.
Array< var > * getArray() const noexcept
If this variant holds an array, this provides access to it.
NewLine newLine
A predefined object representing a new-line, which can be written to a string or stream.
wchar_t juce_wchar
A platform-independent 32-bit unicode character type.
bool juce_isfinite(NumericType value) noexcept
The isfinite() method seems to vary between platforms, so this is a platform-independent function for...
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
constexpr int numElementsInArray(Type(&)[N]) noexcept
Handy function for getting the number of elements in a simple const C array.
long long int64
A platform-independent 64-bit integer type.
std::u16string toString(NumberT value)
convert an number to an UTF-16 string