Esempio n. 1
0
void JSONSerializer::SerializeStaticMeshNode(rapidjson::Value& nodeValue,
  const shared_ptr<StaticMeshNode>& node)
{
  const shared_ptr<Mesh>& mesh = node->GetMesh();
  ASSERT(mesh->mRawVertexData != nullptr);
  nodeValue.AddMember("format", mesh->mFormat->mBinaryFormat, *mAllocator);
  nodeValue.AddMember("vertexcount", mesh->mVertexCount, *mAllocator);
  nodeValue.AddMember("indexcount", mesh->mIndexCount, *mAllocator);

  UINT floatCount = mesh->mVertexCount * mesh->mFormat->mStride / sizeof(float);
  float* attribs = reinterpret_cast<float*>(mesh->mRawVertexData);
  rapidjson::Value attribArray(rapidjson::kArrayType);
  for (UINT i = 0; i < floatCount; i++) {
    attribArray.PushBack(double(attribs[i]), *mAllocator);
  }
  nodeValue.AddMember("vertices", attribArray, *mAllocator);

  if (mesh->mIndexCount > 0) {
    rapidjson::Value indexArray(rapidjson::kArrayType);
    for (UINT i = 0; i < mesh->mIndexCount; i++) {
      indexArray.PushBack(UINT(mesh->mIndexData[i]), *mAllocator);
    }
    nodeValue.AddMember("indices", indexArray, *mAllocator);
  }
}
Esempio n. 2
0
        void etcd_packer::pack(const etcd_key_value &etcd_val, rapidjson::Value &json_val, rapidjson::Document &doc) {
            if (0 != etcd_val.create_revision) {
                json_val.AddMember("create_revision", etcd_val.create_revision, doc.GetAllocator());
            }

            if (0 != etcd_val.mod_revision) {
                json_val.AddMember("mod_revision", etcd_val.mod_revision, doc.GetAllocator());
            }

            if (0 != etcd_val.version) {
                json_val.AddMember("version", etcd_val.version, doc.GetAllocator());
            }

            if (0 != etcd_val.lease) {
                json_val.AddMember("lease", etcd_val.lease, doc.GetAllocator());
            }

            if (!etcd_val.key.empty()) {
                pack_base64(json_val, "key", etcd_val.key, doc);
            }

            if (!etcd_val.value.empty()) {
                pack_base64(json_val, "value", etcd_val.value, doc);
            }
        }
