+json_t *
+gss_eap_attr_ctx::jsonRepresentation(void) const
+{
+ json_t *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;
+ }
+
+ for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
+ gss_eap_attr_provider *provider;
+ const char *key;
+
+ provider = m_providers[i];
+ if (provider == NULL)
+ continue; /* provider not initialised */
+
+ key = provider->name();
+ if (key == NULL)
+ continue; /* provider does not have state */
+
+ json_t *source = provider->jsonRepresentation();
+ json_object_set_new(sources, key, source);
+ }
+
+ json_object_set_new(obj, "sources", sources);
+
+ return obj;
+}
+
+/*
+ * Initialize a context from an exported context or name token
+ */
+bool
+gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
+{
+ OM_uint32 major, minor;
+ 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) {
+ ret = initWithJsonObject(obj);
+ json_decref(obj);
+ } else
+ ret = false;
+
+ GSSEAP_FREE(s);
+
+ return ret;
+}
+