예제 #1
0
int
test_bson(int argc, char *argv[])
{
	struct bson_encoder_s encoder;
	struct bson_decoder_s decoder;
	void *buf;
	int len;

	/* encode data to a memory buffer */
	if (bson_encoder_init_buf(&encoder, nullptr, 0)) {
		PX4_ERR("FAIL: bson_encoder_init_buf");
		return 1;
	}

	encode(&encoder);
	len = bson_encoder_buf_size(&encoder);

	if (len <= 0) {
		PX4_ERR("FAIL: bson_encoder_buf_len");
		return 1;
	}

	buf = bson_encoder_buf_data(&encoder);

	if (buf == nullptr) {
		PX4_ERR("FAIL: bson_encoder_buf_data");
		return 1;
	}

	/* now test-decode it */
	if (bson_decoder_init_buf(&decoder, buf, len, decode_callback, nullptr)) {
		PX4_ERR("FAIL: bson_decoder_init_buf");
		return 1;
	}

	decode(&decoder);
	free(buf);

	return PX4_OK;
}
예제 #2
0
static int
param_export_internal(bool only_unsaved)
{
	struct param_wbuf_s *s = NULL;
	struct bson_encoder_s encoder;
	int     result = -1;

	param_lock();

	/* Use realloc */

	bson_encoder_init_buf(&encoder, NULL, 0);

	/* no modified parameters -> we are done */
	if (param_values == NULL) {
		result = 0;
		goto out;
	}

	while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) {

		int32_t i;
		float   f;

		/*
		 * If we are only saving values changed since last save, and this
		 * one hasn't, then skip it
		 */
		if (only_unsaved && !s->unsaved) {
			continue;
		}

		s->unsaved = false;

		/* append the appropriate BSON type object */

		switch (param_type(s->param)) {

		case PARAM_TYPE_INT32:
			param_get(s->param, &i);

			if (bson_encoder_append_int(&encoder, param_name(s->param), i)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_FLOAT:
			param_get(s->param, &f);

			if (bson_encoder_append_double(&encoder, param_name(s->param), f)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX:
			if (bson_encoder_append_binary(&encoder,
						       param_name(s->param),
						       BSON_BIN_BINARY,
						       param_size(s->param),
						       param_get_value_ptr_external(s->param))) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		default:
			debug("unrecognized parameter type");
			goto out;
		}
	}

	result = 0;

out:
	param_unlock();

	if (result == 0) {

		/* Finalize the bison encoding*/

		bson_encoder_fini(&encoder);

		/* Get requiered space */

		size_t buf_size = bson_encoder_buf_size(&encoder);

		/* Get a buffer from the flash driver with enough space */

		uint8_t *buffer;
		result = parameter_flashfs_alloc(parameters_token, &buffer, &buf_size);

		if (result == OK) {

			/* Check for a write that has no changes */

			uint8_t *was_buffer;
			size_t was_buf_size;
			int was_result = parameter_flashfs_read(parameters_token, &was_buffer, &was_buf_size);

			void *enc_buff = bson_encoder_buf_data(&encoder);

			bool commit = was_result < OK || was_buf_size != buf_size || 0 != memcmp(was_buffer, enc_buff, was_buf_size);

			if (commit) {

				memcpy(buffer, enc_buff, buf_size);
				result = parameter_flashfs_write(parameters_token, buffer, buf_size);
				result = result == buf_size ? OK : -EFBIG;

			}

			free(enc_buff);
		}
	}

	return result;
}