Пример #1
0
ConversionResultFlags jstr_to_i64(raw_buffer *str, int64_t *result)
{
	ConversionResultFlags conv_result;

	CHECK_POINTER_RETURN_VALUE(str->m_str, CONV_BAD_ARGS);
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);

	conv_result = parseJSONNumber(str, result, NULL, NULL, NULL);
	if (CONV_HAS_POSITIVE_OVERFLOW(conv_result))
		*result = INT64_MAX;
	else if (CONV_HAS_NEGATIVE_OVERFLOW(conv_result))
		*result = INT64_MIN;
	return conv_result;
}
Пример #2
0
static const char *jvalue_tostring_internal_layer2 (jvalue_ref val, JSchemaInfoRef schemainfo, bool schemaNecessary)
{
	SANITY_CHECK_POINTER(val);
	CHECK_POINTER_RETURN_VALUE(val, "null");

	if (!val->m_toString) {

		if (schemaNecessary && !jvalue_check_schema(val, schemainfo)) {
			return NULL;
		}

		bool parseok = false;
		StreamStatus error;
		JStreamRef generating = jstreamInternal(TOP_None);
		if (generating == NULL) {
			return NULL;
		}
		parseok = jvalue_to_string_append (val, generating);
		val->m_toString = generating->finish (generating, &error);
		val->m_toStringDealloc = free;
		assert (val->m_toString != NULL);
		if(!parseok) {
			return NULL;
		}
	}

	return val->m_toString;
}
Пример #3
0
int dom_number(JSAXContextRef ctxt, const char *number, size_t numberLen)
{
	DomInfo *data = getDOMContext(ctxt);
	jvalue_ref jnum;

	CHECK_CONDITION_RETURN_VALUE(data == NULL, 0, "number encountered without any context");
	CHECK_CONDITION_RETURN_VALUE(data->m_prev == NULL, 0, "unexpected state - how is this possible?");
	CHECK_POINTER_RETURN_VALUE(number, 0);
	CHECK_CONDITION_RETURN_VALUE(numberLen == 0, 0, "unexpected - numeric string doesn't actually contain a number");

	jnum = createOptimalNumber(data->m_optInformation, number, numberLen);

	if (data->m_value == NULL) {
		if (UNLIKELY(!jis_array(data->m_prev->m_value))) {
			PJ_LOG_ERR("PBNJSON_ARR_MISPLACED_NUM", 1, PMLOGKS("NUM", number), "Improper place for number");
			j_release(&jnum);
			return 0;
		}
		jarray_append(data->m_prev->m_value, jnum);
	} else if (jis_string(data->m_value)) {
		if (UNLIKELY(!jis_object(data->m_prev->m_value))) {
			PJ_LOG_ERR("PBNJSON_OBJ_MISPLACED_NUM", 1, PMLOGKS("NUM", number), "Improper place for number");
			j_release(&jnum);
			return 0;
		}
		jobject_put(data->m_prev->m_value, data->m_value, jnum);
		data->m_value = NULL;
	} else {
		PJ_LOG_ERR("PBNJSON_NUM_VALUE_WO_KEY", 1, PMLOGKS("NUM", number), "value portion of key-value pair without a key");
		return 0;
	}

	return 1;
}
Пример #4
0
ConversionResultFlags jdouble_to_i32(double value, int32_t *result)
{
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);
	
	if (isnan(value) != 0) {
		PJ_LOG_WARN("PBNJSON_NAN_TO_INT_WARN", 0, "attempting to convert nan to int");
		*result = 0;
		return CONV_NOT_A_NUM;
	}

	switch (isinf(value)) {
		case 0:
			break;
		case 1:
			PJ_LOG_WARN("PBNJSON_+INF_TO_INT_WARN", 0, "attempting to convert +infinity to int");
			*result = PJSON_MAX_INT;
			return CONV_POSITIVE_INFINITY;
		case -1:
			PJ_LOG_WARN("PBNJSON_-INF_TO_INT_WARN", 0, "attempting to convert -infinity to int");
			*result = PJSON_MIN_INT;
			return CONV_NEGATIVE_INFINITY;
		default:
			PJ_LOG_ERR("PBNJSON_ISINF_ERR", 1, PMLOGKFV("VALUE", "%lf", value), "unknown result from isinf for %lf", value);
			return CONV_GENERIC_ERROR;
	}

	if (value > PJSON_MAX_INT) {
		PJ_LOG_WARN("PBNJSON_DBL_OO_INT_RANGE", 1, PMLOGKFV("VALUE", "%lf", value), "attempting to convert double %lf outside of int range", value);
		*result = PJSON_MAX_INT;
		return CONV_POSITIVE_OVERFLOW;
	}

	if (value < PJSON_MIN_INT) {
		PJ_LOG_WARN("PBNJSON_DBL_OO_INT_RANGE", 1, PMLOGKFV("VALUE", "%lf", value), "attempting to convert double %lf outside of int range", value);
		*result = PJSON_MIN_INT;
		return CONV_NEGATIVE_OVERFLOW;
	}

