add JSON utility class
authorLuke Howard <lukeh@padl.com>
Mon, 28 Mar 2011 06:07:43 +0000 (17:07 +1100)
committerLuke Howard <lukeh@padl.com>
Mon, 28 Mar 2011 06:07:43 +0000 (17:07 +1100)
Makefile.am
util.h
util_attr.cpp
util_attr.h
util_json.cpp [new file with mode: 0644]
util_json.h [new file with mode: 0644]
util_radius.cpp
util_radius.h
util_saml.h
util_shib.cpp
util_shib.h

index d2c8583..163b9e0 100644 (file)
@@ -76,6 +76,7 @@ mech_eap_la_SOURCES =                         \
        util_cksum.c                            \
        util_cred.c                             \
        util_crypt.c                            \
+       util_json.cpp                           \
        util_krb.c                              \
        util_lucid.c                            \
        util_mech.c                             \
diff --git a/util.h b/util.h
index 31c89f2..5687d52 100644 (file)
--- a/util.h
+++ b/util.h
@@ -845,6 +845,7 @@ gssBufferToKrbData(gss_buffer_t buffer, krb5_data *data)
 }
 #endif
 
+#include "util_json.h"
 #include "util_attr.h"
 #include "util_base64.h"
 #ifdef GSSEAP_ENABLE_REAUTH
index 28e6356..d9c4614 100644 (file)
@@ -276,28 +276,26 @@ gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred,
 }
 
 bool
