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

ircd::js: Add JSON support.

This commit is contained in:
Jason Volk 2016-11-24 18:20:34 -08:00
parent 3e4a9e58f7
commit 0e47468e63
4 changed files with 180 additions and 0 deletions

View file

@ -66,6 +66,7 @@ inline JSVersion version(const char *const &v) { return JS_StringToVersion(v);
#include "native.h"
#include "value.h"
#include "string.h"
#include "json.h"
#include "id.h"
#include "object.h"
#include "has.h"

46
include/ircd/js/json.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#define HAVE_IRCD_JS_JSON_H
namespace ircd {
namespace js {
namespace json {
using closure = std::function<bool (const char16_t *, uint32_t)>;
void stringify(const value::handle_mutable &, const JS::HandleObject &fmtr, const value::handle &sp, const closure &);
void stringify(const value::handle_mutable &, const closure &);
std::u16string stringify(const value::handle_mutable &, const JS::HandleObject &fmtr, const value::handle &sp);
std::u16string stringify(const value::handle_mutable &, const bool &pretty = false);
std::u16string stringify(value &, const bool &pretty = false);
std::u16string stringify(const value &, const bool &pretty = false);
value parse(const char16_t *const &, const size_t &);
value parse(const std::u16string &);
value parse(const std::string &);
value parse(const char *const &);
value parse(const string &);
} // namespace json
} // namespace js
} // namespace ircd

View file

@ -54,6 +54,7 @@ template<lifetime L>
struct object
:root<JSObject *, L>
{
IRCD_OVERLOAD(json)
IRCD_OVERLOAD(array)
IRCD_OVERLOAD(uninitialized)
using handle = object_handle;
@ -80,6 +81,7 @@ struct object
template<class T, lifetime LL> object(const root<T, LL> &);
using root<JSObject *, L>::root;
template<class... args> object(json_t, args&&...);
object(array_t, const size_t &length);
object(const JS::HandleValueArray &);
object(const value<L> &);
@ -166,6 +168,14 @@ object<L>::object(array_t,
throw internal_error("NULL object (array)");
}
template<lifetime L>
template<class... args>
object<L>::object(json_t,
args&&... a)
:object<L>(js::json::parse(std::forward<args>(a)...))
{
}
template<lifetime L>
template<class T,
lifetime LL>

View file

@ -1717,6 +1717,129 @@ ircd::js::c_str(const JSString *const &str)
// ircd/js/value.h
//
///////////////////////////////////////////////////////////////////////////////
//
// ircd/js/json.h
//
namespace ircd {
namespace js {
namespace json {
bool write_callback(const char16_t *, uint32_t, void *) noexcept;
} // namespace json
} // namespace js
} // namespace ircd
ircd::js::value
ircd::js::json::parse(const string &string)
{
value ret;
if(!JS_ParseJSON(*cx, string, &ret))
throw jserror(jserror::pending);
return ret;
}
ircd::js::value
ircd::js::json::parse(const char *const &str)
{
return parse(locale::char16::conv(str));
}
ircd::js::value
ircd::js::json::parse(const std::string &str)
{
return parse(locale::char16::conv(str));
}
ircd::js::value
ircd::js::json::parse(const std::u16string &str)
{
return parse(str.c_str(), str.size());
}
ircd::js::value
ircd::js::json::parse(const char16_t *const &str,
const size_t &size)
{
value ret;
if(!JS_ParseJSON(*cx, str, size, &ret))
throw jserror(jserror::pending);
return ret;
}
std::u16string
ircd::js::json::stringify(const value &val,
const bool &pretty)
{
value v(val);
return stringify(value::handle_mutable(&v), pretty);
}
std::u16string
ircd::js::json::stringify(value &v,
const bool &pretty)
{
return stringify(value::handle_mutable(&v), pretty);
}
std::u16string
ircd::js::json::stringify(const value::handle_mutable &val,
const bool &pretty)
{
const object fmtr;
const string sp(string::literal, pretty? u"\t" : u"");
return stringify(val, fmtr, value(sp));
}
std::u16string
ircd::js::json::stringify(const value::handle_mutable &value,
const JS::HandleObject &fmtr,
const value::handle &sp)
{
std::u16string ret;
stringify(value, fmtr, sp, [&ret]
(const char16_t *const &ptr, const uint &len)
{
ret.assign(ptr, len);
return true;
});
return ret;
}
void
ircd::js::json::stringify(const value::handle_mutable &val,
const closure &cont)
{
value sp;
object fmtr;
return stringify(val, fmtr, sp, cont);
}
void
ircd::js::json::stringify(const value::handle_mutable &value,
const JS::HandleObject &fmtr,
const value::handle &sp,
const closure &cont)
{
if(!JS_Stringify(*cx, value, fmtr, sp, write_callback, const_cast<closure *>(&cont)))
throw jserror(jserror::pending);
}
bool
ircd::js::json::write_callback(const char16_t *const str,
const uint32_t len,
void *const priv)
noexcept
{
const auto &func(*reinterpret_cast<const closure *>(priv));
return func(str, len);
}
///////////////////////////////////////////////////////////////////////////////
//
// ircd/js/native.h