Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions include/sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ typedef enum {
SENTRY_VALUE_TYPE_NULL,
SENTRY_VALUE_TYPE_BOOL,
SENTRY_VALUE_TYPE_INT32,
SENTRY_VALUE_TYPE_INT64,
SENTRY_VALUE_TYPE_UINT64,
SENTRY_VALUE_TYPE_DOUBLE,
SENTRY_VALUE_TYPE_STRING,
SENTRY_VALUE_TYPE_LIST,
Expand Down Expand Up @@ -200,6 +202,16 @@ SENTRY_API sentry_value_t sentry_value_new_null(void);
*/
SENTRY_API sentry_value_t sentry_value_new_int32(int32_t value);

/**
* Creates a new 64-bit signed integer value.
*/
SENTRY_API sentry_value_t sentry_value_new_int64(int64_t value);

/**
* Creates a new 64-bit unsigned integer value.
*/
SENTRY_API sentry_value_t sentry_value_new_uint64(uint64_t value);

/**
* Creates a new double value.
*/
Expand Down Expand Up @@ -338,6 +350,16 @@ SENTRY_API size_t sentry_value_get_length(sentry_value_t value);
*/
SENTRY_API int32_t sentry_value_as_int32(sentry_value_t value);

/**
* Converts a value into a 64 bit signed integer.
*/
SENTRY_API int64_t sentry_value_as_int64(sentry_value_t value);

/**
* Converts a value into a 64 bit unsigned integer.
*/
SENTRY_API uint64_t sentry_value_as_uint64(sentry_value_t value);

/**
* Converts a value into a double value.
*/
Expand Down
20 changes: 20 additions & 0 deletions src/sentry_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,26 @@ sentry__jsonwriter_write_int32(sentry_jsonwriter_t *jw, int32_t val)
}
}

void
sentry__jsonwriter_write_int64(sentry_jsonwriter_t *jw, int64_t val)
{
if (can_write_item(jw)) {
char buf[24];
snprintf(buf, sizeof(buf), "%" PRId64, val);
write_str(jw, buf);
}
}

void
sentry__jsonwriter_write_uint64(sentry_jsonwriter_t *jw, uint64_t val)
{
if (can_write_item(jw)) {
char buf[24];
snprintf(buf, sizeof(buf), "%" PRIu64, val);
write_str(jw, buf);
}
}