-gss_eap_attr_ctx::initWithJsonObject(json_t *obj)
+gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
 {
     bool ret = false;
     bool foundSource[ATTR_TYPE_MAX + 1];
     unsigned int type;
-    json_t *sources;
 
     for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
         foundSource[type] = false;
 
-    if (json_integer_value(json_object_get(obj, "version")) != 1)
+    if (obj["version"].integer() != 1)
         return false;
 
-    m_flags = json_integer_value(json_object_get(obj, "flags"));
+    m_flags = obj["flags"].integer();
 
-    sources = json_object_get(obj, "sources");
+    JSONObject sources = obj["sources"];
 
     /* Initialize providers from serialized state */
     for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
         gss_eap_attr_provider *provider;
         const char *key;
-        json_t *source;
 
         if (!providerEnabled(type)) {
             releaseProvider(type);
@@ -309,8 +307,8 @@ gss_eap_attr_ctx::initWithJsonObject(json_t *obj)
         if (key == NULL)
             continue;
 
-        source = json_object_get(sources, key);
-        if (source != NULL &&
+        JSONObject source = sources.get(key);
+        if (!source.isnull() &&
             !provider->initWithJsonObject(this, source)) {
             releaseProvider(type);
             return false;
@@ -340,26 +338,14 @@ gss_eap_attr_ctx::initWithJsonObject(json_t *obj)
     return true;
 }
 
-json_t *
+JSONObject
 gss_eap_attr_ctx::jsonRepresentation(void) const
 {
-    json_t *obj, *sources;
+    JSONObject obj, sources;
     unsigned int i;
 
-    obj = json_object();
-    if (obj == NULL) {
-        throw new std::bad_alloc;
-    }
-
-    /* FIXME check json_object_set_new return value */
-    json_object_set_new(obj, "version", json_integer(1));
-    json_object_set_new(obj, "flags", json_integer(m_flags));
-
-    sources = json_object();
-    if (sources == NULL) {
-        json_decref(obj);
-        throw new std::bad_alloc;
-    }
+    obj.set("version", 1);
+    obj.set("flags", m_flags);
 
     for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
         gss_eap_attr_provider *provider;
@@ -373,11 +359,11 @@ gss_eap_attr_ctx::jsonRepresentation(void) const
         if (key == NULL)
             continue; /* provider does not have state */
 
-        json_t *source = provider->jsonRepresentation();
-        json_object_set_new(sources, key, source);
+        JSONObject source = provider->jsonRepresentation();
+        sources.set(key, source);
     }
 
-    json_object_set_new(obj, "sources", sources);
+    obj.set("sources", sources);
 
     return obj;
 }
@@ -392,16 +378,14 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
     bool ret;
     char *s;
     json_error_t error;
-    json_t *obj;
 
     major = bufferToString(&minor, buffer, &s);
     if (GSS_ERROR(major))
         return false;
 
-    obj = json_loads(s, 0, &error);
-    if (obj != NULL) {
+    JSONObject obj = JSONObject::load(s, 0, &error);
+    if (!obj.isnull()) {
         ret = initWithJsonObject(obj);
-        json_decref(obj);
     } else
         ret = false;
 
@@ -641,32 +625,16 @@ void
 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
 {
     OM_uint32 minor;
-    json_t *obj;
     char *s;
 
-    obj = jsonRepresentation();
-    if (obj == NULL) {
-        std::string error("gss_eap_attr_ctx::exportToBuffer::jsonRepresentation");
-        throw new std::runtime_error(error); /* XXX */
-    }
+    JSONObject obj = jsonRepresentation();
 
-#if 0
-    json_dumpf(obj, stdout, JSON_INDENT(3));
-#endif
+    obj.dump(stdout, JSON_INDENT(3));
 
-    s = json_dumps(obj, JSON_COMPACT);
-    if (s == NULL) {
-        json_decref(obj);
-        std::string error("gss_eap_attr_ctx::exportToBuffer: json_dumps");
-        throw new std::runtime_error(error); /* XXX */
-    }
+    s = obj.dump(JSON_COMPACT);
 
-    if (GSS_ERROR(makeStringBuffer(&minor, s, buffer))) {
-        json_decref(obj);
+    if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
         throw new std::bad_alloc;
-    }
-
-    json_decref(obj);
 }
 
 /*
index 1a427f7..05da947 100644 (file)
@@ -41,7 +41,7 @@
 #include <string>
 #include <new>
 
-#include <jansson.h>
+using namespace gss_eap;
 
 struct gss_eap_attr_provider;
 struct gss_eap_attr_ctx;
@@ -142,15 +142,15 @@ public:
     }
 
     virtual bool initWithJsonObject(const gss_eap_attr_ctx *manager,
-                                    json_t *object GSSEAP_UNUSED)
+                                    JSONObject &object GSSEAP_UNUSED)
     {
         return initWithManager(manager);
     }
 
 
-    virtual json_t *jsonRepresentation(void) const
+    virtual JSONObject jsonRepresentation(void) const
     {
-        return NULL;
+        return JSONObject::null();
     }
 
     virtual time_t getExpiryTime(void) const { return 0; }
@@ -254,8 +254,8 @@ private:
     unsigned int attributePrefixToType(const gss_buffer_t prefix) const;
     gss_buffer_desc attributeTypeToPrefix(unsigned int type) const;
 
-    bool initWithJsonObject(json_t *object);
-    json_t *jsonRepresentation(void) const;
+    bool initWithJsonObject(JSONObject &object);
+    JSONObject jsonRepresentation(void) const;
 
     gss_eap_attr_provider *getPrimaryProvider(void) const;
 
diff --git a/util_json.cpp b/util_json.cpp
new file mode 100644 (file)
index 0000000..9b4b9d1
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2011, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
+ */
+
+/*
+ * JSONObject utilities.
+ */
+
+#include "gssapiP_eap.h"
+
+#include <typeinfo>
+#include <string>
+#include <sstream>
+#include <exception>
+#include <stdexcept>
+#include <new>
+
+#define JSON_INIT(obj) do {                                     \
+        if ((obj) == NULL)                                      \
+            throw new std::bad_alloc;                           \
+        m_obj = (obj);                                          \
+    } while (0)
+
+#define JSON_CHECK_CONTAINER() do {                             \
+        if (!json_is_object(m_obj) && !json_is_array(m_obj)) {  \
+            std::string s("JSONObject object is not a container");   \
+            throw new std::runtime_error(s);                    \
+        }                                                       \
+    } while (0)
+#define JSON_CHECK_OBJECT() do {                                \
+        if (!json_is_object(m_obj)) {                           \
+            std::string s("JSONObject object is not a dictionary");   \
+            throw new std::runtime_error(s);                    \
+        }                                                       \
+    } while (0)
+
+#define JSON_CHECK_ARRAY() do {                                 \
+        if (!json_is_array(m_obj)) {                            \
+            std::string s("JSONObject object is not an array");       \
+            throw new std::runtime_error(s);                    \
+        }                                                       \
+    } while (0)
+
+#define JSON_CHECK(s) do {              \
+        if ((s) != 0)                   \
+            throw new std::bad_alloc;   \
+    } while (0)
+
+JSONObject
+JSONObject::load(const char *input, size_t flags, json_error_t *error)
+{
+    json_t *obj;
+
+    obj = json_loads(input, flags, error);
+
+    return JSONObject(obj, false);
+}
+
+JSONObject
+JSONObject::load(FILE *fp, size_t flags, json_error_t *error)
+{
+    json_t *obj;
+
+    obj = json_loadf(fp, flags, error);
+
+    return JSONObject(obj, false);
+}
+
+char *
+JSONObject::dump(size_t flags) const
+{
+    char *s = json_dumps(m_obj, flags);
+
+    if (s == NULL)
+        throw new std::bad_alloc;
+
+    return s;
+}
+
+void
+JSONObject::dump(FILE *fp, size_t flags) const
+{
+    int r = json_dumpf(m_obj, fp, flags);
+
+    if (r != 0)
+        throw new std::bad_alloc;
+}
+
+size_t
+JSONObject::size(void) const
+{
+    if (json_is_object(m_obj))
+        return json_object_size(m_obj);
+    else if (json_is_array(m_obj))
+        return json_array_size(m_obj);
+    else
+        return 0;
+}
+
+JSONObject::JSONObject(json_t *obj, bool retain)
+{
+    if (retain)
+        json_incref(obj);
+    JSON_INIT(obj);
+}
+
+JSONObject::JSONObject(const char *value)
+{
+    json_t *obj = json_string(value);
+
+    JSON_INIT(obj);
+}
+
+JSONObject::JSONObject(json_int_t value)
+{
+    json_t *obj = json_integer(value);
+
+    JSON_INIT(obj);
+}
+
+JSONObject::JSONObject(double value)
+{
+    json_t *obj = json_real(value);
+
+    JSON_INIT(obj);
+}
+
+JSONObject::JSONObject(bool value)
+{
+    json_t *obj = value ? json_true() : json_false();
+
+    JSON_INIT(obj);
+}
+
+JSONObject::JSONObject(void)
+{
+    json_t *obj = json_object();
+
+    JSON_INIT(obj);
+}
+
+JSONObject
+JSONObject::object(void)
+{
+    return JSONObject();
+}
+
+JSONObject
+JSONObject::null(void)
+{
+    return JSONObject(json_null(), false);
+}
+
+JSONObject
+JSONObject::array(void)
+{
+    return JSONObject(json_array(), false);
+}
+
+void
+JSONObject::set(const char *key, JSONObject &value)
+{
+    JSON_CHECK_OBJECT();
+    JSON_CHECK(json_object_set_new(m_obj, key, value.get()));
+}
+
+void
+JSONObject::set(const char *key, const char *value)
+{
+    JSONObject jobj(value);
+    set(key, jobj);
+}
+
+void
+JSONObject::set(const char *key, json_int_t value)
+{
+    JSONObject jobj(value);
+    set(key, jobj);
+}
+
+void
+JSONObject::del(const char *key)
+{
+    json_object_del(m_obj, key);
+}
+
+JSONObject
+JSONObject::get(const char *key) const
+{
+    json_t *obj;
+
+    obj = json_object_get(m_obj, key);
+    if (obj == NULL)
+        return JSONObject::null();
+
+    return JSONObject(obj, true);
+}
+
+JSONObject
+JSONObject::get(size_t index) const
+{
+    json_t *obj;
+
+    obj = json_array_get(m_obj, index);
+    if (obj == NULL)
+        return JSONObject::null();
+
+    return JSONObject(obj, true);
+}
+
+void
+JSONObject::update(JSONObject &value)
+{
+    JSON_CHECK_OBJECT();
+    json_t *other = value.get();
+    JSON_CHECK(json_object_update(m_obj, other));
+    json_decref(other);
+}
+
+JSONObject
+JSONObject::operator[](size_t index) const
+{
+    return get(index);
+}
+
+JSONObject
+JSONObject::operator[](const char *key) const
+{
+    return get(key);
+}
+
+void
+JSONObject::append(JSONObject &value)
+{
+    JSON_CHECK_ARRAY();
+    JSON_CHECK(json_array_append_new(m_obj, value.get()));
+}
+
+void
+JSONObject::insert(size_t index, JSONObject &value)
+{
+    JSON_CHECK_ARRAY();
+    JSON_CHECK(json_array_insert_new(m_obj, index, value.get()));
+}
+
+void
+JSONObject::remove(size_t index)
+{
+    JSON_CHECK_ARRAY();
+    JSON_CHECK(json_array_remove(m_obj, index));
+}
+
+void
+JSONObject::clear(void)
+{
+    JSON_CHECK_CONTAINER();
+
+    if (json_is_object(m_obj)) {
+        JSON_CHECK(json_object_clear(m_obj));
+    } else if (json_is_array(m_obj)) {
+        JSON_CHECK(json_array_clear(m_obj));
+    }
+}
+
+void
+JSONObject::extend(JSONObject &value)
+{
+    JSON_CHECK_ARRAY();
+    json_t *other = value.get();
+    JSON_CHECK(json_array_extend(m_obj, other));
+    json_decref(other);
+}
+
+const char *
+JSONObject::string(void) const
+{
+    return json_string_value(m_obj);
+}
+
+json_int_t
+JSONObject::integer(void) const
+{
+    return json_integer_value(m_obj);
+}
+
+double
+JSONObject::real(void) const
+{
+    return json_real_value(m_obj);
+}
+
+double
+JSONObject::number(void) const
+{
+    return json_number_value(m_obj);
+}
+
+bool
+JSONObject::isnull(void) const
+{
+    return json_is_null(m_obj);
+}
+
+JSONObject::JSONObject(DDF &ddf)
+{
+    if (ddf.isstruct()) {
+        DDF elem = ddf.first();
+        JSONObject jobj = JSONObject::array();
+
+        while (!elem.isnull()) {
+            JSONObject jtmp(elem);
+            jobj.append(jtmp);
+            elem = ddf.next();
+        }
+    } else if (ddf.islist()) {
+        DDF elem = ddf.first();
+        JSONObject jobj = JSONObject::object();
+
+        while (!elem.isnull()) {
+            JSONObject jtmp(elem);
+            jobj.set(elem.name(), jtmp);
+            elem = ddf.next();
+        }
+    } else if (ddf.isstring()) {
+        JSONObject(ddf.string());
+    } else if (ddf.isint()) {
+        JSONObject((json_int_t)ddf.integer());
+    } else if (ddf.isfloat()) {
+        JSONObject(ddf.floating());
+    } else if (ddf.isempty() || ddf.ispointer()) {
+        JSONObject::object();
+    } else if (ddf.isnull()) {
+        JSONObject::null();
+    }
+
+    std::string s("Unbridgeable DDF object");
+    throw new std::runtime_error(s);
+}
+
+DDF
+JSONObject::ddf(void) const
+{
+    DDF ddf(NULL);
+
+    switch (type()) {
+    case JSON_OBJECT: {
+        JSONIterator iter = iterator();
+
+        do {
+            const char *key = iter.key();
+            DDF value = iter.value().ddf();
+            ddf.add(value.name(key));
+        } while (iter.next());
+        break;
+    }
+    case JSON_ARRAY: {
+        size_t i, nelems = size();
+
+        for (i = 0; i < nelems; i++) {
+            DDF value = get(i).ddf();
+            ddf.add(value);
+        }
+        break;
+    }
+    case JSON_STRING:
+        ddf.string(string());
+        break;
+    case JSON_INTEGER:
+        ddf.integer(integer());
+        break;
+    case JSON_REAL:
+        ddf.floating(real());
+        break;
+    case JSON_TRUE:
+        ddf.integer(1L);
+        break;
+    case JSON_FALSE:
+        ddf.integer(0L);
+        break;
+    case JSON_NULL:
+        break;
+    }
+
+    return DDF(NULL);
+}
+
+JSONIterator::JSONIterator(const JSONObject &obj)
+{
+    m_obj = obj.get();
+    m_iter = json_object_iter(m_obj);
+}
+
+JSONIterator::~JSONIterator(void)
+{
+    json_decref(m_obj);
+}
+
+const char *
+JSONIterator::key(void) const
+{
+    return json_object_iter_key(m_iter);
+}
+
+JSONObject
+JSONIterator::value(void) const
+{
+    return JSONObject(json_object_iter_value(m_iter));
+}
+
+bool
+JSONIterator::next(void)
+{
+    m_iter = json_object_iter_next(m_obj, m_iter);
+    return m_iter != NULL;
+}
diff --git a/util_json.h b/util_json.h
new file mode 100644 (file)
index 0000000..639e7b0
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
+ */
+
+/*
+ * JSON object wrapper with toll-free DDF bridging.
+ */
+
+#ifndef _UTIL_JSON_H_
+#define _UTIL_JSON_H_ 1
+
+#ifdef __cplusplus
+#include <string>
+#include <new>
+
+#include <jansson.h>
+#include <shibsp/remoting/ddf.h>
+
+using namespace shibsp;
+
+namespace gss_eap {
+    class JSONObject;
+
+    class JSONIterator {
+    public:
+        JSONIterator(const JSONObject &obj);
+        ~JSONIterator(void);
+        const char *key(void) const;
+        JSONObject value(void) const;
+        bool next(void);
+
+    private:
+        json_t *m_obj;
+        void *m_iter;
+    };
+
+    class JSONObject {
+    public:
+        static JSONObject load(const char *input, size_t flags, json_error_t *error);
+        static JSONObject load(FILE *, size_t flags, json_error_t *error);
+
+        static JSONObject object(void);
+        static JSONObject array(void);
+        static JSONObject null(void);
+
+        char *dump(size_t flags = 0) const;
+        void dump(FILE *fp, size_t flags = 0) const;
+
+        json_type type(void) const { return json_typeof(m_obj); }
+        size_t size(void) const;
+
+        JSONObject(void);
+        JSONObject(DDF &value);
+        JSONObject(const char *value);
+        JSONObject(json_int_t value);
+        JSONObject(double value);
+        JSONObject(bool value);
+
+        void set(const char *key, JSONObject &value);
+        void set(const char *key, const char *value);
+        void set(const char *key, json_int_t value);
+        void del(const char *key);
+        void update(JSONObject &value);
+        JSONIterator iterator(void) const { return JSONIterator(*this); }
+        JSONObject get(const char *key) const;
+        JSONObject operator[](const char *key) const;
+
+        JSONObject get(size_t index) const;
+        JSONObject operator[](size_t index) const;
+        void append(JSONObject &value);
+        void insert(size_t index, JSONObject &value);
+        void remove(size_t index);
+        void clear(void);
+        void extend(JSONObject &value);
+
+        const char *string(void) const;
+        json_int_t integer(void) const;
+        double real(void) const;
+        double number(void) const;
+        bool isnull(void) const;
+        DDF ddf(void) const;
+
+        ~JSONObject(void)
+        {
+            if (m_obj != NULL)
+                json_decref(m_obj);
+        }
+
+        JSONObject(const JSONObject &obj)
+        {
+            m_obj = json_incref(obj.m_obj);
+        }
+
+        JSONObject& operator=(const JSONObject &obj)
+        {
+            if (this != &obj)
+                set(obj.m_obj);
+            return *this;
+        }
+
+    private:
+        friend class JSONIterator;
+
+        json_t *get(void) const {
+            return m_obj ? json_incref(m_obj) : json_null();
+        }
+
+        void set(json_t *obj) {
+            if (m_obj != obj) {
+                json_decref(m_obj);
+                m_obj = json_incref(m_obj);
+            }
+        }
+
+        JSONObject(json_t *obj, bool retain);
+
+        json_t *m_obj;
+    };
+
+}
+
+#endif /* __cplusplus */
+
+#endif /* _UTIL_JSON_H_ */
index 4e2f6e0..fe43135 100644 (file)
@@ -619,18 +619,10 @@ gssEapRadiusAttrProviderFinalize(OM_uint32 *minor)
     return GSS_S_COMPLETE;
 }
 
