From 1b4d8bbd2bd61de384c302ba23cce76bf2adf2ec Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Wed, 27 Nov 2019 11:55:12 +0100 Subject: [PATCH] tests/pkg_flattbuffers: add sample application --- tests/pkg_flatbuffers/.gitignore | 1 + tests/pkg_flatbuffers/Makefile | 13 ++++ tests/pkg_flatbuffers/Makefile.ci | 3 + tests/pkg_flatbuffers/README.md | 26 +++++++ tests/pkg_flatbuffers/main.cpp | 105 ++++++++++++++++++++++++++ tests/pkg_flatbuffers/monster.fbs | 33 ++++++++ tests/pkg_flatbuffers/tests/01-run.py | 12 +++ 7 files changed, 193 insertions(+) create mode 100644 tests/pkg_flatbuffers/.gitignore create mode 100644 tests/pkg_flatbuffers/Makefile create mode 100644 tests/pkg_flatbuffers/Makefile.ci create mode 100644 tests/pkg_flatbuffers/README.md create mode 100644 tests/pkg_flatbuffers/main.cpp create mode 100644 tests/pkg_flatbuffers/monster.fbs create mode 100755 tests/pkg_flatbuffers/tests/01-run.py diff --git a/tests/pkg_flatbuffers/.gitignore b/tests/pkg_flatbuffers/.gitignore new file mode 100644 index 0000000000..60653ab688 --- /dev/null +++ b/tests/pkg_flatbuffers/.gitignore @@ -0,0 +1 @@ +monster_generated.h diff --git a/tests/pkg_flatbuffers/Makefile b/tests/pkg_flatbuffers/Makefile new file mode 100644 index 0000000000..44032e14a5 --- /dev/null +++ b/tests/pkg_flatbuffers/Makefile @@ -0,0 +1,13 @@ +include ../Makefile.tests_common + +USEPKG += flatbuffers + +# Skip warning raised when building monster_generated.h +CXXEXFLAGS += -Wno-type-limits + +BUILDDEPS += monster_generated.h + +include $(RIOTBASE)/Makefile.include + +monster_generated.h: $(FLATC) + $(Q)$(FLATC) --cpp $(CURDIR)/monster.fbs diff --git a/tests/pkg_flatbuffers/Makefile.ci b/tests/pkg_flatbuffers/Makefile.ci new file mode 100644 index 0000000000..518b330a9e --- /dev/null +++ b/tests/pkg_flatbuffers/Makefile.ci @@ -0,0 +1,3 @@ +BOARD_INSUFFICIENT_MEMORY := \ + stm32f030f4-demo \ + # diff --git a/tests/pkg_flatbuffers/README.md b/tests/pkg_flatbuffers/README.md new file mode 100644 index 0000000000..b4a19ec098 --- /dev/null +++ b/tests/pkg_flatbuffers/README.md @@ -0,0 +1,26 @@ +FlatBuffer sample application +============================= + +This application shows how to use the FlatBuffer library from Google for +serializing/deserializing a runtime C++ object to/from a binary buffer. + +The application is +[taken as is from the upstream repository](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp). + +More details are available on +[the FlatBuffers website](http://google.github.io/flatbuffers/). + +Usage +----- + +Simply flash and run the application on the board of your choice using: + + make BOARD= -C tests/pkg_flatbuffers flash term + +Expected result +--------------- + +The application creates an object, serialize it in a FlatBuffer and after +reloading the serialized object it displays: + + "The FlatBuffer was successfully created and verified!" diff --git a/tests/pkg_flatbuffers/main.cpp b/tests/pkg_flatbuffers/main.cpp new file mode 100644 index 0000000000..eb63b66b2d --- /dev/null +++ b/tests/pkg_flatbuffers/main.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2015 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h". + +using namespace MyGame::Sample; + +// Example how to use FlatBuffers to create and read binary buffers. + +int main(int /*argc*/, const char * /*argv*/[]) { + // Build up a serialized buffer algorithmically: + flatbuffers::FlatBufferBuilder builder; + + // First, lets serialize some weapons for the Monster: A 'sword' and an 'axe'. + auto weapon_one_name = builder.CreateString("Sword"); + short weapon_one_damage = 3; + + auto weapon_two_name = builder.CreateString("Axe"); + short weapon_two_damage = 5; + + // Use the `CreateWeapon` shortcut to create Weapons with all fields set. + auto sword = CreateWeapon(builder, weapon_one_name, weapon_one_damage); + auto axe = CreateWeapon(builder, weapon_two_name, weapon_two_damage); + + // Create a FlatBuffer's `vector` from the `std::vector`. + std::vector> weapons_vector; + weapons_vector.push_back(sword); + weapons_vector.push_back(axe); + auto weapons = builder.CreateVector(weapons_vector); + + // Second, serialize the rest of the objects needed by the Monster. + auto position = Vec3(1.0f, 2.0f, 3.0f); + + auto name = builder.CreateString("MyMonster"); + + unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + auto inventory = builder.CreateVector(inv_data, 10); + + // Shortcut for creating monster with all fields set: + auto orc = CreateMonster(builder, &position, 150, 80, name, inventory, + Color_Red, weapons, Equipment_Weapon, axe.Union()); + + builder.Finish(orc); // Serialize the root of the object. + + // We now have a FlatBuffer we can store on disk or send over a network. + + // ** file/network code goes here :) ** + // access builder.GetBufferPointer() for builder.GetSize() bytes + + // Instead, we're going to access it right away (as if we just received it). + + // Get access to the root: + auto monster = GetMonster(builder.GetBufferPointer()); + + // Get and test some scalar types from the FlatBuffer. + assert(monster->hp() == 80); + assert(monster->mana() == 150); // default + assert(monster->name()->str() == "MyMonster"); + + // Get and test a field of the FlatBuffer's `struct`. + auto pos = monster->pos(); + assert(pos); + assert(pos->z() == 3.0f); + (void)pos; + + // Get a test an element from the `inventory` FlatBuffer's `vector`. + auto inv = monster->inventory(); + assert(inv); + assert(inv->Get(9) == 9); + (void)inv; + + // Get and test the `weapons` FlatBuffers's `vector`. + std::string expected_weapon_names[] = { "Sword", "Axe" }; + short expected_weapon_damages[] = { 3, 5 }; + auto weps = monster->weapons(); + for (unsigned int i = 0; i < weps->size(); i++) { + assert(weps->Get(i)->name()->str() == expected_weapon_names[i]); + assert(weps->Get(i)->damage() == expected_weapon_damages[i]); + } + (void)expected_weapon_names; + (void)expected_weapon_damages; + + // Get and test the `Equipment` union (`equipped` field). + assert(monster->equipped_type() == Equipment_Weapon); + auto equipped = static_cast(monster->equipped()); + assert(equipped->name()->str() == "Axe"); + assert(equipped->damage() == 5); + (void)equipped; + + printf("The FlatBuffer was successfully created and verified!\n"); +} diff --git a/tests/pkg_flatbuffers/monster.fbs b/tests/pkg_flatbuffers/monster.fbs new file mode 100644 index 0000000000..af224512ee --- /dev/null +++ b/tests/pkg_flatbuffers/monster.fbs @@ -0,0 +1,33 @@ +// Example IDL file for our monster's schema. + +namespace MyGame.Sample; + +enum Color:byte { Red = 0, Green, Blue = 2 } + +union Equipment { Weapon } // Optionally add more tables. + +struct Vec3 { + x:float; + y:float; + z:float; +} + +table Monster { + pos:Vec3; + mana:short = 150; + hp:short = 100; + name:string; + friendly:bool = false (deprecated); + inventory:[ubyte]; + color:Color = Blue; + weapons:[Weapon]; + equipped:Equipment; + path:[Vec3]; +} + +table Weapon { + name:string; + damage:short; +} + +root_type Monster; diff --git a/tests/pkg_flatbuffers/tests/01-run.py b/tests/pkg_flatbuffers/tests/01-run.py new file mode 100755 index 0000000000..c0de8e223b --- /dev/null +++ b/tests/pkg_flatbuffers/tests/01-run.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +import sys +from testrunner import run + + +def testfunc(child): + child.expect_exact('The FlatBuffer was successfully created and verified!') + + +if __name__ == "__main__": + sys.exit(run(testfunc))