void
sentry__jsonwriter_write_double(sentry_jsonwriter_t *jw, double val)
{
Expand Down
10 changes: 10 additions & 0 deletions src/sentry_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ void sentry__jsonwriter_write_bool(sentry_jsonwriter_t *jw, bool val);
*/
void sentry__jsonwriter_write_int32(sentry_jsonwriter_t *jw, int32_t val);

/**
* Write a 64-bit signed integer, encoded as JSON number.
*/
void sentry__jsonwriter_write_int64(sentry_jsonwriter_t *jw, int64_t val);

/**
* Write a 64-bit unsigned integer, encoded as JSON number.
*/
void sentry__jsonwriter_write_uint64(sentry_jsonwriter_t *jw, uint64_t val);

/**
* Write a 64-bit float, encoded as JSON number.
*/
Expand Down
155 changes: 139 additions & 16 deletions src/sentry_value.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,17 @@
#define THING_TYPE_OBJECT 1
#define THING_TYPE_STRING 2
#define THING_TYPE_DOUBLE 3
#define THING_TYPE_INT64 4
#define THING_TYPE_UINT64 5

/* internal value helpers */

typedef struct {
union {
void *_ptr;
double _double;
int64_t _i64;
uint64_t _u64;
} payload;
long refcount;
uint8_t type;
Expand Down Expand Up @@ -326,6 +330,38 @@ sentry_value_new_double(double value)
return rv;
}

sentry_value_t
sentry_value_new_int64(int64_t value)
{
thing_t *thing = sentry_malloc(sizeof(thing_t));
if (!thing) {
return sentry_value_new_null();
}
thing->payload._i64 = value;
thing->refcount = 1;
thing->type = (uint8_t)(THING_TYPE_INT64 | THING_TYPE_FROZEN);

sentry_value_t rv;
rv._bits = (uint64_t)(size_t)thing;
return rv;
}

sentry_value_t
sentry_value_new_uint64(uint64_t value)
{
thing_t *thing = sentry_malloc(sizeof(thing_t));
if (!thing) {
return sentry_value_new_null();
}
thing->payload._u64 = value;
thing->refcount = 1;
thing->type = (uint8_t)(THING_TYPE_UINT64 | THING_TYPE_FROZEN);

sentry_value_t rv;
rv._bits = (uint64_t)(size_t)thing;
return rv;
}

sentry_value_t
sentry_value_new_bool(int value)
{
Expand Down Expand Up @@ -490,6 +526,10 @@ sentry_value_get_type(sentry_value_t value)
return SENTRY_VALUE_TYPE_OBJECT;
case THING_TYPE_DOUBLE:
return SENTRY_VALUE_TYPE_DOUBLE;
case THING_TYPE_INT64:
return SENTRY_VALUE_TYPE_INT64;
case THING_TYPE_UINT64:
return SENTRY_VALUE_TYPE_UINT64;
}
UNREACHABLE("invalid thing type");
} else if ((value._bits & TAG_MASK) == TAG_CONST) {
Expand Down Expand Up @@ -626,6 +666,18 @@ sentry__value_as_uuid(sentry_value_t value)
char *
sentry__value_stringify(sentry_value_t value)
{
#define STRINGIFY_NUMERIC(fmt, value_fn) \
do { \
char buf[24]; \
size_t written \
= (size_t)sentry__snprintf_c(buf, sizeof(buf), fmt, value_fn); \
if (written >= sizeof(buf)) { \
return sentry__string_clone(""); \
} \
buf[written] = '\0'; \
return sentry__string_clone(buf); \
} while (0)

switch (sentry_value_get_type(value)) {
case SENTRY_VALUE_TYPE_LIST:
case SENTRY_VALUE_TYPE_OBJECT:
Expand All @@ -636,19 +688,17 @@ sentry__value_stringify(sentry_value_t value)
sentry_value_is_true(value) ? "true" : "false");
case SENTRY_VALUE_TYPE_STRING:
return sentry__string_clone(sentry_value_as_string(value));
case SENTRY_VALUE_TYPE_INT64:
STRINGIFY_NUMERIC("%" PRIi64, sentry_value_as_int64(value));
case SENTRY_VALUE_TYPE_UINT64:
STRINGIFY_NUMERIC("%" PRIi64, sentry_value_as_uint64(value));
case SENTRY_VALUE_TYPE_INT32:
case SENTRY_VALUE_TYPE_DOUBLE:
default: {
char buf[24];
size_t written = (size_t)sentry__snprintf_c(
buf, sizeof(buf), "%g", sentry_value_as_double(value));
if (written >= sizeof(buf)) {
return sentry__string_clone("");
}
buf[written] = '\0';
return sentry__string_clone(buf);
}
default:
STRINGIFY_NUMERIC("%g", sentry_value_as_double(value));
}

#undef STRINGIFY_NUMERIC
}

sentry_value_t
Expand Down Expand Up @@ -679,6 +729,8 @@ sentry__value_clone(sentry_value_t value)
}
case THING_TYPE_STRING:
case THING_TYPE_DOUBLE:
case THING_TYPE_INT64:
case THING_TYPE_UINT64:
sentry_value_incref(value);
return value;
default:
Expand Down Expand Up @@ -873,9 +925,18 @@ sentry_value_as_int32(sentry_value_t value)
{
if ((value._bits & TAG_MASK) == TAG_INT32) {
return (int32_t)((int64_t)value._bits >> 32);
} else {
return 0;
}
const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_INT64) {
SENTRY_WARN("Cannot convert int64 into int32, returning 0");
}
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
SENTRY_WARN("Cannot convert uint64 into int32, returning 0");
}
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
SENTRY_WARN("Cannot convert double into int32, returning 0");
}
return 0;
}

