PX4 Firmware
PX4 Autopilot Software http://px4.io
test_bson.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2018-2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file test_bson.cpp
36  * Tests for the bson en/decoder
37  */
38 
39 #include <inttypes.h>
40 
41 #include <px4_platform_common/defines.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <limits.h>
46 #include <math.h>
47 
48 #include <systemlib/err.h>
50 
51 #include "tests_main.h"
52 
53 static const bool sample_bool = true;
54 static const int32_t sample_small_int = 123;
55 static const int64_t sample_big_int = (int64_t)INT_MAX + 123LL;
56 static const double sample_double = 2.5f;
57 static const char *sample_string = "this is a test";
58 static const uint8_t sample_data[256] = {0};
59 //static const char *sample_filename = "/fs/microsd/bson.test";
60 
61 static int
63 {
64  if (bson_encoder_append_bool(encoder, "bool1", sample_bool) != 0) {
65  PX4_ERR("FAIL: encoder: append bool failed");
66  return 1;
67  }
68 
69  if (bson_encoder_append_int(encoder, "int1", sample_small_int) != 0) {
70  PX4_ERR("FAIL: encoder: append int failed");
71  return 1;
72  }
73 
74  if (bson_encoder_append_int(encoder, "int2", sample_big_int) != 0) {
75  PX4_ERR("FAIL: encoder: append int failed");
76  return 1;
77  }
78 
79  if (bson_encoder_append_double(encoder, "double1", sample_double) != 0) {
80  PX4_ERR("FAIL: encoder: append double failed");
81  return 1;
82  }
83 
84  if (bson_encoder_append_string(encoder, "string1", sample_string) != 0) {
85  PX4_ERR("FAIL: encoder: append string failed");
86  return 1;
87  }
88 
89  if (bson_encoder_append_binary(encoder, "data1", BSON_BIN_BINARY, sizeof(sample_data), sample_data) != 0) {
90  PX4_ERR("FAIL: encoder: append data failed");
91  return 1;
92  }
93 
94  bson_encoder_fini(encoder);
95 
96  return 0;
97 }
98 
99 static int
100 decode_callback(bson_decoder_t decoder, void *priv, bson_node_t node)
101 {
102  unsigned len;
103 
104  if (!strcmp(node->name, "bool1")) {
105  if (node->type != BSON_BOOL) {
106  PX4_ERR("FAIL: decoder: bool1 type %d, expected %d", node->type, BSON_BOOL);
107  return 1;
108  }
109 
110  if (node->b != sample_bool) {
111  PX4_ERR("FAIL: decoder: bool1 value %s, expected %s",
112  (node->b ? "true" : "false"),
113  (sample_bool ? "true" : "false"));
114  return 1;
115  }
116 
117  PX4_INFO("PASS: decoder: bool1");
118  return 1;
119  }
120 
121  if (!strcmp(node->name, "int1")) {
122  if (node->type != BSON_INT32) {
123  PX4_ERR("FAIL: decoder: int1 type %d, expected %d", node->type, BSON_INT32);
124  return 1;
125  }
126 
127  if (node->i != sample_small_int) {
128  PX4_ERR("FAIL: decoder: int1 value %" PRIu64 ", expected %d", node->i, sample_small_int);
129  return 1;
130  }
131 
132  warnx("PASS: decoder: int1");
133  return 1;
134  }
135 
136  if (!strcmp(node->name, "int2")) {
137  if (node->type != BSON_INT64) {
138  PX4_ERR("FAIL: decoder: int2 type %d, expected %d", node->type, BSON_INT64);
139  return 1;
140  }
141 
142  if (node->i != sample_big_int) {
143  PX4_ERR("FAIL: decoder: int2 value %" PRIu64 ", expected %" PRIu64, node->i, sample_big_int);
144  return 1;
145  }
146 
147  warnx("PASS: decoder: int2");
148  return 1;
149  }
150 
151  if (!strcmp(node->name, "double1")) {
152  if (node->type != BSON_DOUBLE) {
153  PX4_ERR("FAIL: decoder: double1 type %d, expected %d", node->type, BSON_DOUBLE);
154  return 1;
155  }
156 
157  if (fabs(node->d - sample_double) > 1e-12) {
158  PX4_ERR("FAIL: decoder: double1 value %f, expected %f", node->d, sample_double);
159  return 1;
160  }
161 
162  warnx("PASS: decoder: double1");
163  return 1;
164  }
165 
166  if (!strcmp(node->name, "string1")) {
167  if (node->type != BSON_STRING) {
168  PX4_ERR("FAIL: decoder: string1 type %d, expected %d", node->type, BSON_STRING);
169  return 1;
170  }
171 
172  len = bson_decoder_data_pending(decoder);
173 
174  if (len != strlen(sample_string) + 1) {
175  PX4_ERR("FAIL: decoder: string1 length %d wrong, expected %zd", len, strlen(sample_string) + 1);
176  return 1;
177  }
178 
179  char sbuf[len];
180 
181  if (bson_decoder_copy_data(decoder, sbuf)) {
182  PX4_ERR("FAIL: decoder: string1 copy failed");
183  return 1;
184  }
185 
186  if (bson_decoder_data_pending(decoder) != 0) {
187  PX4_ERR("FAIL: decoder: string1 copy did not exhaust all data");
188  return 1;
189  }
190 
191  if (sbuf[len - 1] != '\0') {
192  PX4_ERR("FAIL: decoder: string1 not 0-terminated");
193  return 1;
194  }
195 
196  if (strcmp(sbuf, sample_string) != 0) {
197  PX4_ERR("FAIL: decoder: string1 value '%s', expected '%s'", sbuf, sample_string);
198  return 1;
199  }
200 
201  warnx("PASS: decoder: string1");
202  return 1;
203  }
204 
205  if (!strcmp(node->name, "data1")) {
206  if (node->type != BSON_BINDATA) {
207  PX4_ERR("FAIL: decoder: data1 type %d, expected %d", node->type, BSON_BINDATA);
208  return 1;
209  }
210 
211  len = bson_decoder_data_pending(decoder);
212 
213  if (len != sizeof(sample_data)) {
214  PX4_ERR("FAIL: decoder: data1 length %d, expected %zu", len, sizeof(sample_data));
215  return 1;
216  }
217 
218  if (node->subtype != BSON_BIN_BINARY) {
219  PX4_ERR("FAIL: decoder: data1 subtype %d, expected %d", node->subtype, BSON_BIN_BINARY);
220  return 1;
221  }
222 
223  uint8_t dbuf[len];
224 
225  if (bson_decoder_copy_data(decoder, dbuf)) {
226  PX4_ERR("FAIL: decoder: data1 copy failed");
227  return 1;
228  }
229 
230  if (bson_decoder_data_pending(decoder) != 0) {
231  PX4_ERR("FAIL: decoder: data1 copy did not exhaust all data");
232  return 1;
233  }
234 
235  if (memcmp(sample_data, dbuf, len) != 0) {
236  PX4_ERR("FAIL: decoder: data1 compare fail");
237  return 1;
238  }
239 
240  PX4_INFO("PASS: decoder: data1");
241  return 1;
242  }
243 
244  if (node->type != BSON_EOO) {
245  PX4_ERR("FAIL: decoder: unexpected node name '%s'", node->name);
246  }
247 
248  return 1;
249 }
250 
251 static void
253 {
254  int result;
255 
256  do {
257  result = bson_decoder_next(decoder);
258  } while (result > 0);
259 }
260 
261 int
262 test_bson(int argc, char *argv[])
263 {
264  struct bson_encoder_s encoder;
265  struct bson_decoder_s decoder;
266  void *buf;
267  int len;
268 
269  /* encode data to a memory buffer */
270  if (bson_encoder_init_buf(&encoder, nullptr, 0)) {
271  PX4_ERR("FAIL: bson_encoder_init_buf");
272  return 1;
273  }
274 
275  encode(&encoder);
276  len = bson_encoder_buf_size(&encoder);
277 
278  if (len <= 0) {
279  PX4_ERR("FAIL: bson_encoder_buf_len");
280  return 1;
281  }
282 
283  buf = bson_encoder_buf_data(&encoder);
284 
285  if (buf == nullptr) {
286  PX4_ERR("FAIL: bson_encoder_buf_data");
287  return 1;
288  }
289 
290  /* now test-decode it */
291  if (bson_decoder_init_buf(&decoder, buf, len, decode_callback, nullptr)) {
292  PX4_ERR("FAIL: bson_decoder_init_buf");
293  return 1;
294  }
295 
296  decode(&decoder);
297  free(buf);
298 
299  return PX4_OK;
300 }
static const uint8_t sample_data[256]
Definition: test_bson.cpp:58
char name[BSON_MAXNAME]
Definition: tinybson.h:85
void * bson_encoder_buf_data(bson_encoder_t encoder)
Get a pointer to the encoded object buffer.
Definition: tinybson.cpp:527
int bson_decoder_next(bson_decoder_t decoder)
Process the next node from the stream and invoke the callback.
Definition: tinybson.cpp:180
int bson_encoder_append_binary(bson_encoder_t encoder, const char *name, bson_binary_subtype_t subtype, size_t size, const void *data)
Append a binary blob to the encoded stream.
Definition: tinybson.cpp:614
uint8_t * buf
Definition: tinybson.h:109
bson_binary_subtype_t subtype
Definition: tinybson.h:87
Encoder state structure.
Definition: tinybson.h:173
int bson_decoder_copy_data(bson_decoder_t decoder, void *buf)
Copy node data.
Definition: tinybson.cpp:312
Node structure passed to the callback.
Definition: tinybson.h:84
int bson_encoder_append_string(bson_encoder_t encoder, const char *name, const char *string)
Append a string to the encoded stream.
Definition: tinybson.cpp:595
A simple subset SAX-style BSON parser and generator.
int bson_encoder_append_double(bson_encoder_t encoder, const char *name, double value)
Append a double to the encoded stream.
Definition: tinybson.cpp:580
static const int64_t sample_big_int
Definition: test_bson.cpp:55
int bson_decoder_init_buf(bson_decoder_t decoder, void *buf, unsigned bufsize, bson_decoder_callback callback, void *priv)
Initialise the decoder to read from a buffer in memory.
Definition: tinybson.cpp:137
static const bool sample_bool
Definition: test_bson.cpp:53
int bson_encoder_append_bool(bson_encoder_t encoder, const char *name, bool value)
Append a boolean to the encoded stream.
Definition: tinybson.cpp:538
size_t bson_decoder_data_pending(bson_decoder_t decoder)
Report copyable data size.
Definition: tinybson.cpp:331
#define warnx(...)
Definition: err.h:95
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
int test_bson(int argc, char *argv[])
Definition: test_bson.cpp:262
Tests declaration file.
static const char * sample_string
Definition: test_bson.cpp:57
int bson_encoder_fini(bson_encoder_t encoder)
Finalise the encoded stream.
Definition: tinybson.cpp:484
bson_type_t type
Definition: tinybson.h:86
int bson_encoder_buf_size(bson_encoder_t encoder)
Fetch the size of the encoded object; only valid for buffer operations.
Definition: tinybson.cpp:515
int bson_encoder_init_buf(bson_encoder_t encoder, void *buf, unsigned bufsize)
Initialze the encoder for writing to a buffer.
Definition: tinybson.cpp:460
static const int32_t sample_small_int
Definition: test_bson.cpp:54
bool b
Definition: tinybson.h:91
int64_t i
Definition: tinybson.h:89
static const double sample_double
Definition: test_bson.cpp:56
static int decode_callback(bson_decoder_t decoder, void *priv, bson_node_t node)
Definition: test_bson.cpp:100
static int encode(bson_encoder_t encoder)
Definition: test_bson.cpp:62
double d
Definition: tinybson.h:90
static void decode(bson_decoder_t decoder)
Definition: test_bson.cpp:252
int bson_encoder_append_int(bson_encoder_t encoder, const char *name, int64_t value)
Append an integer to the encoded stream.
Definition: tinybson.cpp:552