Esempio n. 3
0
void
SkillInfo::to_json_value(rapidjson::Document& d, rapidjson::Value& v) const
{
	rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
	v.SetObject();
	// Avoid unused variable warnings
	(void)allocator;

	if (kind_) {
		rapidjson::Value v_kind;
		v_kind.SetString(*kind_, allocator);
		v.AddMember("kind", v_kind, allocator);
	}
	if (apiVersion_) {
		rapidjson::Value v_apiVersion;
		v_apiVersion.SetString(*apiVersion_, allocator);
		v.AddMember("apiVersion", v_apiVersion, allocator);
	}
	if (name_) {
		rapidjson::Value v_name;
		v_name.SetString(*name_, allocator);
		v.AddMember("name", v_name, allocator);
	}

}
Esempio n. 4
0
void jsonifyModule(const Module& module, rapidjson::Value& moduleValue, rapidjson::Document& document){
    moduleValue.SetObject();
    moduleValue.AddMember("name", module.getName().c_str(), document.GetAllocator());
    moduleValue.AddMember("description", module.getDescription().c_str(), document.GetAllocator());
    moduleValue.AddMember("type", module.getType().getName().c_str(), document.GetAllocator());

    //add inputs
    rapidjson::Value inputsValue;
    inputsValue.SetObject();
    for(unsigned int i=0; i<module.getInputSize(); ++i){
        auto inputLink = module.getInput(i);
        auto outputLink = inputLink->getOutputLink();
        //only add connected links
        if(outputLink){
            std::string sourceString = outputLink->getOwner().getName() + "." + outputLink->getModuleOutput().getName();
            rapidjson::Value source(sourceString.c_str(), document.GetAllocator());
            rapidjson::Value inputName(inputLink->getModuleInput().getName().c_str(), document.GetAllocator());
            inputsValue.AddMember(inputName, source, document.GetAllocator());
        } else {
            //add custom unlinked values
            rapidjson::Value vectorValue;
            vectorValue.SetArray();
            auto unlinkedValue = inputLink->getUnlinkedValue();
            for(int j=0; j<unlinkedValue.getSignalType().dimensionality; ++j){
                vectorValue.PushBack(unlinkedValue[j], document.GetAllocator());
            }
            rapidjson::Value inputName(inputLink->getModuleInput().getName().c_str(), document.GetAllocator());
            inputsValue.AddMember(inputName, vectorValue, document.GetAllocator());
        }
    }
    moduleValue.AddMember("inputs", inputsValue, document.GetAllocator());
}
Esempio n. 5
0
void
BlackboardGraph::to_json_value(rapidjson::Document& d, rapidjson::Value& v) const
{
	rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
	v.SetObject();
	// Avoid unused variable warnings
	(void)allocator;

	if (kind_) {
		rapidjson::Value v_kind;
		v_kind.SetString(*kind_, allocator);
		v.AddMember("kind", v_kind, allocator);
	}
	if (apiVersion_) {
		rapidjson::Value v_apiVersion;
		v_apiVersion.SetString(*apiVersion_, allocator);
		v.AddMember("apiVersion", v_apiVersion, allocator);
	}
	if (dotgraph_) {
		rapidjson::Value v_dotgraph;
		v_dotgraph.SetString(*dotgraph_, allocator);
		v.AddMember("dotgraph", v_dotgraph, allocator);
	}

}
Esempio n. 6
0
void addObjectMember(rapidjson::Value &v, const char *name, const JsonSerializable &o,
        rapidjson::Document::AllocatorType &allocator)
{
    if (o.unnamed())
        v.AddMember(name, o.toJson(allocator), allocator);
    else
        v.AddMember(name, o.name().c_str(), allocator);
}
Esempio n. 7
0
void JSONSerializer::SerializeTextureNode(rapidjson::Value& nodeValue,
  const shared_ptr<TextureNode>& node)
{
  shared_ptr<Texture> texture = node->Get();
  ASSERT(texture->mTexelData);
  string b64 = base64_encode((UCHAR*)&(*texture->mTexelData)[0], 
      UINT((*texture->mTexelData).size()));
  nodeValue.AddMember("width", texture->mWidth, *mAllocator);
  nodeValue.AddMember("height", texture->mHeight, *mAllocator);
  nodeValue.AddMember("type", rapidjson::Value(
    EnumMapperA::GetStringFromEnum(TexelTypeMapper, int(texture->mType)), *mAllocator),
    *mAllocator);
  nodeValue.AddMember("base64", b64, *mAllocator);
}
Esempio n. 8
0
void JSONSerializer::SerializeStubNode(
  rapidjson::Value& nodeValue, const shared_ptr<StubNode>& node)
{
  const string& f = node->mSource.Get();
  rapidjson::Value slotValue(rapidjson::kObjectType);
  nodeValue.AddMember("source", f, *mAllocator);
}
Esempio n. 9
0
 void etcd_packer::pack_string(rapidjson::Value &json_val, const char *key, const char *val, rapidjson::Document &doc) {
     rapidjson::Value k;
     rapidjson::Value v;
     k.SetString(key, doc.GetAllocator());
     v.SetString(val, doc.GetAllocator());
     json_val.AddMember(k, v, doc.GetAllocator());
 }
Esempio n. 10
0
void Map::SaveToJSON( rapidjson::Document& document, rapidjson::Value& object )
{
    DebugPrintf( "Saving game state..." );

    // TODO: Add the ID.
    //rapidjson::Value gameIDValue;
    //gameIDValue.SetString( mGameID.c_str(), result.GetAllocator() );
    //result.AddMember( "id", gameIDValue, result.GetAllocator() );

    // Start an array for Units.
    rapidjson::Value unitsArray;
    unitsArray.SetArray();
    DebugPrintf( "Created array!" );

    ForEachUnit( [ &document, &object, &unitsArray ]( Unit* unit )
    {
        // Serialize each Unit.
        rapidjson::Value unitJSON;
        unitJSON.SetObject();

        // Have the Unit serialize its values to JSON.
        unit->SaveToJSON( document, unitJSON );

        // Add each Unit's JSON to the array.
        unitsArray.PushBack( unitJSON, document.GetAllocator() );
    });

    // Add it to the result.
    object.AddMember( "units", unitsArray, document.GetAllocator() );
    DebugPrintf( "Added array!" );
}
/*
 * Gets statistics from lowlevel backend and writes it to "backend" section
 */
