1 /*
2 *
3 * Tests for C++ wrappers.
4 */
5
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <fstream>
10 #include <iostream>
11 #include <set>
12 #include <sstream>
13
14 #include "tests/test_cpp.upbdefs.h"
15 #include "tests/upb_test.h"
16 #include "upb/def.h"
17 #include "upb/handlers.h"
18 #include "upb/pb/decoder.h"
19 #include "upb/pb/textprinter.h"
20 #include "upb/port_def.inc"
21 #include "upb/upb.h"
22
23 template <class T>
AssertInsert(T * const container,const typename T::value_type & val)24 void AssertInsert(T* const container, const typename T::value_type& val) {
25 bool inserted = container->insert(val).second;
26 ASSERT(inserted);
27 }
28
29 //
30 // Tests for registering and calling handlers in all their variants.
31 // This test code is very repetitive because we have to declare each
32 // handler function variant separately, and they all have different
33 // signatures so it does not lend itself well to templates.
34 //
35 // We test three handler types:
36 // StartMessage (no data params)
37 // Int32 (1 data param (int32_t))
38 // String Buf (2 data params (const char*, size_t))
39 //
40 // For each handler type we test all 8 handler variants:
41 // (handler data?) x (function/method) x (returns {void, success})
42 //
43 // The one notable thing we don't test at the moment is
44 // StartSequence/StartString handlers: these are different from StartMessage()
45 // in that they return void* for the sub-closure. But this is exercised in
46 // other tests.
47 //
48
49 static const int kExpectedHandlerData = 1232323;
50
51 class StringBufTesterBase {
52 public:
53 static constexpr int kFieldNumber = 3;
54
StringBufTesterBase()55 StringBufTesterBase() : seen_(false), handler_data_val_(0) {}
56
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)57 void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
58 upb_selector_t start;
59 ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STARTSTR, &start));
60 upb_selector_t str;
61 ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STRING, &str));
62
63 ASSERT(!seen_);
64 upb::Sink sub;
65 sink.StartMessage();
66 sink.StartString(start, 0, &sub);
67 size_t ret = sub.PutStringBuffer(str, &buf_, 5, &handle_);
68 ASSERT(seen_);
69 ASSERT(len_ == 5);
70 ASSERT(ret == 5);
71 ASSERT(handler_data_val_ == kExpectedHandlerData);
72 }
73
74 protected:
75 bool seen_;
76 int handler_data_val_;
77 size_t len_;
78 char buf_;
79 upb_bufhandle handle_;
80 };
81
82 // Test 8 combinations of:
83 // (handler data?) x (buffer handle?) x (function/method)
84 //
85 // Then we add one test each for this variation: to prevent combinatorial
86 // explosion of these tests we don't test the full 16 combinations, but
87 // rely on our knowledge that the implementation processes the return wrapping
88 // in a second separate and independent stage:
89 //
90 // (function/method)
91
92 class StringBufTesterVoidMethodNoHandlerDataNoHandle
93 : public StringBufTesterBase {
94 public:
95 typedef StringBufTesterVoidMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)96 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
97 UPB_UNUSED(f);
98 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
99 handler_data_val_ = kExpectedHandlerData;
100 }
101
102 private:
Handler(const char * buf,size_t len)103 void Handler(const char *buf, size_t len) {
104 ASSERT(buf == &buf_);
105 seen_ = true;
106 len_ = len;
107 }
108 };
109
110 class StringBufTesterVoidMethodNoHandlerDataWithHandle
111 : public StringBufTesterBase {
112 public:
113 typedef StringBufTesterVoidMethodNoHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)114 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
115 UPB_UNUSED(f);
116 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
117 handler_data_val_ = kExpectedHandlerData;
118 }
119
120 private:
Handler(const char * buf,size_t len,const upb_bufhandle * handle)121 void Handler(const char *buf, size_t len, const upb_bufhandle* handle) {
122 ASSERT(buf == &buf_);
123 ASSERT(handle == &handle_);
124 seen_ = true;
125 len_ = len;
126 }
127 };
128
129 class StringBufTesterVoidMethodWithHandlerDataNoHandle
130 : public StringBufTesterBase {
131 public:
132 typedef StringBufTesterVoidMethodWithHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)133 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
134 UPB_UNUSED(f);
135 ASSERT(h.SetStringHandler(
136 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
137 }
138
139 private:
Handler(const int * hd,const char * buf,size_t len)140 void Handler(const int* hd, const char *buf, size_t len) {
141 ASSERT(buf == &buf_);
142 handler_data_val_ = *hd;
143 seen_ = true;
144 len_ = len;
145 }
146 };
147
148 class StringBufTesterVoidMethodWithHandlerDataWithHandle
149 : public StringBufTesterBase {
150 public:
151 typedef StringBufTesterVoidMethodWithHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)152 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
153 UPB_UNUSED(f);
154 ASSERT(h.SetStringHandler(
155 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
156 }
157
158 private:
Handler(const int * hd,const char * buf,size_t len,const upb_bufhandle * handle)159 void Handler(const int* hd, const char* buf, size_t len,
160 const upb_bufhandle* handle) {
161 ASSERT(buf == &buf_);
162 ASSERT(handle == &handle_);
163 handler_data_val_ = *hd;
164 seen_ = true;
165 len_ = len;
166 }
167 };
168
169 class StringBufTesterVoidFunctionNoHandlerDataNoHandle
170 : public StringBufTesterBase {
171 public:
172 typedef StringBufTesterVoidFunctionNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)173 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
174 UPB_UNUSED(f);
175 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
176 handler_data_val_ = kExpectedHandlerData;
177 }
178
179 private:
Handler(ME * t,const char * buf,size_t len)180 static void Handler(ME* t, const char *buf, size_t len) {
181 ASSERT(buf == &t->buf_);
182 t->seen_ = true;
183 t->len_ = len;
184 }
185 };
186
187 class StringBufTesterVoidFunctionNoHandlerDataWithHandle
188 : public StringBufTesterBase {
189 public:
190 typedef StringBufTesterVoidFunctionNoHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)191 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
192 UPB_UNUSED(f);
193 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
194 handler_data_val_ = kExpectedHandlerData;
195 }
196
197 private:
Handler(ME * t,const char * buf,size_t len,const upb_bufhandle * handle)198 static void Handler(ME* t, const char* buf, size_t len,
199 const upb_bufhandle* handle) {
200 ASSERT(buf == &t->buf_);
201 ASSERT(handle == &t->handle_);
202 t->seen_ = true;
203 t->len_ = len;
204 }
205 };
206
207 class StringBufTesterVoidFunctionWithHandlerDataNoHandle
208 : public StringBufTesterBase {
209 public:
210 typedef StringBufTesterVoidFunctionWithHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)211 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
212 UPB_UNUSED(f);
213 ASSERT(h.SetStringHandler(
214 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
215 }
216
217 private:
Handler(ME * t,const int * hd,const char * buf,size_t len)218 static void Handler(ME* t, const int* hd, const char *buf, size_t len) {
219 ASSERT(buf == &t->buf_);
220 t->handler_data_val_ = *hd;
221 t->seen_ = true;
222 t->len_ = len;
223 }
224 };
225
226 class StringBufTesterVoidFunctionWithHandlerDataWithHandle
227 : public StringBufTesterBase {
228 public:
229 typedef StringBufTesterVoidFunctionWithHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)230 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
231 UPB_UNUSED(f);
232 ASSERT(h.SetStringHandler(
233 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
234 }
235
236 private:
Handler(ME * t,const int * hd,const char * buf,size_t len,const upb_bufhandle * handle)237 static void Handler(ME* t, const int* hd, const char* buf, size_t len,
238 const upb_bufhandle* handle) {
239 ASSERT(buf == &t->buf_);
240 ASSERT(handle == &t->handle_);
241 t->handler_data_val_ = *hd;
242 t->seen_ = true;
243 t->len_ = len;
244 }
245 };
246
247 class StringBufTesterSizeTMethodNoHandlerDataNoHandle
248 : public StringBufTesterBase {
249 public:
250 typedef StringBufTesterSizeTMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)251 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
252 UPB_UNUSED(f);
253 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
254 handler_data_val_ = kExpectedHandlerData;
255 }
256
257 private:
Handler(const char * buf,size_t len)258 size_t Handler(const char *buf, size_t len) {
259 ASSERT(buf == &buf_);
260 seen_ = true;
261 len_ = len;
262 return len;
263 }
264 };
265
266 class StringBufTesterBoolMethodNoHandlerDataNoHandle
267 : public StringBufTesterBase {
268 public:
269 typedef StringBufTesterBoolMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)270 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
271 UPB_UNUSED(f);
272 ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
273 handler_data_val_ = kExpectedHandlerData;
274 }
275
276 private:
Handler(const char * buf,size_t len)277 bool Handler(const char *buf, size_t len) {
278 ASSERT(buf == &buf_);
279 seen_ = true;
280 len_ = len;
281 return true;
282 }
283 };
284
285 class StartMsgTesterBase {
286 public:
287 // We don't need the FieldDef it will create, but the test harness still
288 // requires that we provide one.
289 static constexpr int kFieldNumber = 3;
290
StartMsgTesterBase()291 StartMsgTesterBase() : seen_(false), handler_data_val_(0) {}
292
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)293 void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
294 UPB_UNUSED(f);
295 ASSERT(!seen_);
296 sink.StartMessage();
297 ASSERT(seen_);
298 ASSERT(handler_data_val_ == kExpectedHandlerData);
299 }
300
301 protected:
302 bool seen_;
303 int handler_data_val_;
304 };
305
306 // Test all 8 combinations of:
307 // (handler data?) x (function/method) x (returns {void, bool})
308
309 class StartMsgTesterVoidFunctionNoHandlerData : public StartMsgTesterBase {
310 public:
311 typedef StartMsgTesterVoidFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)312 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
313 UPB_UNUSED(f);
314 ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
315 handler_data_val_ = kExpectedHandlerData;
316 }
317
318 private:
319 //static void Handler(ME* t) {
Handler(ME * t)320 static void Handler(ME* t) {
321 t->seen_ = true;
322 }
323 };
324
325 class StartMsgTesterBoolFunctionNoHandlerData : public StartMsgTesterBase {
326 public:
327 typedef StartMsgTesterBoolFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)328 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
329 UPB_UNUSED(f);
330 ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
331 handler_data_val_ = kExpectedHandlerData;
332 }
333
334 private:
Handler(ME * t)335 static bool Handler(ME* t) {
336 t->seen_ = true;
337 return true;
338 }
339 };
340
341 class StartMsgTesterVoidMethodNoHandlerData : public StartMsgTesterBase {
342 public:
343 typedef StartMsgTesterVoidMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)344 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
345 UPB_UNUSED(f);
346 ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
347 handler_data_val_ = kExpectedHandlerData;
348 }
349
350 private:
Handler()351 void Handler() {
352 seen_ = true;
353 }
354 };
355
356 class StartMsgTesterBoolMethodNoHandlerData : public StartMsgTesterBase {
357 public:
358 typedef StartMsgTesterBoolMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)359 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
360 UPB_UNUSED(f);
361 ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
362 handler_data_val_ = kExpectedHandlerData;
363 }
364
365 private:
Handler()366 bool Handler() {
367 seen_ = true;
368 return true;
369 }
370 };
371
372 class StartMsgTesterVoidFunctionWithHandlerData : public StartMsgTesterBase {
373 public:
374 typedef StartMsgTesterVoidFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)375 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
376 UPB_UNUSED(f);
377 ASSERT(h.SetStartMessageHandler(
378 UpbBind(&Handler, new int(kExpectedHandlerData))));
379 }
380
381 private:
Handler(ME * t,const int * hd)382 static void Handler(ME* t, const int* hd) {
383 t->handler_data_val_ = *hd;
384 t->seen_ = true;
385 }
386 };
387
388 class StartMsgTesterBoolFunctionWithHandlerData : public StartMsgTesterBase {
389 public:
390 typedef StartMsgTesterBoolFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)391 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
392 UPB_UNUSED(f);
393 ASSERT(h.SetStartMessageHandler(
394 UpbBind(&Handler, new int(kExpectedHandlerData))));
395 }
396
397 private:
Handler(ME * t,const int * hd)398 static bool Handler(ME* t, const int* hd) {
399 t->handler_data_val_ = *hd;
400 t->seen_ = true;
401 return true;
402 }
403 };
404
405 class StartMsgTesterVoidMethodWithHandlerData : public StartMsgTesterBase {
406 public:
407 typedef StartMsgTesterVoidMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)408 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
409 UPB_UNUSED(f);
410 ASSERT(h.SetStartMessageHandler(
411 UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
412 }
413
414 private:
Handler(const int * hd)415 void Handler(const int* hd) {
416 handler_data_val_ = *hd;
417 seen_ = true;
418 }
419 };
420
421 class StartMsgTesterBoolMethodWithHandlerData : public StartMsgTesterBase {
422 public:
423 typedef StartMsgTesterBoolMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)424 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
425 UPB_UNUSED(f);
426 ASSERT(h.SetStartMessageHandler(
427 UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
428 }
429
430 private:
Handler(const int * hd)431 bool Handler(const int* hd) {
432 handler_data_val_ = *hd;
433 seen_ = true;
434 return true;
435 }
436 };
437
438 class Int32ValueTesterBase {
439 public:
440 static constexpr int kFieldNumber = 1;
441
Int32ValueTesterBase()442 Int32ValueTesterBase() : seen_(false), val_(0), handler_data_val_(0) {}
443
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)444 void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
445 upb_selector_t s;
446 ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_INT32, &s));
447
448 ASSERT(!seen_);
449 sink.PutInt32(s, 5);
450 ASSERT(seen_);
451 ASSERT(handler_data_val_ == kExpectedHandlerData);
452 ASSERT(val_ == 5);
453 }
454
455 protected:
456 bool seen_;
457 int32_t val_;
458 int handler_data_val_;
459 };
460
461 // Test all 8 combinations of:
462 // (handler data?) x (function/method) x (returns {void, bool})
463
464 class ValueTesterInt32VoidFunctionNoHandlerData
465 : public Int32ValueTesterBase {
466 public:
467 typedef ValueTesterInt32VoidFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)468 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
469 ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
470 handler_data_val_ = kExpectedHandlerData;
471 }
472
473 private:
Handler(ME * t,int32_t val)474 static void Handler(ME* t, int32_t val) {
475 t->val_ = val;
476 t->seen_ = true;
477 }
478 };
479
480 class ValueTesterInt32BoolFunctionNoHandlerData
481 : public Int32ValueTesterBase {
482 public:
483 typedef ValueTesterInt32BoolFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)484 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
485 ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
486 handler_data_val_ = kExpectedHandlerData;
487 }
488
489 private:
Handler(ME * t,int32_t val)490 static bool Handler(ME* t, int32_t val) {
491 t->val_ = val;
492 t->seen_ = true;
493 return true;
494 }
495 };
496
497 class ValueTesterInt32VoidMethodNoHandlerData : public Int32ValueTesterBase {
498 public:
499 typedef ValueTesterInt32VoidMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)500 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
501 ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
502 handler_data_val_ = kExpectedHandlerData;
503 }
504
505 private:
Handler(int32_t val)506 void Handler(int32_t val) {
507 val_ = val;
508 seen_ = true;
509 }
510 };
511
512 class ValueTesterInt32BoolMethodNoHandlerData : public Int32ValueTesterBase {
513 public:
514 typedef ValueTesterInt32BoolMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)515 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
516 ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
517 handler_data_val_ = kExpectedHandlerData;
518 }
519
520 private:
Handler(int32_t val)521 bool Handler(int32_t val) {
522 val_ = val;
523 seen_ = true;
524 return true;
525 }
526 };
527
528 class ValueTesterInt32VoidFunctionWithHandlerData
529 : public Int32ValueTesterBase {
530 public:
531 typedef ValueTesterInt32VoidFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)532 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
533 ASSERT(h.SetInt32Handler(
534 f, UpbBind(&Handler, new int(kExpectedHandlerData))));
535 }
536
537 private:
Handler(ME * t,const int * hd,int32_t val)538 static void Handler(ME* t, const int* hd, int32_t val) {
539 t->val_ = val;
540 t->handler_data_val_ = *hd;
541 t->seen_ = true;
542 }
543 };
544
545 class ValueTesterInt32BoolFunctionWithHandlerData
546 : public Int32ValueTesterBase {
547 public:
548 typedef ValueTesterInt32BoolFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)549 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
550 ASSERT(h.SetInt32Handler(
551 f, UpbBind(&Handler, new int(kExpectedHandlerData))));
552 }
553
554 private:
Handler(ME * t,const int * hd,int32_t val)555 static bool Handler(ME* t, const int* hd, int32_t val) {
556 t->val_ = val;
557 t->handler_data_val_ = *hd;
558 t->seen_ = true;
559 return true;
560 }
561 };
562
563 class ValueTesterInt32VoidMethodWithHandlerData : public Int32ValueTesterBase {
564 public:
565 typedef ValueTesterInt32VoidMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)566 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
567 ASSERT(h.SetInt32Handler(
568 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
569 }
570
571 private:
Handler(const int * hd,int32_t val)572 void Handler(const int* hd, int32_t val) {
573 val_ = val;
574 handler_data_val_ = *hd;
575 seen_ = true;
576 }
577 };
578
579 class ValueTesterInt32BoolMethodWithHandlerData : public Int32ValueTesterBase {
580 public:
581 typedef ValueTesterInt32BoolMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)582 void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
583 ASSERT(h.SetInt32Handler(
584 f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
585 }
586
587 private:
Handler(const int * hd,int32_t val)588 bool Handler(const int* hd, int32_t val) {
589 val_ = val;
590 handler_data_val_ = *hd;
591 seen_ = true;
592 return true;
593 }
594 };
595
596 template <class T>
RegisterHandlers(const void * closure,upb::Handlers * h_ptr)597 void RegisterHandlers(const void* closure, upb::Handlers* h_ptr) {
598 T* tester = const_cast<T*>(static_cast<const T*>(closure));
599 upb::HandlersPtr h(h_ptr);
600 upb::FieldDefPtr f = h.message_def().FindFieldByNumber(T::kFieldNumber);
601 ASSERT(f);
602 tester->Register(h, f);
603 }
604
605 template <class T>
TestHandler()606 void TestHandler() {
607 T tester;
608 upb::SymbolTable symtab;
609 upb::HandlerCache cache(&RegisterHandlers<T>, &tester);
610 upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
611 ASSERT(md);
612 upb::FieldDefPtr f = md.FindFieldByNumber(T::kFieldNumber);
613 ASSERT(f);
614
615 const upb::Handlers* h = cache.Get(md);
616
617 upb::Sink sink(h, &tester);
618 tester.CallAndVerify(sink, f);
619 }
620
621 class T1 {};
622 class T2 {};
623
624 template <class C>
DoNothingHandler(C * closure)625 void DoNothingHandler(C* closure) {
626 UPB_UNUSED(closure);
627 }
628
629 template <class C>
DoNothingInt32Handler(C * closure,int32_t val)630 void DoNothingInt32Handler(C* closure, int32_t val) {
631 UPB_UNUSED(closure);
632 UPB_UNUSED(val);
633 }
634
635 template <class R>
636 class DoNothingStartHandler {
637 public:
638 // We wrap these functions inside of a class for a somewhat annoying reason.
639 // UpbMakeHandler() is a macro, so we can't say
640 // UpbMakeHandler(DoNothingStartHandler<T1, T2>)
641 //
642 // because otherwise the preprocessor gets confused at the comma and tries to
643 // make it two macro arguments. The usual solution doesn't work either:
644 // UpbMakeHandler((DoNothingStartHandler<T1, T2>))
645 //
646 // If we do that the macro expands correctly, but then it tries to pass that
647 // parenthesized expression as a template parameter, ie. Type<(F)>, which
648 // isn't legal C++ (Clang will compile it but complains with
649 // warning: address non-type template argument cannot be surrounded by
650 // parentheses
651 //
652 // This two-level thing allows us to effectively pass two template parameters,
653 // but without any commas:
654 // UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)
655 template <class C>
Handler(C * closure)656 static R* Handler(C* closure) {
657 UPB_UNUSED(closure);
658 return NULL;
659 }
660
661 template <class C>
String(C * closure,size_t size_len)662 static R* String(C* closure, size_t size_len) {
663 UPB_UNUSED(closure);
664 UPB_UNUSED(size_len);
665 return NULL;
666 }
667 };
668
669 template <class C>
DoNothingStringBufHandler(C * closure,const char * buf,size_t len)670 void DoNothingStringBufHandler(C* closure, const char *buf, size_t len) {
671 UPB_UNUSED(closure);
672 UPB_UNUSED(buf);
673 UPB_UNUSED(len);
674 }
675
676 template <class C>
DoNothingEndMessageHandler(C * closure,upb_status * status)677 void DoNothingEndMessageHandler(C* closure, upb_status *status) {
678 UPB_UNUSED(closure);
679 UPB_UNUSED(status);
680 }
681
RegisterMismatchedTypes(const void * closure,upb::Handlers * h_ptr)682 void RegisterMismatchedTypes(const void* closure, upb::Handlers* h_ptr) {
683 upb::HandlersPtr h(h_ptr);
684 UPB_UNUSED(closure);
685
686 upb::MessageDefPtr md(h.message_def());
687 ASSERT(md);
688 upb::FieldDefPtr i32 = md.FindFieldByName("i32");
689 upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
690 upb::FieldDefPtr str = md.FindFieldByName("str");
691 upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
692 upb::FieldDefPtr msg = md.FindFieldByName("msg");
693 upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
694 ASSERT(i32);
695 ASSERT(r_i32);
696 ASSERT(str);
697 ASSERT(r_str);
698 ASSERT(msg);
699 ASSERT(r_msg);
700
701 // Establish T1 as the top-level closure type.
702 ASSERT(h.SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
703
704 // Now any other attempt to set another handler with T2 as the top-level
705 // closure should fail. But setting these same handlers with T1 as the
706 // top-level closure will succeed.
707 ASSERT(!h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T2>)));
708 ASSERT(h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T1>)));
709
710 ASSERT(
711 !h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T2>)));
712 ASSERT(
713 h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T1>)));
714
715 ASSERT(!h.SetStartStringHandler(
716 str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T2>)));
717 ASSERT(h.SetStartStringHandler(
718 str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
719
720 ASSERT(!h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler<T2>)));
721 ASSERT(h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler<T1>)));
722
723 ASSERT(!h.SetStartSubMessageHandler(
724 msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
725 ASSERT(h.SetStartSubMessageHandler(
726 msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
727
728 ASSERT(
729 !h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler<T2>)));
730 ASSERT(
731 h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler<T1>)));
732
733 ASSERT(!h.SetStartSequenceHandler(
734 r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
735 ASSERT(h.SetStartSequenceHandler(
736 r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
737
738 ASSERT(!h.SetEndSequenceHandler(
739 r_i32, UpbMakeHandler(DoNothingHandler<T2>)));
740 ASSERT(h.SetEndSequenceHandler(
741 r_i32, UpbMakeHandler(DoNothingHandler<T1>)));
742
743 ASSERT(!h.SetStartSequenceHandler(
744 r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
745 ASSERT(h.SetStartSequenceHandler(
746 r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
747
748 ASSERT(!h.SetEndSequenceHandler(
749 r_msg, UpbMakeHandler(DoNothingHandler<T2>)));
750 ASSERT(h.SetEndSequenceHandler(
751 r_msg, UpbMakeHandler(DoNothingHandler<T1>)));
752
753 ASSERT(!h.SetStartSequenceHandler(
754 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
755 ASSERT(h.SetStartSequenceHandler(
756 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
757
758 ASSERT(!h.SetEndSequenceHandler(
759 r_str, UpbMakeHandler(DoNothingHandler<T2>)));
760 ASSERT(h.SetEndSequenceHandler(
761 r_str, UpbMakeHandler(DoNothingHandler<T1>)));
762
763 // By setting T1 as the return type for the Start* handlers we have
764 // established T1 as the type of the sequence and string frames.
765 // Setting callbacks that use T2 should fail, but T1 should succeed.
766 ASSERT(
767 !h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T2>)));
768 ASSERT(
769 h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T1>)));
770
771 ASSERT(!h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T2>)));
772 ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
773
774 ASSERT(!h.SetStartSubMessageHandler(
775 r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
776 ASSERT(h.SetStartSubMessageHandler(
777 r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
778
779 ASSERT(!h.SetEndSubMessageHandler(r_msg,
780 UpbMakeHandler(DoNothingHandler<T2>)));
781 ASSERT(h.SetEndSubMessageHandler(r_msg,
782 UpbMakeHandler(DoNothingHandler<T1>)));
783
784 ASSERT(!h.SetStartStringHandler(
785 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T2>)));
786 ASSERT(h.SetStartStringHandler(
787 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
788
789 ASSERT(
790 !h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler<T2>)));
791 ASSERT(h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler<T1>)));
792
793 ASSERT(!h.SetStringHandler(r_str,
794 UpbMakeHandler(DoNothingStringBufHandler<T2>)));
795 ASSERT(h.SetStringHandler(r_str,
796 UpbMakeHandler(DoNothingStringBufHandler<T1>)));
797 }
798
RegisterMismatchedTypes2(const void * closure,upb::Handlers * h_ptr)799 void RegisterMismatchedTypes2(const void* closure, upb::Handlers* h_ptr) {
800 upb::HandlersPtr h(h_ptr);
801 UPB_UNUSED(closure);
802
803 upb::MessageDefPtr md(h.message_def());
804 ASSERT(md);
805 upb::FieldDefPtr i32 = md.FindFieldByName("i32");
806 upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
807 upb::FieldDefPtr str = md.FindFieldByName("str");
808 upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
809 upb::FieldDefPtr msg = md.FindFieldByName("msg");
810 upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
811 ASSERT(i32);
812 ASSERT(r_i32);
813 ASSERT(str);
814 ASSERT(r_str);
815 ASSERT(msg);
816 ASSERT(r_msg);
817
818 // For our second test we do the same in reverse. We directly set the type of
819 // the frame and then observe failures at registering a Start* handler that
820 // returns a different type.
821
822 // First establish the type of a sequence frame directly.
823 ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
824
825 // Now setting a StartSequence callback that returns a different type should
826 // fail.
827 ASSERT(!h.SetStartSequenceHandler(
828 r_i32, UpbMakeHandler(DoNothingStartHandler<T2>::Handler<T1>)));
829 ASSERT(h.SetStartSequenceHandler(
830 r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
831
832 // Establish a string frame directly.
833 ASSERT(h.SetStringHandler(r_str,
834 UpbMakeHandler(DoNothingStringBufHandler<T1>)));
835
836 // Fail setting a StartString callback that returns a different type.
837 ASSERT(!h.SetStartStringHandler(
838 r_str, UpbMakeHandler(DoNothingStartHandler<T2>::String<T1>)));
839 ASSERT(h.SetStartStringHandler(
840 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
841
842 // The previous established T1 as the frame for the r_str sequence.
843 ASSERT(!h.SetStartSequenceHandler(
844 r_str, UpbMakeHandler(DoNothingStartHandler<T2>::Handler<T1>)));
845 ASSERT(h.SetStartSequenceHandler(
846 r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
847 }
848
TestMismatchedTypes()849 void TestMismatchedTypes() {
850 // First create a schema for our test.
851 upb::SymbolTable symtab;
852 upb::HandlerCache handler_cache(&RegisterMismatchedTypes, nullptr);
853 upb::HandlerCache handler_cache2(&RegisterMismatchedTypes2, nullptr);
854 const upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
855
856 // Now test the type-checking in handler registration.
857 handler_cache.Get(md);
858 handler_cache2.Get(md);
859 }
860
861 class IntIncrementer {
862 public:
IntIncrementer(int * x)863 explicit IntIncrementer(int* x) : x_(x) { (*x_)++; }
~IntIncrementer()864 ~IntIncrementer() { (*x_)--; }
865
Handler(void * closure,const IntIncrementer * incrementer,int32_t x)866 static void Handler(void* closure, const IntIncrementer* incrementer,
867 int32_t x) {
868 UPB_UNUSED(closure);
869 UPB_UNUSED(incrementer);
870 UPB_UNUSED(x);
871 }
872
873 private:
874 int* x_;
875 };
876
RegisterIncrementor(const void * closure,upb::Handlers * h_ptr)877 void RegisterIncrementor(const void* closure, upb::Handlers* h_ptr) {
878 const int* x = static_cast<const int*>(closure);
879 upb::HandlersPtr h(h_ptr);
880 upb::FieldDefPtr f = h.message_def().FindFieldByName("i32");
881 h.SetInt32Handler(f, UpbBind(&IntIncrementer::Handler,
882 new IntIncrementer(const_cast<int*>(x))));
883 }
884
TestHandlerDataDestruction()885 void TestHandlerDataDestruction() {
886 int x = 0;
887
888 {
889 upb::SymbolTable symtab;
890 upb::HandlerCache cache(&RegisterIncrementor, &x);
891 upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
892 cache.Get(md);
893 ASSERT(x == 1);
894 }
895
896 ASSERT(x == 0);
897 }
898
TestIteration()899 void TestIteration() {
900 upb::SymbolTable symtab;
901 upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
902
903 // Test range-based for on both fields and oneofs (with the iterator adaptor).
904 int field_count = 0;
905 for (auto field : md.fields()) {
906 UPB_UNUSED(field);
907 field_count++;
908 }
909 ASSERT(field_count == md.field_count());
910
911 int oneof_count = 0;
912 for (auto oneof : md.oneofs()) {
913 UPB_UNUSED(oneof);
914 oneof_count++;
915 }
916 ASSERT(oneof_count == md.oneof_count());
917 }
918
TestArena()919 void TestArena() {
920 int n = 100000;
921
922 struct Decrementer {
923 Decrementer(int* _p) : p(_p) {}
924 ~Decrementer() { (*p)--; }
925 int* p;
926 };
927
928 {
929 upb::Arena arena;
930 for (int i = 0; i < n; i++) {
931 arena.Own(new Decrementer(&n));
932
933 // Intersperse allocation and ensure we can write to it.
934 int* val = static_cast<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
935 *val = i;
936 }
937
938 // Test a large allocation.
939 upb_arena_malloc(arena.ptr(), 1000000);
940 }
941 ASSERT(n == 0);
942
943 {
944 // Test fuse.
945 upb::Arena arena1;
946 upb::Arena arena2;
947
948 arena1.Fuse(arena2);
949
950 upb_arena_malloc(arena1.ptr(), 10000);
951 upb_arena_malloc(arena2.ptr(), 10000);
952 }
953 }
954
TestInlinedArena()955 void TestInlinedArena() {
956 int n = 100000;
957
958 struct Decrementer {
959 Decrementer(int* _p) : p(_p) {}
960 ~Decrementer() { (*p)--; }
961 int* p;
962 };
963
964 {
965 upb::InlinedArena<1024> arena;
966 for (int i = 0; i < n; i++) {
967 arena.Own(new Decrementer(&n));
968
969 // Intersperse allocation and ensure we can write to it.
970 int* val = static_cast<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
971 *val = i;
972 }
973
974 // Test a large allocation.
975 upb_arena_malloc(arena.ptr(), 1000000);
976 }
977 ASSERT(n == 0);
978 }
979
980 extern "C" {
981
run_tests()982 int run_tests() {
983 TestHandler<ValueTesterInt32VoidFunctionNoHandlerData>();
984 TestHandler<ValueTesterInt32BoolFunctionNoHandlerData>();
985 TestHandler<ValueTesterInt32VoidMethodNoHandlerData>();
986 TestHandler<ValueTesterInt32BoolMethodNoHandlerData>();
987 TestHandler<ValueTesterInt32VoidFunctionWithHandlerData>();
988 TestHandler<ValueTesterInt32BoolFunctionWithHandlerData>();
989 TestHandler<ValueTesterInt32VoidMethodWithHandlerData>();
990 TestHandler<ValueTesterInt32BoolMethodWithHandlerData>();
991
992 TestHandler<StartMsgTesterVoidFunctionNoHandlerData>();
993 TestHandler<StartMsgTesterBoolFunctionNoHandlerData>();
994 TestHandler<StartMsgTesterVoidMethodNoHandlerData>();
995 TestHandler<StartMsgTesterBoolMethodNoHandlerData>();
996 TestHandler<StartMsgTesterVoidFunctionWithHandlerData>();
997 TestHandler<StartMsgTesterBoolFunctionWithHandlerData>();
998 TestHandler<StartMsgTesterVoidMethodWithHandlerData>();
999 TestHandler<StartMsgTesterBoolMethodWithHandlerData>();
1000
1001 TestHandler<StringBufTesterVoidMethodNoHandlerDataNoHandle>();
1002 TestHandler<StringBufTesterVoidMethodNoHandlerDataWithHandle>();
1003 TestHandler<StringBufTesterVoidMethodWithHandlerDataNoHandle>();
1004 TestHandler<StringBufTesterVoidMethodWithHandlerDataWithHandle>();
1005 TestHandler<StringBufTesterVoidFunctionNoHandlerDataNoHandle>();
1006 TestHandler<StringBufTesterVoidFunctionNoHandlerDataWithHandle>();
1007 TestHandler<StringBufTesterVoidFunctionWithHandlerDataNoHandle>();
1008 TestHandler<StringBufTesterVoidFunctionWithHandlerDataWithHandle>();
1009 TestHandler<StringBufTesterSizeTMethodNoHandlerDataNoHandle>();
1010 TestHandler<StringBufTesterBoolMethodNoHandlerDataNoHandle>();
1011
1012 TestMismatchedTypes();
1013
1014 TestHandlerDataDestruction();
1015 TestIteration();
1016 TestArena();
1017
1018 return 0;
1019 }
1020
1021 }
1022