mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 13:38:02 +02:00
Pasre Entities JSON with our own top-level parser
Use QJsonDocument for each individual entity.
This commit is contained in:
parent
e86d1691ce
commit
f5f34e8e7d
3 changed files with 264 additions and 0 deletions
|
@ -50,6 +50,7 @@
|
||||||
#include "OctreeLogging.h"
|
#include "OctreeLogging.h"
|
||||||
#include "OctreeQueryNode.h"
|
#include "OctreeQueryNode.h"
|
||||||
#include "OctreeUtils.h"
|
#include "OctreeUtils.h"
|
||||||
|
#include "OctreeEntitiesFileParser.h"
|
||||||
|
|
||||||
QVector<QString> PERSIST_EXTENSIONS = {"json", "json.gz"};
|
QVector<QString> PERSIST_EXTENSIONS = {"json", "json.gz"};
|
||||||
|
|
||||||
|
@ -827,12 +828,19 @@ bool Octree::readJSONFromStream(uint64_t streamLength, QDataStream& inputStream,
|
||||||
jsonBuffer += QByteArray(rawData, got);
|
jsonBuffer += QByteArray(rawData, got);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OctreeEntitiesFileParser octreeParser;
|
||||||
|
octreeParser.setEntitiesString(jsonBuffer);
|
||||||
|
QVariantMap asMap;
|
||||||
|
bool parseSuccess = octreeParser.parseEntities(asMap);
|
||||||
|
|
||||||
|
/*
|
||||||
QJsonDocument asDocument = QJsonDocument::fromJson(jsonBuffer);
|
QJsonDocument asDocument = QJsonDocument::fromJson(jsonBuffer);
|
||||||
if (!marketplaceID.isEmpty()) {
|
if (!marketplaceID.isEmpty()) {
|
||||||
asDocument = addMarketplaceIDToDocumentEntities(asDocument, marketplaceID);
|
asDocument = addMarketplaceIDToDocumentEntities(asDocument, marketplaceID);
|
||||||
}
|
}
|
||||||
QVariant asVariant = asDocument.toVariant();
|
QVariant asVariant = asDocument.toVariant();
|
||||||
QVariantMap asMap = asVariant.toMap();
|
QVariantMap asMap = asVariant.toMap();
|
||||||
|
*/
|
||||||
bool success = readFromMap(asMap);
|
bool success = readFromMap(asMap);
|
||||||
delete[] rawData;
|
delete[] rawData;
|
||||||
return success;
|
return success;
|
||||||
|
|
218
libraries/octree/src/OctreeEntitiesFileParser.cpp
Normal file
218
libraries/octree/src/OctreeEntitiesFileParser.cpp
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
//
|
||||||
|
// OctreeEntititesFileParser.cpp
|
||||||
|
// libraries/octree/src
|
||||||
|
//
|
||||||
|
// Created by Simon Walton on Oct 15, 2018.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QVariantList>
|
||||||
|
|
||||||
|
#include "OctreeEntitiesFileParser.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
OctreeEntitiesFileParser::OctreeEntitiesFileParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OctreeEntitiesFileParser::getErrorString() const {
|
||||||
|
std::ostringstream err;
|
||||||
|
if (_errorString.size() != 0) {
|
||||||
|
err << "Error: Line " << _line << ", byte position " << _position << ": " << _errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
return err.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OctreeEntitiesFileParser::setEntitiesString(const QByteArray& entitiesContents) {
|
||||||
|
_entitiesContents = entitiesContents;
|
||||||
|
_entitiesLength = _entitiesContents.length();
|
||||||
|
_position = 0;
|
||||||
|
_line = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OctreeEntitiesFileParser::parseEntities(QVariantMap& parsedEntities) {
|
||||||
|
if (nextToken() != '{') {
|
||||||
|
_errorString = "Text before start of object";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gotDataVersion = false;
|
||||||
|
bool gotEntities = false;
|
||||||
|
bool gotId = false;
|
||||||
|
bool gotVersion = false;
|
||||||
|
|
||||||
|
while (!(gotDataVersion && gotEntities && gotId && gotVersion)) {
|
||||||
|
if (nextToken() != '"') {
|
||||||
|
_errorString = "Incorrect key string";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string key = readString();
|
||||||
|
if (key.size() == 0) {
|
||||||
|
_errorString = "Missing object key";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextToken() != ':') {
|
||||||
|
_errorString = "Ill-formed id/value entry";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == "DataVersion") {
|
||||||
|
if (gotDataVersion) {
|
||||||
|
_errorString = "Duplicate DataVersion entries";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dataVersionValue = readInteger();
|
||||||
|
parsedEntities["DataVersion"] = dataVersionValue;
|
||||||
|
gotDataVersion = true;
|
||||||
|
} else if (key == "Entities") {
|
||||||
|
if (gotEntities) {
|
||||||
|
_errorString = "Duplicate Entities entries";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList entitiesValue;
|
||||||
|
if (!readEntitiesArray(entitiesValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedEntities["Entities"] = entitiesValue;
|
||||||
|
gotEntities = true;
|
||||||
|
} else if (key == "Id") {
|
||||||
|
if (gotId) {
|
||||||
|
_errorString = "Duplicate Id entries";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextToken() != '"') {
|
||||||
|
_errorString = "Invalid Id value";
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
string idString = readString();
|
||||||
|
if (idString.size() == 0) {
|
||||||
|
_errorString = "Invalid Id string";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QUuid idValue = QUuid::fromString(QLatin1String(idString.c_str()) );
|
||||||
|
if (idValue.isNull()) {
|
||||||
|
_errorString = "Id value invalid UUID string: " + idString;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedEntities["Id"] = idValue;
|
||||||
|
gotId = true;
|
||||||
|
} else if (key == "Version") {
|
||||||
|
if (gotVersion) {
|
||||||
|
_errorString = "Duplicate Version entries";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int versionValue = readInteger();
|
||||||
|
parsedEntities["Version"] = versionValue;
|
||||||
|
gotVersion = true;
|
||||||
|
} else {
|
||||||
|
_errorString = "Unrecognized key name: " + key;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotDataVersion && gotEntities && gotId && gotVersion) {
|
||||||
|
break;
|
||||||
|
} else if (nextToken() != ',') {
|
||||||
|
_errorString = "Id/value incorrectly terminated";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextToken() != '}' || nextToken() != -1) {
|
||||||
|
_errorString = "Ill-formed end of object";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OctreeEntitiesFileParser::nextToken() {
|
||||||
|
while (_position < _entitiesLength) {
|
||||||
|
char c = _entitiesContents[_position++];
|
||||||
|
if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (c == '\n') {
|
||||||
|
++_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string OctreeEntitiesFileParser::readString() {
|
||||||
|
string returnString;
|
||||||
|
while (_position < _entitiesLength) {
|
||||||
|
char c = _entitiesContents[_position++];
|
||||||
|
if (c == '"') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
returnString.push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnString;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OctreeEntitiesFileParser::readInteger() {
|
||||||
|
const char* currentPosition = _entitiesContents.constData() + _position;
|
||||||
|
int i = atoi(currentPosition);
|
||||||
|
|
||||||
|
int token;
|
||||||
|
do {
|
||||||
|
token = nextToken();
|
||||||
|
} while (token == '-' || token == '+' || (token >= '0' && token <= '9'));
|
||||||
|
|
||||||
|
--_position;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OctreeEntitiesFileParser::readEntitiesArray(QVariantList& entitiesArray) {
|
||||||
|
if (nextToken() != '[') {
|
||||||
|
_errorString = "Entities entry is not an array";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QByteArray entitiesJson(_entitiesContents.right(_entitiesLength - _position));
|
||||||
|
QJsonDocument entity = QJsonDocument::fromJson(entitiesJson, &parseError);
|
||||||
|
if (parseError.error != QJsonParseError::GarbageAtEnd) {
|
||||||
|
_errorString = "Ill-formed entity array";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int entityLength = parseError.offset;
|
||||||
|
entitiesJson.truncate(entityLength);
|
||||||
|
_position += entityLength;
|
||||||
|
|
||||||
|
entity = QJsonDocument::fromJson(entitiesJson, &parseError);
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
_errorString = "Entity item parse error";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
entitiesArray.append(entity.object());
|
||||||
|
char c = nextToken();
|
||||||
|
if (c == ']') {
|
||||||
|
return true;
|
||||||
|
} else if (c != ',') {
|
||||||
|
_errorString = "Entity array item incorrectly terminated";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
38
libraries/octree/src/OctreeEntitiesFileParser.h
Normal file
38
libraries/octree/src/OctreeEntitiesFileParser.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// OctreeEntititesFileParser.h
|
||||||
|
// libraries/octree/src
|
||||||
|
//
|
||||||
|
// Created by Simon Walton on Oct 15, 2018.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_OctreeEntitiesFileParser_h
|
||||||
|
#define hifi_OctreeEntitiesFileParser_h
|
||||||
|
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
class OctreeEntitiesFileParser {
|
||||||
|
public:
|
||||||
|
OctreeEntitiesFileParser();
|
||||||
|
void setEntitiesString(const QByteArray& entitiesContents);
|
||||||
|
bool parseEntities(QVariantMap& parsedEntities);
|
||||||
|
std::string getErrorString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int nextToken();
|
||||||
|
std::string readString();
|
||||||
|
int readInteger();
|
||||||
|
bool readEntitiesArray(QVariantList& entitiesArray);
|
||||||
|
|
||||||
|
QByteArray _entitiesContents;
|
||||||
|
int _position { 0 };
|
||||||
|
int _line { 1 };
|
||||||
|
int _entitiesLength { 0 };
|
||||||
|
std::string _errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_OctreeEntitiesFileParser_h
|
Loading…
Reference in a new issue