static void fill_backend_backend(rapidjson::Value &stat_value,
                                 rapidjson::Document::AllocatorType &allocator,
                                 const struct dnet_backend_io *backend,
                                 const dnet_backend_info *config_backend) {
	char *json_stat = NULL;
	size_t size = 0;
	struct dnet_backend_callbacks *cb = backend->cb;
	if (cb->storage_stat_json) {
		cb->storage_stat_json(cb->command_private, &json_stat, &size);
		if (json_stat && size) {
			rapidjson::Document backend_value(&allocator);
			backend_value.Parse<0>(json_stat);
			auto &config_value = backend_value["config"];
			config_value.AddMember("group", config_backend->group, allocator);
			config_value.AddMember("queue_timeout", config_backend->queue_timeout, allocator);

			rapidjson::Document initial_config(&allocator);
			initial_config.Parse<0>(config_backend->initial_config.c_str());
			backend_value.AddMember("initial_config",
			                        static_cast<rapidjson::Value&>(initial_config),
			                        allocator);

			stat_value.AddMember("backend",
			                     static_cast<rapidjson::Value&>(backend_value),
			                     allocator);
		}
	}

	free(json_stat);
}
/*
 * Fills status section of one backend
 */
static void fill_backend_status(rapidjson::Value &stat_value,
                                rapidjson::Document::AllocatorType &allocator,
                                struct dnet_node *node,
                                dnet_backend_status &status,
                                const dnet_backend_info *config_backend) {
	backend_fill_status_nolock(node, &status, config_backend);

	rapidjson::Value status_value(rapidjson::kObjectType);
	status_value.AddMember("state", status.state, allocator);
	status_value.AddMember("string_state", dnet_backend_state_string(status.state), allocator);
	status_value.AddMember("defrag_state", status.defrag_state, allocator);
	status_value.AddMember("string_defrag_state", dnet_backend_defrag_state_string(status.defrag_state), allocator);

	rapidjson::Value last_start(rapidjson::kObjectType);
	last_start.AddMember("tv_sec", status.last_start.tsec, allocator);
	last_start.AddMember("tv_usec", status.last_start.tnsec / 1000, allocator);
	status_value.AddMember("last_start", last_start, allocator);

	status_value.AddMember("string_last_time", dnet_print_time(&status.last_start), allocator);
	status_value.AddMember("last_start_err", status.last_start_err, allocator);
	status_value.AddMember("read_only", status.read_only == 1, allocator);
	status_value.AddMember("delay", status.delay, allocator);

	stat_value.AddMember("status", status_value, allocator);
}
Esempio n. 13
0
void core::wim::auth_parameters::serialize(rapidjson::Value& _node, rapidjson_allocator& _a) const
{
    _node.AddMember("login", login_, _a);
    _node.AddMember("aimid", aimid_, _a);
    _node.AddMember("atoken", a_token_, _a);
    _node.AddMember("sessionkey", session_key_, _a);
    _node.AddMember("devid", dev_id_, _a);
    _node.AddMember("expiredin", (int64_t)exipired_in_, _a);
    _node.AddMember("timeoffset", (int64_t)time_offset_, _a);
    _node.AddMember("aimsid", aimsid_, _a);
    _node.AddMember("fetchurl", fetch_url_, _a);
    _node.AddMember(settings_need_show_promo, need_promo_, _a);
}
Esempio n. 14
0
void ensure_has_object_mem(rapidjson::Value & _val, rapidjson::Value::StringRefType _name, rapidjson::Document & _doc)
{
	if (!_val.HasMember(_name)) {
		rapidjson::Value v(rapidjson::kObjectType);
		_val.AddMember(_name, v, _doc.GetAllocator());
	}
	RAPIDJSON_ASSERT(_val.FindMember(_name)->value.IsObject());
}
Esempio n. 15
0
        void etcd_packer::pack(const etcd_response_header &etcd_val, rapidjson::Value &json_val, rapidjson::Document &doc) {
            if (0 != etcd_val.cluster_id) {
                json_val.AddMember("cluster_id", etcd_val.cluster_id, doc.GetAllocator());
            }

            if (0 != etcd_val.member_id) {
                json_val.AddMember("member_id", etcd_val.member_id, doc.GetAllocator());
            }

            if (0 != etcd_val.revision) {
                json_val.AddMember("revision", etcd_val.revision, doc.GetAllocator());
            }

            if (0 != etcd_val.raft_term) {
                json_val.AddMember("raft_term", etcd_val.raft_term, doc.GetAllocator());
            }
        }