-static json_t *
+static JSONObject
 avpToJson(const VALUE_PAIR *vp)
 {
-    json_t *obj = json_object();
-
-    if (obj == NULL) {
-        throw new std::bad_alloc;
-        return NULL;
-    }
-
-    /* FIXME check json_object_set_new return value */
-    json_object_set_new(obj, "type", json_integer(vp->attribute));
+    JSONObject obj;
 
     assert(vp->length <= MAX_STRING_LEN);
 
@@ -638,42 +630,41 @@ avpToJson(const VALUE_PAIR *vp)
     case PW_TYPE_INTEGER:
     case PW_TYPE_IPADDR:
     case PW_TYPE_DATE:
-        json_object_set_new(obj, "value", json_integer(vp->lvalue));
+        obj.set("value", vp->lvalue);
         break;
     case PW_TYPE_STRING:
-        json_object_set_new(obj, "value", json_string(vp->vp_strvalue));
+        obj.set("value", vp->vp_strvalue);
         break;
     default: {
         char *b64;
 
-        if (base64Encode(vp->vp_octets, vp->length, &b64) < 0) {
-            json_decref(obj);
+        if (base64Encode(vp->vp_octets, vp->length, &b64) < 0)
             throw new std::bad_alloc;
-        }
 
-        json_object_set_new(obj, "value", json_string(b64));
+        obj.set("value", b64);
         GSSEAP_FREE(b64);
         break;
     }
     }
 