#if 0
	// unnecessary for 32-bits because they will always fit in a double
	// with no precision loss
	if (value > PJSON_MAX_INT_IN_DBL || value < PJSON_MIN_INT_IN_DBL) {
		PJ_LOG_WARN("PBNJSON_DBL_TO_INT_CONV_WARN", 1, PMLOGKFV("VALUE", "%lf", value), "conversion of double %lf to integer potentially has precision loss", value);
		*result = (int64_t)value;
		return CONV_PRECISION_LOSS;
	}
#endif

	*result = (int32_t) value;
	if (*result != value) {
		PJ_LOG_WARN("PBNJSON_DBL_TO_INT_CONV_LOSS", 1, PMLOGKFV("VALUE", "%lf", value), "conversion of double %lf results in integer with different value", value);
		return CONV_PRECISION_LOSS;
	}

	return CONV_OK;
}
Пример #5
0
ConversionResultFlags ji64_to_double(int64_t value, double *result)
{
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);
	if (value > PJSON_MAX_INT_IN_DBL || value < PJSON_MIN_INT_IN_DBL) {
		PJ_LOG_WARN("PBNJSON_INT_TO_DBL_CONV_WARN", 1, PMLOGKFV("VALUE", "%"PRId64, value), "conversion of integer %"PRId64 " to a double will result in precision loss when doing reverse", value);
		*result = (double)value;
		return CONV_PRECISION_LOSS;
	}
	*result = (double)value;
	return CONV_OK;
}
Пример #6
0
ConversionResultFlags jstr_to_double(raw_buffer *str, double *result)
{
	ConversionResultFlags conv_result;

	int64_t wholeComponent = 0;
	int64_t fraction = 0;
	int64_t fractionLeadingZeros = 0;
	int64_t exponent = 0;

	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);

	conv_result = parseJSONNumber(str, &wholeComponent, &exponent, &fraction, &fractionLeadingZeros);

	if (UNLIKELY(CONV_IS_BAD_ARGS(conv_result) || CONV_IS_GENERIC_ERROR(conv_result))) {
		PJ_LOG_ERR("PBNJSON_STR_TO_NUM_ERR", 1, PMLOGKS("STRING", str->m_str), "Some weird problem converting %.*s to a number: %x", (int)str->m_len, str->m_str, conv_result);
		assert(false);
		*result = DBL_QUIET_NAN;
	} else if (UNLIKELY(CONV_HAS_POSITIVE_INFINITY(conv_result))) {
		*result = HUGE_VAL;
	} else if (UNLIKELY(CONV_HAS_NEGATIVE_INFINITY(conv_result))) {
		*result = -HUGE_VAL;
	} else {
		if (CONV_HAS_OVERFLOW(conv_result)) {
			// overflow that isn't infinity is precision loss
			assert (CONV_HAS_PRECISION_LOSS(conv_result));
		}

		double calculatedWhole = expBase10(wholeComponent, exponent);
		double calculatedFraction = copysign(expBase10(fraction, exponent - fractionLeadingZeros), calculatedWhole);
		*result = calculatedWhole + calculatedFraction;
		if (isinf(*result))
			conv_result |= CONV_POSITIVE_OVERFLOW;
		else if (-isinf(*result))
			conv_result |= CONV_NEGATIVE_OVERFLOW;
		else if (*result == 0 && fraction != 0)
			conv_result |= CONV_PRECISION_LOSS;
	}

	return conv_result;
}
Пример #7
0
ConversionResultFlags ji32_to_double(int32_t value, double *result)
{
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);
	*result = value;
	return CONV_OK;
}
Пример #8
0
static ConversionResult jdouble_noop(double value, double *result)
{
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);
	*result = value;
	return CONV_OK;
}
Пример #9
0
static ConversionResult ji64_noop(int64_t value, int64_t *result)
{
	CHECK_POINTER_RETURN_VALUE(result, CONV_BAD_ARGS);
	*result = value;
	return CONV_OK;
}