Esempio n. 16
0
void
tws::geoarray::write(const dimension_t& dim,
                     rapidjson::Value& jdim,
                     rapidjson::Document::AllocatorType& allocator)
{
  if(!jdim.IsObject())
    throw tws::conversion_error() << tws::error_description("dimension metadata must be a JSON object!");

  rapidjson::Value jdim_name(dim.name.c_str(), dim.name.length(), allocator);
  jdim.AddMember("name", jdim_name, allocator);

  rapidjson::Value jdim_dsc(dim.description.c_str(), dim.description.length(), allocator);
  jdim.AddMember("description", jdim_dsc, allocator);

  jdim.AddMember("min_idx", dim.min_idx, allocator);
  jdim.AddMember("max_idx", dim.max_idx, allocator);
}
Esempio n. 17
0
void jsonValueToRapidJSON(JSONValue* value, rapidjson::Value& rapidValue, rapidjson::Document& document) {
	JSONNull* nullValue = dynamic_cast<JSONNull*>(value);
	if (nullValue) {
		rapidValue.SetNull();
		return;
	}
	JSONNumber* numberValue = dynamic_cast<JSONNumber*>(value);
	if (numberValue) {
		if (numberValue->canBeUInt64()) {
			rapidValue.SetUint64(numberValue->getUInt64Value());
		}
		else if (numberValue->canBeInt64()) {
			rapidValue.SetInt64(numberValue->getInt64Value());
		}
		else  {
			rapidValue.SetDouble(numberValue->getDoubleValue());
		}
		return;
	}
	JSONString* stringValue = dynamic_cast<JSONString*>(value);
	if (stringValue) {
		rapidValue.SetString(stringValue->getValue().c_str(), stringValue->getValue().size(), document.GetAllocator());
		return;
	}
	JSONBool* boolValue = dynamic_cast<JSONBool*>(value);
	if (boolValue) {
		rapidValue.SetBool(boolValue->getValue());
		return;
	}
	JSONArray* arrayValue = dynamic_cast<JSONArray*>(value);
	if (arrayValue) {
		rapidValue.SetArray();
		std::vector<JSONValue::ref> values = arrayValue->getValues();
		for (auto & value : values) {
			rapidjson::Value obj;
			jsonValueToRapidJSON(value.get(), obj, document);
			rapidValue.PushBack(obj, document.GetAllocator());
		}
		return;
	}
	JSONObject* objectValue = dynamic_cast<JSONObject*>(value);
	if (objectValue) {
		rapidValue.SetObject();
		typedef std::map<std::string, JSONValue::ref> ValuesMap;
		ValuesMap values = objectValue->getValues();
		for (auto & value : values) {
			rapidjson::Value obj;
			jsonValueToRapidJSON(value.second.get(), obj, document);
			rapidjson::Value key;
			key.SetString(value.first.c_str(), value.first.size(), document.GetAllocator());
			rapidValue.AddMember(key, obj, document.GetAllocator());
		}
		return;
	}
	assert(false);
}
Esempio n. 18
0
        void etcd_packer::pack_base64(rapidjson::Value &json_val, const char *key, const std::string &val, rapidjson::Document &doc) {
            std::string base64_val;
            util::base64_encode(base64_val, val);

            rapidjson::Value k;
            rapidjson::Value v;
            k.SetString(key, doc.GetAllocator());
            v.SetString(base64_val.c_str(), base64_val.size(), doc.GetAllocator());
            json_val.AddMember(k, v, doc.GetAllocator());
        }
Esempio n. 19
0
void IBaseObj::_SerializeFieldStr(int i, rapidjson::Value& json, rapidjson::Document& root)
{
	rapidjson::Value jsonName;
	rapidjson::Value jsonValue;

	jsonName.SetString(GetFieldName(i).c_str(), root.GetAllocator());
	jsonValue.SetString(GetFieldStr(i).c_str());

	json.AddMember(jsonName, jsonValue, root.GetAllocator());
}
Esempio n. 20
0
void add_attributes(rapidxml::xml_node<> *xmlnode, rapidjson::Value &jsvalue, rapidjson::Document::AllocatorType& allocator)
{
    rapidxml::xml_attribute<> *myattr;
    for (myattr = xmlnode->first_attribute(); myattr; myattr = myattr->next_attribute())
    {
        rapidjson::Value jn, jv;
        jn.SetString((std::string("@") + myattr->name()).c_str(), allocator);
        jv.SetString(myattr->value(), allocator);
        jsvalue.AddMember(jn, jv, allocator);
    }
}
/*
 * Fills cache section of one backend
 */