+    obj.set("type", vp->attribute);
+
     return obj;
 }
 
 static bool
-jsonToAvp(VALUE_PAIR **pVp, json_t *obj)
+jsonToAvp(VALUE_PAIR **pVp, JSONObject &obj)
 {
     VALUE_PAIR *vp = NULL;
     DICT_ATTR *da;
     uint32_t attrid;
-    json_t *type, *value;
 
-    type = json_object_get(obj, "type");
-    value = json_object_get(obj, "value");
-    if (type == NULL || value == NULL)
+    JSONObject type = obj["type"];
+    JSONObject value = obj["value"];
+    if (type.isnull() || value.isnull())
         goto fail;
 
-    attrid = json_integer_value(type);
+    attrid = type.integer();
     da = dict_attrbyvalue(attrid);
     if (da != NULL) {
         vp = pairalloc(da);
@@ -690,10 +681,10 @@ jsonToAvp(VALUE_PAIR **pVp, json_t *obj)
     case PW_TYPE_IPADDR:
     case PW_TYPE_DATE:
         vp->length = 4;
-        vp->lvalue = json_integer_value(value);
+        vp->lvalue = value.integer();
         break;
     case PW_TYPE_STRING: {
-        const char *str = json_string_value(value);
+        const char *str = value.string();
         size_t len;
 
         if (str == NULL || (len = strlen(str)) >= MAX_STRING_LEN)
@@ -705,7 +696,7 @@ jsonToAvp(VALUE_PAIR **pVp, json_t *obj)
     }
     case PW_TYPE_OCTETS:
     default: {
-        const char *str = json_string_value(value);
+        const char *str = value.string();
         int len;
 
         /* this optimization requires base64Decode only understand packed encoding */
@@ -742,19 +733,18 @@ gss_eap_radius_attr_provider::name(void) const
 
 bool
 gss_eap_radius_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx,
-                                                json_t *obj)
+                                                 JSONObject &obj)
 {
     VALUE_PAIR **pNext = &m_vps;
-    json_t *attrs;
-    size_t i;
 
     if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj))
         return false;
 