double
Expand All @@ -888,9 +949,56 @@ sentry_value_as_double(sentry_value_t value)
const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
return thing->payload._double;
} else {
return (double)NAN;
}
if (thing && thing_get_type(thing) == THING_TYPE_INT64) {
SENTRY_WARN("Cannot convert int64 into double, returning NAN");
}
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
SENTRY_WARN("Cannot convert uint64 into double, returning NAN");
}

return (double)NAN;
}

int64_t
sentry_value_as_int64(sentry_value_t value)
{
if ((value._bits & TAG_MASK) == TAG_INT32) {
return (int64_t)sentry_value_as_int32(value);
}

const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_INT64) {
return thing->payload._i64;
}
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
SENTRY_WARN("Cannot convert uint64 into int64, returning 0");
}
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
SENTRY_WARN("Cannot convert double into int64, returning 0");
}
return 0;
}

uint64_t
sentry_value_as_uint64(sentry_value_t value)
{
if ((value._bits & TAG_MASK) == TAG_INT32) {
SENTRY_WARN("Cannot convert int32 into uint64, returning 0");
return 0;
}

const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
return thing->payload._u64;
}
if (thing && thing_get_type(thing) == THING_TYPE_INT64) {
SENTRY_WARN("Cannot convert int64 into uint64, returning 0");
}
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
SENTRY_WARN("Cannot convert int64 into uint64, returning 0");
}
return 0;
}

const char *
Expand All @@ -899,9 +1007,8 @@ sentry_value_as_string(sentry_value_t value)
const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_STRING) {
return (const char *)thing->payload._ptr;
} else {
return "";
}
return "";
}

sentry_value_t
Expand Down Expand Up @@ -938,6 +1045,10 @@ sentry_value_is_true(sentry_value_t value)
return 0;
case SENTRY_VALUE_TYPE_INT32:
return sentry_value_as_int32(value) != 0;
case SENTRY_VALUE_TYPE_INT64:
return sentry_value_as_int64(value) != 0;
case SENTRY_VALUE_TYPE_UINT64:
return sentry_value_as_uint64(value) != 0;
case SENTRY_VALUE_TYPE_DOUBLE:
return sentry_value_as_double(value) != 0.0;
case SENTRY_VALUE_TYPE_STRING:
Expand Down Expand Up @@ -1002,6 +1113,12 @@ sentry__jsonwriter_write_value(sentry_jsonwriter_t *jw, sentry_value_t value)
case SENTRY_VALUE_TYPE_INT32:
sentry__jsonwriter_write_int32(jw, sentry_value_as_int32(value));
break;
case SENTRY_VALUE_TYPE_INT64:
sentry__jsonwriter_write_int64(jw, sentry_value_as_int64(value));
break;
case SENTRY_VALUE_TYPE_UINT64:
sentry__jsonwriter_write_uint64(jw, sentry_value_as_uint64(value));
break;
case SENTRY_VALUE_TYPE_DOUBLE:
sentry__jsonwriter_write_double(jw, sentry_value_as_double(value));
break;
Expand Down Expand Up @@ -1054,6 +1171,12 @@ value_to_msgpack(mpack_writer_t *writer, sentry_value_t value)
case SENTRY_VALUE_TYPE_INT32:
mpack_write_i32(writer, sentry_value_as_int32(value));
break;
case SENTRY_VALUE_TYPE_INT64:
mpack_write_i64(writer, sentry_value_as_int64(value));
break;
case SENTRY_VALUE_TYPE_UINT64:
mpack_write_u64(writer, sentry_value_as_uint64(value));
break;
case SENTRY_VALUE_TYPE_DOUBLE:
mpack_write_double(writer, sentry_value_as_double(value));
break;
Expand Down
Loading
Loading