0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::json: Reorg utility headers; start a tool header.

This commit is contained in:
Jason Volk 2019-02-27 12:01:15 -08:00
parent 9ac64fcff7
commit 33d89755e8
7 changed files with 213 additions and 139 deletions

View file

@ -22,30 +22,13 @@ namespace ircd::json
IRCD_EXCEPTION(error, not_found);
IRCD_EXCEPTION(parse_error, recursion_limit);
struct value;
struct member;
struct string;
struct object;
struct array;
struct vector;
struct iov;
enum type
{
STRING = 0,
OBJECT = 1,
ARRAY = 2,
NUMBER = 3,
LITERAL = 4,
};
enum type type(const string_view &);
enum type type(const string_view &, std::nothrow_t);
string_view reflect(const enum type &);
template<class... T> string_view stringify(const mutable_buffer &&mb, T&&... t);
template<class... T>
string_view stringify(const mutable_buffer &&mb, T&&... t);
}
#include "type.h"
#include "util.h"
#include "string.h"
#include "array.h"
#include "object.h"
#include "vector.h"
@ -55,6 +38,7 @@ namespace ircd::json
#include "strung.h"
#include "tuple/tuple.h"
#include "stack.h"
#include "tool.h"
namespace ircd
{

View file

@ -0,0 +1,52 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// 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 is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_JSON_STRING_H
namespace ircd::json
{
struct string;
}
/// Strong type representing quoted strings in JSON (which may be unquoted
/// automatically when this type is encountered in a tuple etc).
struct ircd::json::string
:string_view
{
string() = default;
string(json::string &&) = default;
string(const json::string &) = default;
string(const string_view &s);
string &operator=(json::string &&) = default;
string &operator=(const json::string &) = default;
string &operator=(const string_view &s);
};
inline
ircd::json::string::string(const string_view &s)
:string_view
{
surrounds(s, '"')?
unquote(s):
s
}
{}
inline ircd::json::string &
ircd::json::string::operator=(const string_view &s)
{
*static_cast<string_view *>(this) = surrounds(s, '"')?
unquote(s):
s;
return *this;
}

19
include/ircd/json/tool.h Normal file
View file

@ -0,0 +1,19 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// 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 is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_JSON_TOOL_H
namespace ircd::json
{
strung remove(const strung &, const string_view &key);
strung remove(const strung &, const size_t &index);
strung insert(const strung &, const member &);
}

47
include/ircd/json/type.h Normal file
View file

@ -0,0 +1,47 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// 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 is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_JSON_TYPE_H
namespace ircd::json
{
enum type :uint8_t;
struct value;
struct member;
struct string;
struct object;
struct array;
struct vector;
struct iov;
using members = std::initializer_list<member>;
enum type type(const string_view &);
enum type type(const string_view &, std::nothrow_t);
string_view reflect(const enum type &);
extern const string_view literal_null;
extern const string_view literal_true;
extern const string_view literal_false;
extern const string_view empty_string;
extern const string_view empty_object;
extern const string_view empty_array;
extern const int64_t undefined_number;
}
enum ircd::json::type
:uint8_t
{
STRING = 0,
OBJECT = 1,
ARRAY = 2,
NUMBER = 3,
LITERAL = 4,
};

View file

@ -11,21 +11,16 @@
#pragma once
#define HAVE_IRCD_JSON_UTIL_H
// This section contains utilities which are useful other parts of ircd::json
// or developers directly. This interface itself (though not its definition)
// has little dependence on other headers in ircd::json. In contrast, a suite
// of rich developer tools which depend on various assets in ircd::json are
// found in tool.h instead.
namespace ircd::json
{
struct string;
template<size_t SIZE> struct buffer;
using name_hash_t = size_t;
using members = std::initializer_list<member>;
extern const string_view literal_null;
extern const string_view literal_true;
extern const string_view literal_false;
extern const string_view empty_string;
extern const string_view empty_object;
extern const string_view empty_array;
extern const int64_t undefined_number;
constexpr name_hash_t name_hash(const string_view name);
constexpr name_hash_t operator ""_(const char *const name, const size_t len);
@ -45,34 +40,6 @@ namespace ircd::json
string_view escape(const mutable_buffer &out, const string_view &in);
}
/// Strong type representing quoted strings in JSON (which may be unquoted
/// automatically when this type is encountered in a tuple etc)
struct ircd::json::string
:string_view
{
string() = default;
string(json::string &&) = default;
string(const json::string &) = default;
string(const string_view &s)
:string_view
{
surrounds(s, '"')?
unquote(s):
s
}{}
string &operator=(json::string &&) = default;
string &operator=(const json::string &) = default;
string &operator=(const string_view &s)
{
*static_cast<string_view *>(this) = surrounds(s, '"')?
unquote(s):
s;
return *this;
}
};
/// Alternative to `json::strung` which uses a fixed array rather than an
/// allocated string as the target.
template<size_t SIZE>

View file

@ -81,7 +81,7 @@ struct ircd::json::value
};
uint64_t len : 57; ///< length indicator
enum type type : 3; ///< json::type indicator
uint64_t type : 3; ///< json::type indicator
uint64_t serial : 1; ///< only *string is used. type indicates JSON
uint64_t alloc : 1; ///< indicates the pointer for type is owned
uint64_t floats : 1; ///< for NUMBER type, integer or floating

