Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kvs: return const from cache_entry_get_json() #1269

Merged
merged 6 commits into from Nov 3, 2017
Next

libkvs/treeobj: use const on json_t where approp

Add a new internal function treeobj_peek() which accepts
a const json_t * input parameter, and produces a const json_t
*data output parameter.

Internally, treeobj_peek() calls json_unpack(), which required
the const on the input parameter to be cast away - safe since,
while we use the "o" format specifier to extract the data object,
we put a const on it before we return it to internal callers.

The treeobj_peek() function allows many functions to accept
const json_t * where before they did not.

There was one other place where a const had to be cast away.  In
treeobj_validate(), which now calls treeobj_peek() to access the
const data member, the data const had to be dropped while iterating
over its directory entries with json_object_foreach(), since
json_object_iter() does not accept a const object.  I'm hopeful
that the iterator does not actually modify the object as it seems
self-contained, and this is just an oversight in the jansson API design.

As discussed in #1264
  • Loading branch information...
garlick authored and chu11 committed Nov 1, 2017
commit f9e4b7707b2a274b0f65431557427ba55c36e9b8
@@ -57,12 +57,38 @@ static int treeobj_unpack (json_t *obj, const char **typep, json_t **datap)
return 0;
}

int treeobj_validate (json_t *obj)
static int treeobj_peek (const json_t *obj, const char **typep,
const json_t **datap)
{
json_t *o, *data;
json_t *data;
int version;
const char *type;

if (treeobj_unpack (obj, &type, &data) < 0)
/* N.B. it should be safe to cast away const on 'obj' as long as 'data'
* parameter is not modified. We make 'data' const to ensure that.
*/
if (!obj || json_unpack ((json_t *)obj, "{s:i s:s s:o !}",
"ver", &version,
"type", &type,
"data", &data) < 0
|| version != treeobj_version) {
errno = EINVAL;
return -1;
}
if (typep)
*typep = type;
if (datap)
*datap = data;
return 0;
}