static void fill_backend_cache(rapidjson::Value &stat_value,
                               rapidjson::Document::AllocatorType &allocator,
                               const struct dnet_backend_io *backend) {
	if (backend->cache) {
		ioremap::cache::cache_manager *cache = (ioremap::cache::cache_manager *)backend->cache;
		rapidjson::Document caches_value(&allocator);
		caches_value.Parse<0>(cache->stat_json().c_str());
		stat_value.AddMember("cache",
		                     static_cast<rapidjson::Value&>(caches_value),
		                     allocator);
	}
}
Esempio n. 22
0
    void operator() (const std::vector<std::string> &value) const
    {
        rapidjson::Value result;
        result.SetArray();

        for (auto it = value.begin(); it != value.end(); ++it) {
            rapidjson::Value string;
            string.SetString(it->c_str(), it->size(), *allocator);
            result.PushBack(string, *allocator);
        }

        object->AddMember(name, result, *allocator);
    }
/*
 * Fills all section of all backends
 */
static void backends_stats_json(uint64_t categories,
                                rapidjson::Value &stat_value,
                                rapidjson::Document::AllocatorType &allocator,
                                struct dnet_node *node) {
	const auto &backends = node->config_data->backends->backends;
	for (size_t i = 0; i < backends.size(); ++i) {
		rapidjson::Value backend_stat(rapidjson::kObjectType);
		stat_value.AddMember(std::to_string(static_cast<unsigned long long>(i)).c_str(),
		                     allocator,
		                     backend_stats_json(categories, backend_stat, allocator, node, i),
		                     allocator);
	}
}
Esempio n. 24
0
void xml2json_to_array_form(const char *name, rapidjson::Value &jsvalue, rapidjson::Value &jsvalue_chd, rapidjson::Document::AllocatorType& allocator)
{
    rapidjson::Value jsvalue_target; // target to do some operation
    rapidjson::Value jn;             // this is a must, partially because of the latest version of rapidjson
    jn.SetString(name, allocator);
    jsvalue_target = jsvalue.FindMember(name)->value;
    if(jsvalue_target.IsArray())
    {
        jsvalue_target.PushBack(jsvalue_chd, allocator);
        jsvalue.RemoveMember(name);
        jsvalue.AddMember(jn, jsvalue_target, allocator);
    }
    else
    {
        rapidjson::Value jsvalue_array;
        //jsvalue_array = jsvalue_target;
        jsvalue_array.SetArray();
        jsvalue_array.PushBack(jsvalue_target, allocator);
        jsvalue_array.PushBack(jsvalue_chd, allocator);
        jsvalue.RemoveMember(name);
        jsvalue.AddMember(jn, jsvalue_array, allocator);
    }
}
Esempio n. 25
0
void favorites::serialize(rapidjson::Value& _node, rapidjson_allocator& _a)
{
    rapidjson::Value node_contacts(rapidjson::Type::kArrayType);

    for (auto iter = contacts_.begin(); iter != contacts_.end(); ++iter)
    {
        rapidjson::Value node_contact(rapidjson::Type::kObjectType);

        iter->serialize(node_contact, _a);

        node_contacts.PushBack(node_contact, _a);
    }

    _node.AddMember("favorites", node_contacts, _a);
}
/*
 * Fills io section of one backend
 */
static void fill_backend_io(rapidjson::Value &stat_value,
                            rapidjson::Document::AllocatorType &allocator,
                            const struct dnet_backend_io &backend) {
	rapidjson::Value io_value(rapidjson::kObjectType);

	rapidjson::Value blocking_stat(rapidjson::kObjectType);
	dump_list_stats(blocking_stat, backend.pool.recv_pool.pool->list_stats, allocator);
	io_value.AddMember("blocking", blocking_stat, allocator);

	rapidjson::Value nonblocking_stat(rapidjson::kObjectType);
	dump_list_stats(nonblocking_stat, backend.pool.recv_pool_nb.pool->list_stats, allocator);
	io_value.AddMember("nonblocking", nonblocking_stat, allocator);

	stat_value.AddMember("io", io_value, allocator);
}
/*
 * Fills config with common backend info like config, group id
 */
