Skip to content

Commit

Permalink
curl_json plugin: Use the "number" callback of libyajl.
Browse files Browse the repository at this point in the history
The "integer" callback only works with "long"s, which are 32bit on
x86 and other 32bit architectures. The "number" callback gets the raw
string for us to parse ourselves – honoring the data source type in the
process.

The "integer" and "double" callbacks have been removed, since they are not
used if the "number" callback is present.
  • Loading branch information
octo committed Jul 13, 2010
1 parent 731838e commit b16fd65
Showing 1 changed file with 44 additions and 46 deletions.
90 changes: 44 additions & 46 deletions src/curl_json.c
@@ -1,7 +1,7 @@
/**
* collectd - src/curl_json.c
* Copyright (C) 2009 Doug MacEachern
* Copyright (C) 2006-2009 Florian octo Forster
* Copyright (C) 2006-2010 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand Down Expand Up @@ -130,59 +130,57 @@ static int cj_get_type (cj_key_t *key)
}

/* yajl callbacks */
static int cj_cb_integer (void *ctx, long val)
#define CJ_CB_ABORT 0
#define CJ_CB_CONTINUE 1

/* "number" may not be null terminated, so copy it into a buffer before
* parsing. */
static int cj_cb_number (void *ctx,
const char *number, unsigned int number_len)
{
char buffer[number_len + 1];

cj_t *db = (cj_t *)ctx;
cj_key_t *key = db->state[db->depth].key;
char *endptr;
value_t vt;
int type;

if (key != NULL)
{
value_t vt;
int type;
if (key == NULL)
return (CJ_CB_CONTINUE);

type = cj_get_type (key);
if (type == DS_TYPE_COUNTER)
vt.counter = (counter_t) val;
else if (type == DS_TYPE_GAUGE)
vt.gauge = (gauge_t) val;
else if (type == DS_TYPE_DERIVE)
vt.derive = (derive_t) val;
else if (type == DS_TYPE_ABSOLUTE)
vt.absolute = (absolute_t) val;
else
return 0;
memcpy (buffer, number, number_len);
buffer[sizeof (buffer) - 1] = 0;

cj_submit (db, key, &vt);
}
return 1;
}
type = cj_get_type (key);

static int cj_cb_double (void *ctx, double val)
{
cj_t *db = (cj_t *)ctx;
cj_key_t *key = db->state[db->depth].key;
endptr = NULL;
errno = 0;

if (key != NULL)
if (type == DS_TYPE_COUNTER)
vt.counter = (counter_t) strtoull (buffer, &endptr, /* base = */ 0);
else if (type == DS_TYPE_GAUGE)
vt.gauge = (gauge_t) strtod (buffer, &endptr);
else if (type == DS_TYPE_DERIVE)
vt.derive = (derive_t) strtoll (buffer, &endptr, /* base = */ 0);
else if (type == DS_TYPE_ABSOLUTE)
vt.absolute = (absolute_t) strtoull (buffer, &endptr, /* base = */ 0);
else
{
value_t vt;
int type;

type = cj_get_type (key);
if (type == DS_TYPE_COUNTER)
vt.counter = (counter_t) val;
else if (type == DS_TYPE_GAUGE)
vt.gauge = (gauge_t) val;
else if (type == DS_TYPE_DERIVE)
vt.derive = (derive_t) val;
else if (type == DS_TYPE_ABSOLUTE)
vt.absolute = (absolute_t) val;
else
return 0;
ERROR ("curl_json plugin: Unknown data source type: \"%s\"", key->type);
return (CJ_CB_ABORT);
}

cj_submit (db, key, &vt);
if ((endptr == &buffer[0]) || (errno != 0))
{
NOTICE ("curl_json plugin: Overflow while parsing number. "
"Ignoring this value.");
return (CJ_CB_CONTINUE);
}
return 1;
}

cj_submit (db, key, &vt);
return (CJ_CB_CONTINUE);
} /* int cj_cb_number */

static int cj_cb_map_key (void *ctx, const unsigned char *val,
unsigned int len)
Expand Down Expand Up @@ -287,9 +285,9 @@ static int cj_cb_end_array (void * ctx)
static yajl_callbacks ycallbacks = {
NULL, /* null */
NULL, /* boolean */
cj_cb_integer,
cj_cb_double,
NULL, /* number */
NULL, /* integer */
NULL, /* double */
cj_cb_number,
cj_cb_string,
cj_cb_start_map,
cj_cb_map_key,
Expand Down

0 comments on commit b16fd65

Please sign in to comment.