view C++/Json.cpp @ 269:44dcc198bf0c

Dynlib (test): Add dl library for Linux
author David Demelier <markand@malikania.fr>
date Fri, 17 Oct 2014 14:20:00 +0200
parents 777bc3cb665a
children ed3cc10761e4
line wrap: on
line source

/*
 * Json.cpp -- jansson C++11 wrapper
 *
 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "Json.h"

Json Json::fromString(const std::string &data, int flags)
{
	return from(json_loads, data.c_str(), flags);
}

Json Json::fromFile(const std::string &path, int flags)
{
	return from(json_load_file, path.c_str(), flags);
}

Json::Json()
	: m_handle(json_object(), json_decref)
{
}

Json::Json(bool value)
	: m_handle(json_boolean(value), json_decref)
{
}

Json::Json(int value)
	: m_handle(json_integer(value), json_decref)
{
}

Json::Json(double value)
	: m_handle(json_real(value), json_decref)
{
}

Json::Json(const std::string &value)
	: m_handle(json_string(value.c_str()), json_decref)
{
}

Json::Json(const Json &json)
	: m_handle(json_deep_copy(json.m_handle.get()), json_decref)
	, m_list(json.m_list)
	, m_map(json.m_map)
{
}

Json::Json(Json &&value)
	: m_handle(value.m_handle.release(), json_decref)
	, m_list(std::move(value.m_list))
	, m_map(std::move(value.m_map))
{
}

Json::Json(std::initializer_list<Json> list)
	: m_handle(json_array(), json_decref)
{
	m_list.reserve(list.size());

	for (const auto &v : list) {
		m_list.push_back(v);
		json_array_append(m_handle.get(), m_list.back().m_handle.get());
	}
}

Json &Json::operator=(const Json &json)
{
	m_handle = Handle(json.m_handle.get(), json_decref);
	m_list = json.m_list;
	m_map = json.m_map;

	return *this;
}

Json &Json::operator=(Json &&value)
{
	m_handle = Handle(value.m_handle.release(), json_decref);
	m_list = std::move(value.m_list);
	m_map = std::move(value.m_map);

	return *this;
}

int Json::typeOf() const
{
	return json_typeof(m_handle.get());
}

bool Json::isObject() const
{
	return json_is_object(m_handle.get()) != 0;
}

bool Json::isArray() const
{
	return json_is_array(m_handle.get()) != 0;
}

bool Json::isString() const
{
	return json_is_string(m_handle.get()) != 0;
}

bool Json::isReal() const
{
	return json_is_real(m_handle.get()) != 0;
}

bool Json::isTrue() const
{
	return json_is_true(m_handle.get()) != 0;
}

bool Json::isFalse() const
{
	return json_is_true(m_handle.get()) != 0;
}

bool Json::isNull() const
{
	return json_is_null(m_handle.get()) != 0;
}

bool Json::isNumber() const
{
	return json_is_number(m_handle.get()) != 0;
}

bool Json::isInteger() const
{
	return json_is_integer(m_handle.get()) != 0;
}

bool Json::isBoolean() const
{
	return json_is_boolean(m_handle.get()) != 0;
}

unsigned Json::size() const noexcept
{
	return m_list.size();
}

void Json::append(const Json &value)
{
	m_list.push_back(value);
	json_array_append(m_handle.get(), m_list.back().m_handle.get());
}

void Json::append(Json &&value)
{
	m_list.push_back(std::move(value));
	json_array_append(m_handle.get(), m_list.back().m_handle.get());
}

void Json::insert(const Json &value, int index)
{
	m_list.insert(m_list.begin() + index, value);
	json_array_insert(m_handle.get(), index, m_list[index].m_handle.get());
}

void Json::insert(Json &&value, int index)
{
	m_list.insert(m_list.begin() + index, std::move(value));
	json_array_insert(m_handle.get(), index, m_list[index].m_handle.get());
}

void Json::set(const Json &value, const std::string &name)
{
	m_map[name] = value;
	json_object_set(m_handle.get(), name.c_str(), m_map[name].m_handle.get());
}

void Json::set(Json &&value, const std::string &name)
{
	m_map[name] = std::move(value);
	json_object_set(m_handle.get(), name.c_str(), m_map[name].m_handle.get());
}

std::string Json::toString() const
{
	auto value = json_string_value(m_handle.get());

	return (value == nullptr) ? "" : value;
}

int Json::toInteger() const noexcept
{
	return json_integer_value(m_handle.get());
}

double Json::toReal() const noexcept
{
	return json_real_value(m_handle.get());
}

std::string Json::dump(int flags)
{
	auto v = json_dumps(m_handle.get(), flags);

	if (v == nullptr)
		throw std::runtime_error("failed to dump");

	return std::string(v);
}

void Json::dump(const std::string &path, int flags)
{
	if (json_dump_file(m_handle.get(), path.c_str(), flags) < 0)
		throw std::runtime_error("failed to dump");
}

Json &Json::operator[](int index)
{
	if (!isArray())
		throw std::invalid_argument("not an array");

	if (index >= m_list.size())
		throw std::out_of_range("invalid index");

	return m_list[index];
}

const Json &Json::operator[](int index) const
{
	if (!isArray())
		throw std::invalid_argument("not an array");

	if (index >= m_list.size())
		throw std::out_of_range("invalid index");

	return m_list[index];
}

Json &Json::operator[](const std::string &name)
{
	if (!isObject())
		throw std::invalid_argument("not an object");

	if (m_map.count(name) == 0)
		throw std::out_of_range("invalid key");

	return m_map[name];
}

const Json &Json::operator[](const std::string &name) const
{
	if (!isObject())
		throw std::invalid_argument("not an object");

	if (m_map.count(name) == 0)
		throw std::out_of_range("invalid key");

	return m_map.at(name);
}

bool operator==(const Json &j1, const Json &j2)
{
	return json_equal(j1.m_handle.get(), j2.m_handle.get()) != 0;
}