mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 05:24:35 +02:00
Faster JSON entities parser
This commit is contained in:
parent
f5f34e8e7d
commit
c031769c67
4 changed files with 67 additions and 15 deletions
|
@ -9,6 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
#include "OctreeDataUtils.h"
|
#include "OctreeDataUtils.h"
|
||||||
|
#include "OctreeEntitiesFileParser.h"
|
||||||
|
|
||||||
#include <Gzip.h>
|
#include <Gzip.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
|
@ -55,19 +56,30 @@ bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromJSON(QJsonObject root) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromMap(QVariantMap map) {
|
||||||
|
if (map.contains("Id") && map.contains("DataVersion") && map.contains("Version")) {
|
||||||
|
id = map["Id"].toUuid();
|
||||||
|
dataVersion = map["DataVersion"].toInt();
|
||||||
|
version = map["Version"].toInt();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromData(QByteArray data) {
|
bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromData(QByteArray data) {
|
||||||
QByteArray jsonData;
|
QByteArray jsonData;
|
||||||
if (gunzip(data, jsonData)) {
|
if (gunzip(data, jsonData)) {
|
||||||
data = jsonData;
|
data = jsonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto doc = QJsonDocument::fromJson(data);
|
OctreeEntitiesFileParser jsonParser;
|
||||||
if (doc.isNull()) {
|
jsonParser.setEntitiesString(data);
|
||||||
|
QVariantMap entitiesMap;
|
||||||
|
if (!jsonParser.parseEntities(entitiesMap)) {
|
||||||
|
qCritical() << "Can't parse Entities JSON: " << jsonParser.getErrorString().c_str();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto root = doc.object();
|
return readOctreeDataInfoFromMap(entitiesMap);
|
||||||
return readOctreeDataInfoFromJSON(root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads octree file and parses it into a RawOctreeData object.
|
// Reads octree file and parses it into a RawOctreeData object.
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
bool readOctreeDataInfoFromData(QByteArray data);
|
bool readOctreeDataInfoFromData(QByteArray data);
|
||||||
bool readOctreeDataInfoFromFile(QString path);
|
bool readOctreeDataInfoFromFile(QString path);
|
||||||
bool readOctreeDataInfoFromJSON(QJsonObject root);
|
bool readOctreeDataInfoFromJSON(QJsonObject root);
|
||||||
|
bool readOctreeDataInfoFromMap(QVariantMap map);
|
||||||
};
|
};
|
||||||
|
|
||||||
class RawEntityData : public RawOctreeData {
|
class RawEntityData : public RawOctreeData {
|
||||||
|
|
|
@ -189,23 +189,25 @@ bool OctreeEntitiesFileParser::readEntitiesArray(QVariantList& entitiesArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
QJsonParseError parseError;
|
if (nextToken() != '{') {
|
||||||
QByteArray entitiesJson(_entitiesContents.right(_entitiesLength - _position));
|
_errorString = "Entity array item is not an object";
|
||||||
QJsonDocument entity = QJsonDocument::fromJson(entitiesJson, &parseError);
|
return false;
|
||||||
if (parseError.error != QJsonParseError::GarbageAtEnd) {
|
}
|
||||||
_errorString = "Ill-formed entity array";
|
int matchingBrace = findMatchingBrace();
|
||||||
|
if (matchingBrace < 0) {
|
||||||
|
_errorString = "Unterminated entity object";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int entityLength = parseError.offset;
|
|
||||||
entitiesJson.truncate(entityLength);
|
|
||||||
_position += entityLength;
|
|
||||||
|
|
||||||
entity = QJsonDocument::fromJson(entitiesJson, &parseError);
|
QByteArray jsonEntity = _entitiesContents.mid(_position - 1, matchingBrace - _position + 1);
|
||||||
if (parseError.error != QJsonParseError::NoError) {
|
QJsonDocument entity = QJsonDocument::fromJson(jsonEntity);
|
||||||
_errorString = "Entity item parse error";
|
if (entity.isNull()) {
|
||||||
|
_errorString = "Ill-formed entity";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entitiesArray.append(entity.object());
|
entitiesArray.append(entity.object());
|
||||||
|
_position = matchingBrace;
|
||||||
char c = nextToken();
|
char c = nextToken();
|
||||||
if (c == ']') {
|
if (c == ']') {
|
||||||
return true;
|
return true;
|
||||||
|
@ -216,3 +218,37 @@ bool OctreeEntitiesFileParser::readEntitiesArray(QVariantList& entitiesArray) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OctreeEntitiesFileParser::findMatchingBrace() const {
|
||||||
|
int index = _position;
|
||||||
|
int nestCount = 1;
|
||||||
|
while (index < _entitiesLength && nestCount != 0) {
|
||||||
|
switch (_entitiesContents[index++]) {
|
||||||
|
case '{':
|
||||||
|
++nestCount;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '}':
|
||||||
|
--nestCount;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
// Skip string
|
||||||
|
while (index < _entitiesLength) {
|
||||||
|
if (_entitiesContents[index] == '"') {
|
||||||
|
++index;
|
||||||
|
break;
|
||||||
|
} else if (_entitiesContents[index] == '\\' && _entitiesContents[++index] == 'u') {
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nestCount == 0 ? index : -1;
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Parse the top-level of the Models object ourselves - use QJsonDocument for each Entity object.
|
||||||
|
|
||||||
#ifndef hifi_OctreeEntitiesFileParser_h
|
#ifndef hifi_OctreeEntitiesFileParser_h
|
||||||
#define hifi_OctreeEntitiesFileParser_h
|
#define hifi_OctreeEntitiesFileParser_h
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ private:
|
||||||
std::string readString();
|
std::string readString();
|
||||||
int readInteger();
|
int readInteger();
|
||||||
bool readEntitiesArray(QVariantList& entitiesArray);
|
bool readEntitiesArray(QVariantList& entitiesArray);
|
||||||
|
int findMatchingBrace() const;
|
||||||
|
|
||||||
QByteArray _entitiesContents;
|
QByteArray _entitiesContents;
|
||||||
int _position { 0 };
|
int _position { 0 };
|
||||||
|
|
Loading…
Reference in a new issue