summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2013-02-11 21:07:54 -0500
committerGreg Hudson <ghudson@mit.edu>2013-02-13 15:53:29 -0500
commit80f53c8b2c745e75dc9d22acba63812d8533c133 (patch)
tree258cbc960e82ffacea2e634ebcef4d6a9685ff99 /src/util
parent61116eb28a7520dda1e5febba95ac6ba1e70e6ac (diff)
downloadkrb5-80f53c8b2c745e75dc9d22acba63812d8533c133.tar.gz
krb5-80f53c8b2c745e75dc9d22acba63812d8533c133.tar.xz
krb5-80f53c8b2c745e75dc9d22acba63812d8533c133.zip
Add k5_json_array_fmt and use it in export_cred.c
Add a template-based array constructor for convenient marshalling of structured values as JSON array values. Use it to simplify export_cred.c.
Diffstat (limited to 'src/util')
-rw-r--r--src/util/support/json.c93
-rw-r--r--src/util/support/libkrb5support-fixed.exports2
-rw-r--r--src/util/support/t_json.c26
3 files changed, 121 insertions, 0 deletions
diff --git a/src/util/support/json.c b/src/util/support/json.c
index 5151b84159..e3edffd7cd 100644
--- a/src/util/support/json.c
+++ b/src/util/support/json.c
@@ -167,6 +167,13 @@ k5_json_null_create(k5_json_null *val_out)
return (*val_out == NULL) ? ENOMEM : 0;
}
+int
+k5_json_null_create_val(k5_json_value *val_out)
+{
+ *val_out = alloc_value(&null_type, 0);
+ return (*val_out == NULL) ? ENOMEM : 0;
+}
+
/*** Boolean type ***/
static struct json_type_st bool_type = { K5_JSON_TID_BOOL, "bool", NULL };
@@ -265,6 +272,92 @@ k5_json_array_set(k5_json_array array, size_t idx, k5_json_value val)
array->values[idx] = k5_json_retain(val);
}
+int
+k5_json_array_fmt(k5_json_array *array_out, const char *template, ...)
+{
+ const char *p;
+ va_list ap;
+ const char *cstring;
+ unsigned char *data;
+ size_t len;
+ long long nval;
+ k5_json_array array;
+ k5_json_value val;
+ k5_json_number num;
+ k5_json_string str;
+ k5_json_bool b;
+ k5_json_null null;
+ int truth, ret;
+
+ *array_out = NULL;
+ if (k5_json_array_create(&array))
+ return ENOMEM;
+ va_start(ap, template);
+ for (p = template; *p != '\0'; p++) {
+ switch (*p) {
+ case 'v':
+ val = k5_json_retain(va_arg(ap, k5_json_value));
+ break;
+ case 'n':
+ if (k5_json_null_create(&null))
+ goto err;
+ val = null;
+ break;
+ case 'b':
+ truth = va_arg(ap, int);
+ if (k5_json_bool_create(truth, &b))
+ goto err;
+ val = b;
+ break;
+ case 'i':
+ nval = va_arg(ap, int);
+ if (k5_json_number_create(nval, &num))
+ goto err;
+ val = num;
+ break;
+ case 'L':
+ nval = va_arg(ap, long long);
+ if (k5_json_number_create(nval, &num))
+ goto err;
+ val = num;
+ break;
+ case 's':
+ cstring = va_arg(ap, const char *);
+ if (cstring == NULL) {
+ if (k5_json_null_create(&null))
+ goto err;
+ val = null;
+ } else {
+ if (k5_json_string_create(cstring, &str))
+ goto err;
+ val = str;
+ }
+ break;
+ case 'B':
+ data = va_arg(ap, unsigned char *);
+ len = va_arg(ap, size_t);
+ if (k5_json_string_create_base64(data, len, &str))
+ goto err;
+ val = str;
+ break;
+ default:
+ goto err;
+ }
+ ret = k5_json_array_add(array, val);
+ k5_json_release(val);
+ if (ret)
+ goto err;
+ }
+ va_end(ap);
+ *array_out = array;
+ return 0;
+
+err:
+ va_end(ap);
+ k5_json_release(array);
+ return ENOMEM;
+}
+
/*** Object type (string:value mapping) ***/
struct entry {
diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports
index c813310885..41c8c6b7b6 100644
--- a/src/util/support/libkrb5support-fixed.exports
+++ b/src/util/support/libkrb5support-fixed.exports
@@ -8,6 +8,7 @@ k5_clear_error
k5_set_error_info_callout_fn
k5_json_array_add
k5_json_array_create
+k5_json_array_fmt
k5_json_array_get
k5_json_array_length
k5_json_array_set
@@ -17,6 +18,7 @@ k5_json_decode
k5_json_encode
k5_json_get_tid
k5_json_null_create
+k5_json_null_create_val
k5_json_number_create
k5_json_number_value
k5_json_object_count
diff --git a/src/util/support/t_json.c b/src/util/support/t_json.c
index afb02ee614..040a85a914 100644
--- a/src/util/support/t_json.c
+++ b/src/util/support/t_json.c
@@ -114,6 +114,32 @@ test_array()
k5_json_release(v1);
k5_json_release(v2);
+ k5_json_release(a);
+
+ k5_json_array_fmt(&a, "vnbiLssB", v3, 1, 9, (long long)-6, "def", NULL,
+ (void *)"ghij", (size_t)4);
+ v = k5_json_array_get(a, 0);
+ check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[0] tid");
+ v = k5_json_array_get(a, 1);
+ check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[1] tid");
+ v = k5_json_array_get(a, 2);
+ check(k5_json_get_tid(v) == K5_JSON_TID_BOOL, "fmt array[2] tid");
+ check(k5_json_bool_value(v), "fmt array[2] value");
+ v = k5_json_array_get(a, 3);
+ check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[3] tid");
+ check(k5_json_number_value(v) == 9, "fmt array[3] value");
+ v = k5_json_array_get(a, 4);
+ check(k5_json_get_tid(v) == K5_JSON_TID_NUMBER, "fmt array[4] tid");
+ check(k5_json_number_value(v) == -6, "fmt array[4] value");
+ v = k5_json_array_get(a, 5);
+ check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[5] tid");
+ check(strcmp(k5_json_string_utf8(v), "def") == 0, "fmt array[5] value");
+ v = k5_json_array_get(a, 6);
+ check(k5_json_get_tid(v) == K5_JSON_TID_NULL, "fmt array[6] tid");
+ v = k5_json_array_get(a, 7);
+ check(k5_json_get_tid(v) == K5_JSON_TID_STRING, "fmt array[7] tid");
+ check(strcmp(k5_json_string_utf8(v), "Z2hpag==") == 0,
+ "fmt array[7] value");
k5_json_release(v3);
k5_json_release(a);
}