Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
126 changes: 126 additions & 0 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 _int64_data; // to avoid shadowing __int64 (C2628 error)
uint64_t _uint64_data;
} 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._int64_data = 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._uint64_data = 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 @@ -648,6 +688,26 @@ sentry__value_stringify(sentry_value_t value)
buf[written] = '\0';
return sentry__string_clone(buf);
}
case SENTRY_VALUE_TYPE_INT64: {
char buf[24];
size_t written = (size_t)sentry__snprintf_c(
buf, sizeof(buf), "%lld", (long long)sentry_value_as_int64(value));
if (written >= sizeof(buf)) {
return sentry__string_clone("");
}
buf[written] = '\0';
return sentry__string_clone(buf);
}
case SENTRY_VALUE_TYPE_UINT64: {
char buf[24];
size_t written = (size_t)sentry__snprintf_c(buf, sizeof(buf), "%llu",
(unsigned long long)sentry_value_as_uint64(value));
if (written >= sizeof(buf)) {
return sentry__string_clone("");
}
buf[written] = '\0';
return sentry__string_clone(buf);
}
}
}

Expand Down Expand Up @@ -681,6 +741,10 @@ sentry__value_clone(sentry_value_t value)
case THING_TYPE_DOUBLE:
sentry_value_incref(value);
return value;
case THING_TYPE_INT64:
case THING_TYPE_UINT64:
sentry_value_incref(value);
return value;
default:
return sentry_value_new_null();
}
Expand Down Expand Up @@ -893,6 +957,52 @@ sentry_value_as_double(sentry_value_t value)
}
}

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._int64_data;
}
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
return (int64_t)thing->payload._uint64_data;
}
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
return (int64_t)thing->payload._double;
}
return 0;
}

uint64_t
sentry_value_as_uint64(sentry_value_t value)
{
if ((value._bits & TAG_MASK) == TAG_INT32) {
int32_t int32_val = sentry_value_as_int32(value);
return int32_val >= 0 ? (uint64_t)int32_val : 0;
}

const thing_t *thing = value_as_thing(value);
if (thing && thing_get_type(thing) == THING_TYPE_UINT64) {
return thing->payload._uint64_data;
}
if (thing && thing_get_type(thing) == THING_TYPE_INT64) {
return thing->payload._int64_data >= 0
? (uint64_t)thing->payload._int64_data
: 0;
}
if (thing && thing_get_type(thing) == THING_TYPE_DOUBLE) {
// TODO no check for double out of uint64 range
// TODO double gets truncated (1.9 -> 1)
return thing->payload._double >= 0 ? (uint64_t)thing->payload._double
: 0;
}
return 0;
}

const char *
sentry_value_as_string(sentry_value_t value)
{
Expand Down Expand Up @@ -938,6 +1048,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 +1116,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 +1174,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