Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef JSONPROCESSOR_H
- #define JSONPROCESSOR_H
- #include "Objects/components.h"
- #include <string>
- #include "lib/mio.hpp"
- #include "Objects/jsonmodel.h"
- class JsonProcessor
- {
- public:
- JsonProcessor(std::string path);
- enum Status {
- kInDictionary,
- kInArray,
- kInString
- };
- JsonModel* getModel();
- private:
- std::shared_ptr<Components> ParseJson(int startindex = 0);
- mio::mmap_source mmap;
- std::unique_ptr<JsonModel> m_model;
- };
- #endif // JSONPROCESSOR_H
- // jsonprocessor.cpp
- #include "jsonprocessor.h"
- #include <stack>
- JsonProcessor::JsonProcessor(std::string path) {
- std::error_code error;
- mmap = mio::make_mmap_source(path, error);
- ParseJson();
- }
- std::shared_ptr<Components> JsonProcessor::ParseJson(int startIndex) {
- std::shared_ptr<Components> currentComponent = nullptr;
- std::stack<Status> state;
- std::string key;
- std::string currentString;
- // Stores whether next item is value or not
- bool valueIncoming = false;
- for (int it = startIndex; it < mmap.size(); ++it) {
- char character = mmap[it];
- // Capture characters for string
- if (!state.empty() && state.top() == kInString && character != '"') {
- currentString += character;
- continue;
- }
- switch (character) {
- case '{':
- // Generate child
- if (state.empty()) {
- currentComponent = std::shared_ptr<Components>(new Components(Components::kDictionary));
- m_model = std::unique_ptr<JsonModel>(new JsonModel(currentComponent));
- }
- else {
- currentComponent = std::shared_ptr<Components>(new Components(Components::kDictionary, currentComponent, key));
- }
- // Point parent to child
- if (!state.empty()) {
- if (state.top() == kInDictionary) {
- currentComponent->parent()->addChild(currentComponent);
- }
- }
- state.push(kInDictionary);
- valueIncoming = false;
- break;
- case '}':
- state.pop();
- if (!state.empty()) {
- if (currentComponent == nullptr) { throw std::invalid_argument("Component pointer is null"); }
- // Set current to parent
- currentComponent = std::static_pointer_cast<Components>(std::shared_ptr<Components>(currentComponent->parent()));
- if (state.top() == kInDictionary) { valueIncoming = false; }
- }
- break;
- case '"':
- // If is closing quote
- if (!state.empty() && state.top() == kInString) {
- state.pop();
- valueIncoming = !valueIncoming;
- // If key and value have been captured
- if (!valueIncoming) {
- // Create child to save key-value-pair
- std::shared_ptr<Components> child = std::shared_ptr<Components>(new Components(Components::kString, currentComponent, key));
- child->setValue(currentString);
- child->parent()->addChild(child);
- }
- key = currentString;
- currentString = "";
- }
- else {
- state.push(kInString);
- }
- break;
- }
- }
- return currentComponent;
- }
- JsonModel* JsonProcessor::getModel() {
- return m_model.get();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement