18#include <wtf/MathExtras.h>
25#define BEGIN qDebug() << QByteArray(4*indent++, ' ').constData()
27#define DEBUG qDebug() << QByteArray(4*indent, ' ').constData()
29#define BEGIN if (1) ; else qDebug()
30#define END do {} while (0)
31#define DEBUG if (1) ; else qDebug()
88bool JsonParser::eatSpace()
91 const char16_t ch = json->unicode();
104QChar JsonParser::nextToken()
109 switch (
token.unicode()) {
134 qDebug() <<
">>>>> parser begin";
141 if (!parseValue(
v)) {
143 qDebug() <<
">>>>> parser error";
147 error->offset = json - head;
148 error->error = lastError;
155 error->offset = json - head;
156 error->error = lastError;
163 return v->asReturnedValue();
178 BEGIN <<
"parseObject pos=" << json;
206 return o.asReturnedValue();
212bool JsonParser::parseMember(
Object *
o)
214 BEGIN <<
"parseMember";
218 if (!parseString(&
key))
226 if (!parseValue(
val))
231 if (skey.isArrayIndex()) {
232 o->put(skey.asArrayIndex(),
val);
235 o->insertMember(
s,
val);
248 BEGIN <<
"parseArray";
266 if (!parseValue(
val))
287 return array.asReturnedValue();
295bool JsonParser::parseValue(
Value *
val)
297 BEGIN <<
"parse Value" << *json;
299 switch ((json++)->unicode()) {
301 if (
end - json < 3) {
305 if (*json++ == u
'u' &&
309 DEBUG <<
"value: null";
316 if (
end - json < 3) {
320 if (*json++ == u
'r' &&
324 DEBUG <<
"value: true";
331 if (
end - json < 4) {
335 if (*json++ == u
'a' &&
340 DEBUG <<
"value: false";
348 if (!parseString(&
value))
350 DEBUG <<
"value: string";
357 if (
val->isUndefined())
359 DEBUG <<
"value: array";
364 *
val = parseObject();
365 if (
val->isUndefined())
367 DEBUG <<
"value: object";
376 if (!parseNumber(
val))
378 DEBUG <<
"value: number";
403bool JsonParser::parseNumber(
Value *
val)
405 BEGIN <<
"parseNumber" << *json;
411 if (json <
end && *json == u
'-')
415 if (json <
end && *json == u
'0') {
418 while (json < end && *json >= u
'0' && *json <= u
'9')
423 if (json <
end && *json == u
'.') {
426 while (json < end && *json >= u
'0' && *json <= u
'9')
431 if (json <
end && (*json == u
'e' || *json == u
'E')) {
434 if (json <
end && (*json == u
'-' || *json == u
'+'))
436 while (json < end && *json >= u
'0' && *json <= u
'9')
446 if (
ok &&
n < (1<<25) &&
n > -(1<<25)) {
494 if (
d >= u
'0' &&
d <= u
'9')
496 else if (
d >= u
'a' &&
d <= u
'f')
498 else if (
d >= u
'A' &&
d <= u
'F')
511 DEBUG <<
"scan escape";
512 uint escaped = (json++)->unicode();
534 for (
int i = 0;
i < 4; ++
i) {
548bool JsonParser::parseString(
QString *
string)
550 BEGIN <<
"parse string stringPos=" << json;
555 else if (*json == u
'\\') {
561 if (QChar::requiresSurrogates(
ch)) {
562 *
string +=
QChar(QChar::highSurrogate(
ch)) +
QChar(QChar::lowSurrogate(
ch));
567 if (json->unicode() <= 0x1f) {
598 for (
int i = 0;
i < stack.size(); ++
i)
599 if (stack.at(
i)->d() ==
o->d())
629 bool foundProblem()
const {
return m_callDepthRecorder.ee->hasException; }
632 ExecutionEngineCallDepthRecorder<1> m_callDepthRecorder;
639 product.reserve(
length + 2);
643 switch (
c.unicode()) {
666 if (
c.unicode() <= 0x1f) {
668 product += (
c.unicode() > 0xf ? u
'1' : u
'0') +
690 *jsCallData.thisObject =
value;
691 jsCallData.args[0] = v4->newString(
key);
692 value = toJSON->call(jsCallData);
693 if (v4->hasException)
698 if (replacerFunction) {
700 jsCallData.args[0] = v4->newString(
key);
701 jsCallData.args[1] =
value;
703 if (stack.isEmpty()) {
706 *jsCallData.thisObject = holder;
708 *jsCallData.thisObject = stack.top();
711 value = replacerFunction->call(jsCallData);
712 if (v4->hasException)
716 o =
value->asReturnedValue();
721 value = so->d()->string;
728 if (
value->isBoolean())
730 if (
value->isString())
731 return quote(
value->stringValue()->toQString());
733 if (
value->isNumber()) {
734 double d =
value->toNumber();
739 return quote(
v->d()->data().toString());
742 o =
value->asReturnedValue();
745 if (
o->isArrayLike()) {
746 return JA(
o.getPointer());
759 if (!strP.isEmpty()) {
783 if (!propertyListSize) {
789 name =
it.nextPropertyNameAsString(val);
799 for (
int i = 0;
i < propertyListSize; ++
i) {
804 v =
o->get(
s, &exists);
807 QString member = makeMember(
s->toQString(),
v);
813 if (partial.isEmpty()) {
815 }
else if (gap.isEmpty()) {
816 result = u
'{' + partial.join(u
',') + u
'}';
846 v =
a->get(
i, &exists);
858 if (partial.isEmpty()) {
860 }
else if (gap.isEmpty()) {
861 result = u
'[' + partial.join(u
',') + u
']';
864 result =
QLatin1String(
"[\n") + indent + partial.join(separator) + u
'\n' + stepback + u
']';
893 DEBUG <<
"parsing source = " << jtext;
894 JsonParser parser(v4, jtext.constData(), jtext.size());
898 DEBUG <<
"parse error" <<
error.errorString();
913 if (
o->isArrayObject()) {
917 for (
int i = 0;
i < arrayLen; ++
i) {
922 if (!
v->isString()) {
925 for (
int j = 0;
j <
i; ++
j) {
960 if (
value.isString())
962 else if (
value.isDouble())
964 else if (
value.isBool())
966 else if (
value.isArray())
968 else if (
value.isObject())
970 else if (
value.isNull())
978 if (
value.isNumber())
980 else if (
value.isBoolean())
982 else if (
value.isNull())
984 else if (
value.isUndefined())
992 return toJsonArray(
a, visitedObjects);
993 }
else if (Scoped<QV4::Sequence>
a{ scope,
value }) {
994 return toJsonArray(
a, visitedObjects);
995 }
else if (Scoped<QmlListWrapper> lw{ scope,
value }) {
996 return toJsonArray(lw, visitedObjects);
998 return toJsonObject(
o, visitedObjects);
1014 return o.asReturnedValue();
1023 Scope scope(
o->engine());
1038 name =
it.nextPropertyNameAsString(
val);
1057 a->arrayReserve(
size);
1059 for (
int i = 0;
i <
size;
i++)
1061 a->setArrayLengthUnchecked(
size);
1062 return a.asReturnedValue();
1071 Scope scope(
a->engine());
1088 result.append(toJsonValue(
v, visitedObjects));
bool foundProblem() const
CallDepthAndCycleChecker(Stringify *stringify, Object *o)
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString left(qsizetype n) const &
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
qsizetype size() const noexcept
Returns the number of characters in this string.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
QString & insert(qsizetype i, QChar c)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
JsonParser(ExecutionEngine *engine, const QChar *json, int length)
ReturnedValue parse(QJsonParseError *error)
QSet< QString >::iterator it
Scoped< FunctionObject > ScopedFunctionObject
Scoped< String > ScopedString
DBusConnection const char DBusError * error
static QString stringify(const QString &data)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static bool scanEscapeSequence(const char *&json, const char *end, char32_t *ch)
static const int nestingLimit
static bool addHexDigit(char digit, char32_t *result)
constexpr const T & qMin(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QString quote(const QString &str)
static const int nestingLimit
#define CHECK_EXCEPTION()
#define RETURN_UNDEFINED()
#define DEFINE_OBJECT_VTABLE(classname)
manager head(request, this, [this](QRestReply &reply) { if(reply.isSuccess()) })
[6]
\inmodule QtCore\reentrant
\inmodule QtCore \reentrant
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
Heap::Object * newObject()
int safeForAllocLength(qint64 len64)
Symbol * symbol_toStringTag() const
Heap::String * newString(char16_t c)
String * id_empty() const
Heap::ArrayObject * newArrayObject(int count=0)
ReturnedValue throwSyntaxError(const QString &message)
ReturnedValue asReturnedValue() const
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
static QJsonArray toJsonArray(const QV4::Object *o)
static ReturnedValue fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static QJsonObject toJsonObject(const QV4::Object *o)
static ReturnedValue method_stringify(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static QJsonValue toJsonValue(const QV4::Value &value)
Heap::InternalClass * internalClass() const
ExecutionEngine * engine() const
bool put(StringOrSymbol *name, const Value &v, Value *receiver=nullptr)
Value * alloc(qint64 nValues) const =delete
bool hasException() const
static constexpr Value fromInt32(int i)
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
static constexpr Value fromBoolean(bool b)
static constexpr Value undefinedValue()
static Value fromDouble(double d)
static Value fromHeapObject(HeapBasePtr m)
QString toQString() const
static constexpr Value nullValue()
FunctionObject * replacerFunction
QString makeMember(const QString &key, const Value &v)
QV4::String * propertyList
bool stackContains(Object *o)
QString Str(const QString &key, const Value &v)
Stringify(ExecutionEngine *e)