static void fill_disabled_backend_config(rapidjson::Value &stat_value,
                                         rapidjson::Document::AllocatorType &allocator,
					 const dnet_backend_info &config_backend) {
	rapidjson::Value backend_value(rapidjson::kObjectType);
	rapidjson::Value config_value(rapidjson::kObjectType);

	for (auto it = config_backend.options.begin(); it != config_backend.options.end(); ++it) {
		const dnet_backend_config_entry &entry = *it;

		rapidjson::Value tmp_val(entry.value_template.data(), allocator);
		config_value.AddMember(entry.entry->key, tmp_val, allocator);
	}

	backend_value.AddMember("config", config_value, allocator);
	stat_value.AddMember("backend", backend_value, allocator);
}
/*
 * Fills io section of one backend
 */
static void fill_backend_io(rapidjson::Value &stat_value,
                            rapidjson::Document::AllocatorType &allocator,
                            const struct dnet_backend_io *backend) {
	rapidjson::Value io_value(rapidjson::kObjectType);

	rapidjson::Value blocking_stat(rapidjson::kObjectType);
	auto size = dnet_get_pool_queue_size(backend->pool.recv_pool.pool);
	blocking_stat.AddMember("current_size", size, allocator);
	io_value.AddMember("blocking", blocking_stat, allocator);

	rapidjson::Value nonblocking_stat(rapidjson::kObjectType);
	size = dnet_get_pool_queue_size(backend->pool.recv_pool_nb.pool);
	nonblocking_stat.AddMember("current_size", size, allocator);
	io_value.AddMember("nonblocking", nonblocking_stat, allocator);

	stat_value.AddMember("io", io_value, allocator);
}
Esempio n. 29
0
void ensure_has_array_mem(rapidjson::Value & _val, rapidjson::Value::StringRefType _name, rapidjson::Document & _doc)
{
	if (!_val.HasMember(_name)) {
		rapidjson::Value v(rapidjson::kArrayType);
		_val.AddMember(_name, v, _doc.GetAllocator());
	}
	else {
		rapidjson::Value & _mem_val = _val.FindMember(_name)->value;
		if (!_mem_val.IsArray()) {
			rapidjson::Value tmp;
			tmp = _mem_val;
			_mem_val.SetArray();
			_mem_val.PushBack(tmp, _doc.GetAllocator());
		}
	}
	RAPIDJSON_ASSERT(_val.FindMember(_name)->value.IsArray());
}
/*
 * This function is called to fill in config values read from the config for non-enabled (yet) backends.
 *
 * If config template provides API for serializing parsed config values to json
 * it fills 'backend::config' section otherwise it uses unparsed values from original config
 * and fills 'backend::config_template'.
 *
 * After backend has been enabled, @fill_backend_backend() is called instead.
 */
static void fill_disabled_backend_config(rapidjson::Value &stat_value,
                                         rapidjson::Document::AllocatorType &allocator,
                                         const dnet_backend_info *config_backend) {
	rapidjson::Value backend_value(rapidjson::kObjectType);

	/* If config template provides API for serializing parsed config values to json - use it */
	if (config_backend->config_template.to_json) {
		char *json_stat = NULL;
		size_t size = 0;

		dnet_config_backend config = config_backend->config_template;
		std::vector<char> data(config.size, '\0');
		config.data = data.data();
		config.log = config_backend->log.get();

		for (auto it = config_backend->options.begin(); it != config_backend->options.end(); ++it) {
			const dnet_backend_config_entry &entry = *it;
			entry.entry->callback(&config, entry.entry->key, entry.value_template.data());
		}

		config.to_json(&config, &json_stat, &size);
		if (json_stat && size) {
			rapidjson::Document config_value(&allocator);
			config_value.Parse<0>(json_stat);
			config_value.AddMember("group", config_backend->group, allocator);
			backend_value.AddMember("config",
			                        static_cast<rapidjson::Value&>(config_value),
			                        allocator);
		}
		free(json_stat);
		config.cleanup(&config);
	} else {
		rapidjson::Value config_value(rapidjson::kObjectType);
		for (auto it = config_backend->options.begin(); it != config_backend->options.end(); ++it) {
			const dnet_backend_config_entry &entry = *it;

			rapidjson::Value tmp_val(entry.value_template.data(), allocator);
			config_value.AddMember(entry.entry->key, tmp_val, allocator);
		}
		config_value.AddMember("group", config_backend->group, allocator);
		backend_value.AddMember("config_template", config_value, allocator);
	}

	stat_value.AddMember("backend", backend_value, allocator);
}