-    attrs = json_object_get(obj, "attributes");
+    JSONObject attrs = obj["attributes"];
+    size_t nelems = attrs.size();
 
-    for (i = 0; i < json_array_size(attrs); i++) {
-        json_t *attr = json_array_get(attrs, i);
+    for (size_t i = 0; i < nelems; i++) {
+        JSONObject attr = attrs[i];
         VALUE_PAIR *vp;
 
         if (!jsonToAvp(&vp, attr))
@@ -773,27 +763,17 @@ gss_eap_radius_attr_provider::prefix(void) const
     return "urn:ietf:params:gss-eap:radius-avp";
 }
 
-json_t *
+JSONObject
 gss_eap_radius_attr_provider::jsonRepresentation(void) const
 {
-    json_t *obj, *attrs;
-
-    attrs = json_array();
-    if (attrs == NULL)
-        throw new std::bad_alloc;
+    JSONObject obj, attrs = JSONObject::array();
 
     for (VALUE_PAIR *vp = m_vps; vp != NULL; vp = vp->next) {
-        json_t *attr = avpToJson(vp);
-        json_array_append_new(attrs, attr);
-    }
-
-    obj = json_object();
-    if (obj == NULL) {
-        json_decref(attrs);
-        throw new std::bad_alloc;
+        JSONObject attr = avpToJson(vp);
+        attrs.append(attr);
     }
 
-    json_object_set_new(obj, "attributes", attrs);
+    obj.set("attributes", attrs);
 
     return obj;
 }
index 656f1b7..a7878df 100644 (file)
@@ -69,8 +69,8 @@ public:
     const char *prefix(void) const;
     const char *name(void) const;
     bool initWithJsonObject(const gss_eap_attr_ctx *manager,
-                           json_t *obj);
-    json_t *jsonRepresentation(void) const;
+                           JSONObject &obj);
+    JSONObject jsonRepresentation(void) const;
 
     bool getAttribute(uint32_t attribute,
                       int *authenticated,
index 0a14d3e..eeb17e3 100644 (file)
@@ -77,11 +77,11 @@ public:
     const char *prefix(void) const;
     const char *name(void) const { return NULL; }
     bool initWithJsonObject(const gss_eap_attr_ctx *manager GSSEAP_UNUSED,
-                           json_t *object GSSEAP_UNUSED) {
+                           JSONObject &object GSSEAP_UNUSED) {
         return false;
     }
-    json_t *jsonRepresentation(void) const {
-        return NULL;
+    JSONObject jsonRepresentation(void) const {
+        return JSONObject::null();
     }
 
     opensaml::saml2::Assertion *initAssertion(void);
@@ -140,11 +140,11 @@ public:
         return NULL;
     }
     bool initWithJsonObject(const gss_eap_attr_ctx *manager GSSEAP_UNUSED,
-                           json_t *object GSSEAP_UNUSED) {
+                            JSONObject &object GSSEAP_UNUSED) {
         return false;
     }
-    json_t *jsonRepresentation(void) const {
-        return NULL;
+    JSONObject jsonRepresentation(void) const {
+        return JSONObject::null();
     }
 
     bool getAttribute(const gss_buffer_t attr,
index 14757d1..27b03e2 100644 (file)
@@ -396,156 +396,44 @@ gss_eap_shib_attr_provider::name(void) const
     return "local";
 }
 
-static json_t *
-ddfToJson(DDF &ddf)
-{
-    json_t *json;
-
-    if (ddf.isstruct()) {
-        DDF elem = ddf.first();
-        json = json_array();
-        if (json == NULL)
-            throw new std::bad_alloc;
-
-        while (!elem.isnull()) {
-            if (json_array_append_new(json, ddfToJson(elem)) != 0) {
-                json_decref(json);
-                throw new std::bad_alloc;
-            }
-
-            elem = ddf.next();
-        }
-    } else if (ddf.islist()) {
-        DDF elem = ddf.first();
-        json = json_object();
-        if (json == NULL)
-            throw new std::bad_alloc;
-
-        while (!elem.isnull()) {
-            if (json_object_set(json, elem.name(), ddfToJson(elem)) != 0) {
-                json_decref(json);
-                throw new std::bad_alloc;
-            }
-
-            elem = ddf.next();
-        }
-    } else if (ddf.isstring()) {
-        json = json_string(ddf.string());
-    } else if (ddf.isint()) {
-        json = json_integer(ddf.integer());
-    } else if (ddf.isfloat()) {
-        json = json_real(ddf.floating());
-    } else if (ddf.isempty() || ddf.ispointer()) {
-        json = json_object();
-    } else if (ddf.isnull()) {
-        json = json_null();
-    } else {
-        assert(0 && "Invalid DDF object");
-    }
-
-    if (json == NULL)
-        throw new std::bad_alloc;
-
-    return json;
-}
-
-static DDF
-jsonToDdf(json_t *json)
-{
-    DDF ddf(NULL);
-
-    switch (json_typeof(json)) {
-    case JSON_OBJECT: {
-        void *iter = json_object_iter(json);
-
-        while (iter != NULL) {
-            const char *key = json_object_iter_key(iter);
-            json_t *value = json_object_iter_value(iter);
-            ddf.add(jsonToDdf(value).name(key));
-            iter = json_object_iter_next(json, iter);
-        }
-        break;
-    }
-    case JSON_ARRAY: {
-        size_t i;
-
-        for (i = 0; i < json_array_size(json); i++) {
-            DDF value = jsonToDdf(json_array_get(json, i));
-            ddf.add(value);
-        }
-        break;
-    }
-    case JSON_STRING:
-        ddf.string(json_string_value(json));
-        break;
-    case JSON_INTEGER:
-        ddf.integer(json_integer_value(json));
-        break;
-    case JSON_REAL:
-        ddf.floating(json_real_value(json));
-        break;
-    case JSON_TRUE:
-        ddf.integer(1L);
-        break;
-    case JSON_FALSE:
-        ddf.integer(0L);
-        break;
-    case JSON_NULL:
-        break;
-    }
-
-    return ddf;
-}
-
-json_t *
+JSONObject
 gss_eap_shib_attr_provider::jsonRepresentation(void) const
 {
-    json_t *obj, *attrs;
+    JSONObject obj;
 
-    obj = json_object();
-    if (obj == NULL)
-        throw new std::bad_alloc;
+    obj.set("authenticated", m_authenticated);
 
-    /* FIXME check json_object_set_new return value */
-    json_object_set_new(obj, "authenticated", json_integer(m_authenticated));
-
-    attrs = json_array();
-    if (attrs == NULL) {
-        json_decref(obj);
-        throw new std::bad_alloc;
-    }
+    JSONObject attrs = JSONObject::array();
 
     for (vector<Attribute*>::const_iterator a = m_attributes.begin();
          a != m_attributes.end(); ++a) {
         DDF attr = (*a)->marshall();
-        /* FIXME check json_array_append_new return value */
-        json_array_append_new(attrs, ddfToJson(attr));
+        JSONObject jobj(attr);
+        attrs.append(jobj);
     }
 
-    json_object_set_new(obj, "attributes", attrs);
+    obj.set("attributes", attrs);
 
     return obj;
 }
 
 bool
 gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx,
-                                              json_t *obj)
+                                               JSONObject &obj)
 {
-    size_t i;
-    json_t *attrs;
-
     if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj))
         return false;
 
     assert(m_authenticated == false);
     assert(m_attributes.size() == 0);
 
-    m_authenticated = json_integer_value(json_object_get(obj, "authenticated"));
+    m_authenticated = obj["authenticated"].integer();
 
-    attrs = json_object_get(obj, "attributes");
+    JSONObject attrs = obj["attributes"];
+    size_t nelems = attrs.size();
 
-    for (i = 0; i < json_array_size(attrs); i++) {
-        DDF attr = jsonToDdf(json_array_get(attrs, i));
+    for (size_t i = 0; i < nelems; i++) {
+        DDF attr = attrs.get(i).ddf();
         Attribute *attribute = Attribute::unmarshall(attr);
         m_attributes.push_back(attribute);
     }
index 7cacd66..7fc9e6d 100644 (file)
@@ -79,8 +79,8 @@ public:
     const char *prefix(void) const;
     const char *name(void) const;
     bool initWithJsonObject(const gss_eap_attr_ctx *manager,
-                           json_t *obj);
-    json_t *jsonRepresentation(void) const;
+                            JSONObject &obj);
+    JSONObject jsonRepresentation(void) const;
 
     static bool init(void);
     static void finalize(void);