View file

@ -400,6 +400,88 @@ ircd::json::input::throws_exceeded()
};
}
///////////////////////////////////////////////////////////////////////////////
//
// json/tool.h
//
ircd::json::strung
ircd::json::insert(const strung &s,
const json::member &m)
{
if(!empty(s) && type(s) != type::OBJECT)
throw type_error
{
"Cannot insert member into JSON of type %s",
reflect(type(s))
};
size_t mctr {0};
thread_local std::array<member, iov::max_size> mb;
for(const object::member &m : object{s})
mb.at(mctr++) = member{m};
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
ircd::json::strung
ircd::json::remove(const strung &s,
const string_view &key)
{
if(empty(s))
return s;
if(type(s) != type::OBJECT)
throw type_error
{
"Cannot remove object member '%s' from JSON of type %s",
key,
reflect(type(s))
};
size_t mctr {0};
thread_local std::array<object::member, iov::max_size> mb;
for(const object::member &m : object{s})
if(m.first != key)
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
ircd::json::strung
ircd::json::remove(const strung &s,
const size_t &idx)
{
if(empty(s))
return s;
if(type(s) != type::ARRAY)
throw type_error
{
"Cannot remove array element [%zu] from JSON of type %s",
idx,
reflect(type(s))
};
size_t mctr{0}, i{0};
thread_local std::array<string_view, iov::max_size> mb;
for(const string_view &m : array{s})
if(i++ != idx)
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
///////////////////////////////////////////////////////////////////////////////
//
// json/stack.h
@ -1762,83 +1844,6 @@ ircd::json::iov::defaults::defaults(iov &iov,
// json/strung.h
//
ircd::json::strung
ircd::json::insert(const strung &s,
const json::member &m)
{
if(!empty(s) && type(s) != type::OBJECT)
throw type_error
{
"Cannot insert member into JSON of type %s",
reflect(type(s))
};
size_t mctr {0};
thread_local std::array<member, iov::max_size> mb;
for(const object::member &m : object{s})
mb.at(mctr++) = member{m};
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
ircd::json::strung
ircd::json::remove(const strung &s,
const string_view &key)
{
if(empty(s))
return s;
if(type(s) != type::OBJECT)
throw type_error
{
"Cannot remove object member '%s' from JSON of type %s",
key,
reflect(type(s))
};
size_t mctr {0};
thread_local std::array<object::member, iov::max_size> mb;
for(const object::member &m : object{s})
if(m.first != key)
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
ircd::json::strung
ircd::json::remove(const strung &s,
const size_t &idx)
{
if(empty(s))
return s;
if(type(s) != type::ARRAY)
throw type_error
{
"Cannot remove array element [%zu] from JSON of type %s",
idx,
reflect(type(s))
};
size_t mctr{0}, i{0};
thread_local std::array<string_view, iov::max_size> mb;
for(const string_view &m : array{s})
if(i++ != idx)
mb.at(mctr++) = m;
return strung
{
mb.data(), mb.data() + mctr
};
}
ircd::json::strung::operator
json::array()
const
@ -3196,7 +3201,7 @@ ircd::json::defined(const value &a)
enum ircd::json::type
ircd::json::type(const value &a)
{
return a.type;
return static_cast<enum json::type>(a.type);
}
//