int treeobj_validate (const json_t *obj)
{
const json_t *o;
const json_t *data;
const char *type;

if (treeobj_peek (obj, &type, &data) < 0)
goto inval;
if (!strcmp (type, "valref") || !strcmp (type, "dirref")) {
int i, len;
@@ -80,7 +106,10 @@ int treeobj_validate (json_t *obj)
const char *key;
if (!json_is_object (data))
goto inval;
json_object_foreach (data, key, o) {
/* N.B. it should be safe to cast away const on 'data' as long as
* 'o' is not modified. We make 'o' const to ensure that.
*/
json_object_foreach ((json_t *)data, key, o) {
if (treeobj_validate (o) < 0)
goto inval;
}
@@ -102,39 +131,39 @@ int treeobj_validate (json_t *obj)
return -1;
}

const char *treeobj_get_type (json_t *obj)
const char *treeobj_get_type (const json_t *obj)
{
const char *type;
if (treeobj_unpack (obj, &type, NULL) < 0)
if (!obj || treeobj_peek (obj, &type, NULL) < 0)
return NULL;
return type;
}

bool treeobj_is_symlink (json_t *obj)
bool treeobj_is_symlink (const json_t *obj)
{
const char *type = treeobj_get_type (obj);
return type && !strcmp (type, "symlink");
}

bool treeobj_is_val (json_t *obj)
bool treeobj_is_val (const json_t *obj)
{
const char *type = treeobj_get_type (obj);
return type && !strcmp (type, "val");
}

bool treeobj_is_valref (json_t *obj)
bool treeobj_is_valref (const json_t *obj)
{
const char *type = treeobj_get_type (obj);
return type && !strcmp (type, "valref");
}

bool treeobj_is_dir (json_t *obj)
bool treeobj_is_dir (const json_t *obj)
{
const char *type = treeobj_get_type (obj);
return type && !strcmp (type, "dir");
}

bool treeobj_is_dirref (json_t *obj)
bool treeobj_is_dirref (const json_t *obj)
{
const char *type = treeobj_get_type (obj);
return type && !strcmp (type, "dirref");
@@ -148,14 +177,14 @@ json_t *treeobj_get_data (json_t *obj)
return data;
}

int treeobj_decode_val (json_t *obj, void **dp, int *lp)
int treeobj_decode_val (const json_t *obj, void **dp, int *lp)
{
const char *type, *xdatastr;
json_t *xdata;
const json_t *xdata;
int buflen, len, xlen;
char *data;

if (treeobj_unpack (obj, &type, &xdata) < 0
if (treeobj_peek (obj, &type, &xdata) < 0
|| strcmp (type, "val") != 0) {
errno = EINVAL;
return -1;
@@ -187,13 +216,13 @@ int treeobj_decode_val (json_t *obj, void **dp, int *lp)
return 0;
}

int treeobj_get_count (json_t *obj)
int treeobj_get_count (const json_t *obj)
{
json_t *data;
const json_t *data;
const char *type;
int count = -1;

if (treeobj_unpack (obj, &type, &data) < 0)
if (treeobj_peek (obj, &type, &data) < 0)
goto done;
if (!strcmp (type, "valref") || !strcmp (type, "dirref")) {
count = json_array_size (data);
@@ -302,7 +331,7 @@ json_t *treeobj_copy (json_t *obj)
return cpy;
}

json_t *treeobj_deep_copy (json_t *obj)
json_t *treeobj_deep_copy (const json_t *obj)
{
return json_deep_copy (obj);
}
@@ -334,12 +363,13 @@ int treeobj_append_blobref (json_t *obj, const char *blobref)
return rc;
}

const char *treeobj_get_blobref (json_t *obj, int index)
const char *treeobj_get_blobref (const json_t *obj, int index)
{
json_t *data, *o;
const json_t *data;
json_t *o;
const char *type, *blobref = NULL;

if (treeobj_unpack (obj, &type, &data) < 0
if (treeobj_peek (obj, &type, &data) < 0
|| (strcmp (type, "dirref") != 0
&& strcmp (type, "valref") != 0)) {
errno = EINVAL;
@@ -499,7 +529,7 @@ json_t *treeobj_decodeb (const char *buf, size_t buflen)
return NULL;
}

char *treeobj_encode (json_t *obj)
char *treeobj_encode (const json_t *obj)
{
return json_dumps (obj, JSON_COMPACT|JSON_SORT_KEYS);
}
@@ -21,19 +21,19 @@ json_t *treeobj_create_dirref (const char *blobref);
/* Validate treeobj, recursively.
* Return 0 if valid, -1 with errno = EINVAL if invalid.
*/
int treeobj_validate (json_t *obj);
int treeobj_validate (const json_t *obj);

/* get type (RFC 11 defined strings or NULL on error with errno set).
*/
const char *treeobj_get_type (json_t *obj);
const char *treeobj_get_type (const json_t *obj);

/* Test for a particular type
*/
bool treeobj_is_symlink (json_t *obj);
bool treeobj_is_val (json_t *obj);
bool treeobj_is_valref (json_t *obj);
bool treeobj_is_dir (json_t *obj);
bool treeobj_is_dirref (json_t *obj);
bool treeobj_is_symlink (const json_t *obj);
bool treeobj_is_val (const json_t *obj);
bool treeobj_is_valref (const json_t *obj);
bool treeobj_is_dir (const json_t *obj);
bool treeobj_is_dirref (const json_t *obj);

/* get type-specific value.
* For dirref/valref, this is an array of blobrefs.
@@ -50,15 +50,15 @@ json_t *treeobj_get_data (json_t *obj);
* If len > 0, data will be followed by an extra NULL byte in memory.
* Caller must free returned data.
*/
int treeobj_decode_val (json_t *obj, void **data, int *len);
int treeobj_decode_val (const json_t *obj, void **data, int *len);

/* get type-specific count.
* For dirref/valref, this is the number of blobrefs.
* For directory, this is number of entries
* For symlink or val, this is 1.
* Return count on success, -1 on error with errno = EINVAL.
*/
int treeobj_get_count (json_t *obj);
int treeobj_get_count (const json_t *obj);

/* get/add/remove directory entry
* Get returns JSON object (owned by 'obj', do not destory), NULL on error.
@@ -77,7 +77,7 @@ int treeobj_delete_entry (json_t *obj, const char *name);
json_t *treeobj_copy (json_t *obj);

/* Deep copy a treeobj */
json_t *treeobj_deep_copy (json_t *obj);
json_t *treeobj_deep_copy (const json_t *obj);

/* add blobref to dirref,valref object.
* Return 0 on success, -1 on failure with errno set.
@@ -87,7 +87,7 @@ int treeobj_append_blobref (json_t *obj, const char *blobref);
/* get blobref entry at 'index'.
* Return blobref on success, NULL on failure with errno set.
*/
const char *treeobj_get_blobref (json_t *obj, int index);
const char *treeobj_get_blobref (const json_t *obj, int index);

/* Create valref that refers to 'data', a blob of 'len' bytes using
* 'hashtype' hash algorithm (e.g. "sha1"). If 'maxblob' > 0, split the
@@ -102,7 +102,7 @@ json_t *treeobj_create_valref_buf (const char *hashtype, int maxblob,
*/
json_t *treeobj_decode (const char *buf);
json_t *treeobj_decodeb (const char *buf, size_t buflen);
char *treeobj_encode (json_t *obj);
char *treeobj_encode (const json_t *obj);

#endif /* !_FLUX_KVS_TREEOBJ_H */

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.