struct Data { int field1 = 0; std::string field2; };
int main() { Data data; data.field1 = 100500; data.field2 = "Text"; using Meta = Mif::Reflection::Reflect<Data>; std::cout << "Struct name: " << Meta::Name::GetString() << std::endl; std::cout << "Field count: " << Meta::Fields::Count << std::endl; std::cout << "Field1 value: " << data.field1 << std::endl; std::cout << "Field2 value: " << data.field2 << std::endl; std::cout << "Modify fields." << std::endl; data.*Meta::Fields::Field<0>::Access() = 500100; data.*Meta::Fields::Field<1>::Access() = "New Text."; std::cout << "Field1 value: " << data.field1 << std::endl; std::cout << "Field2 value: " << data.field2 << std::endl; return 0; }
MIF_REFLECT_BEGIN(Data) MIF_REFLECT_FIELD(field1) MIF_REFLECT_FIELD(field2) MIF_REFLECT_END() MIF_REGISTER_REFLECTED_TYPE(Data)
// STD #include <iostream> #include <string> // MIF #include <mif/reflection/reflect_type.h> #include <mif/reflection/reflection.h> struct Data { int field1 = 0; std::string field2; }; MIF_REFLECT_BEGIN(Data) MIF_REFLECT_FIELD(field1) MIF_REFLECT_FIELD(field2) MIF_REFLECT_END() MIF_REGISTER_REFLECTED_TYPE(Data) int main() { Data data; data.field1 = 100500; data.field2 = "Text"; using Meta = Mif::Reflection::Reflect<Data>; std::cout << "Struct name: " << Meta::Name::GetString() << std::endl; std::cout << "Field count: " << Meta::Fields::Count << std::endl; std::cout << "Field1 value: " << data.field1 << std::endl; std::cout << "Field2 value: " << data.field2 << std::endl; std::cout << "Modify fields." << std::endl; data.*Meta::Fields::Field<0>::Access() = 500100; data.*Meta::Fields::Field<1>::Access() = "New Text."; std::cout << "Field1 value: " << data.field1 << std::endl; std::cout << "Field2 value: " << data.field2 << std::endl; return 0; }
// STD #include <iostream> #include <map> #include <string> #include <type_traits> // MIF #include <mif/reflection/reflect_type.h> #include <mif/reflection/reflection.h> #include <mif/serialization/traits.h> struct Base1 { int field1 = 0; bool field2 = false; }; struct Base2 { std::string field3; }; struct Nested { int field = 0; }; struct Data : Base1, Base2 { int field4 = 0; std::string field5; std::map<std::string, Nested> field6; }; MIF_REFLECT_BEGIN(Base1) MIF_REFLECT_FIELD(field1) MIF_REFLECT_FIELD(field2) MIF_REFLECT_END() MIF_REFLECT_BEGIN(Base2) MIF_REFLECT_FIELD(field3) MIF_REFLECT_END() MIF_REFLECT_BEGIN(Nested) MIF_REFLECT_FIELD(field) MIF_REFLECT_END() MIF_REFLECT_BEGIN(Data, Base1, Base2) MIF_REFLECT_FIELD(field4) MIF_REFLECT_FIELD(field5) MIF_REFLECT_FIELD(field6) MIF_REFLECT_END() MIF_REGISTER_REFLECTED_TYPE(Base1) MIF_REGISTER_REFLECTED_TYPE(Base2) MIF_REGISTER_REFLECTED_TYPE(Nested) MIF_REGISTER_REFLECTED_TYPE(Data) class Printer final { public: template <typename T> static typename std::enable_if<Mif::Reflection::IsReflectable<T>(), void>::type Print(T const &data) { using Meta = Mif::Reflection::Reflect<T>; using Base = typename Meta::Base; PrintBase<0, std::tuple_size<Base>::value, Base>(data); std::cout << "Struct name: " << Meta::Name::GetString() << std::endl; Print<0, Meta::Fields::Count>(data); } template <typename T> static typename std::enable_if < !Mif::Reflection::IsReflectable<T>() && !Mif::Serialization::Traits::IsIterable<T>(), void >::type Print(T const &data) { std::cout << data << std::boolalpha << std::endl; } template <typename T> static typename std::enable_if < !Mif::Reflection::IsReflectable<T>() && Mif::Serialization::Traits::IsIterable<T>(), void >::type Print(T const &data) { for (auto const &i : data) Print(i); } private: template <std::size_t I, std::size_t N, typename T> static typename std::enable_if<I != N, void>::type Print(T const &data) { using Meta = Mif::Reflection::Reflect<T>; using Field = typename Meta::Fields::template Field<I>; std::cout << Field::Name::GetString() << " = "; Print(data.*Field::Access()); Print<I + 1, N>(data); } template <std::size_t I, std::size_t N, typename T> static typename std::enable_if<I == N, void>::type Print(T const &) { } template <typename K, typename V> static void Print(std::pair<K, V> const &p) { Print(p.first); Print(p.second); } template <std::size_t I, std::size_t N, typename B, typename T> static typename std::enable_if<I != N, void>::type PrintBase(T const &data) { using Type = typename std::tuple_element<I, B>::type; Print(static_cast<Type const &>(data)); PrintBase<I + 1, N, B>(data); } template <std::size_t I, std::size_t N, typename B, typename T> static typename std::enable_if<I == N, void>::type PrintBase(T const &) { } }; int main() { Data data; data.field1 = 1; data.field2 = true; data.field3 = "Text"; data.field4 = 100; data.field5 = "String"; data.field6["key1"].field = 100; data.field6["key2"].field = 200; Printer::Print(data); return 0; }
Struct name: Base1 field1 = 1 field2 = true Struct name: Base2 field3 = Text Struct name: Data field4 = 100 field5 = String field6 = key1 Struct name: Nested field = 100 key2 Struct name: Nested field = 200
#include <mif/reflection/reflect_type.h> #include <mif/serialization/json.h> // Data and meta int main() { Data data; // Fill data auto const buffer = Mif::Serialization::Json::Serialize(data); // json std::cout << buffer.data() << std::endl; return 0; }
{ "Base1" : { "field1" : 1, "field2" : true }, "Base2" : { "field3" : "Text" }, "field4" : 100, "field5" : "String", "field6" : [ { "id" : "key1", "val" : { "field" : 100 } }, { "id" : "key2", "val" : { "field" : 200 } } ] }
// BOOST #include <boost/archive/xml_oarchive.hpp> // MIF #include <mif/reflection/reflect_type.h> #include <mif/serialization/boost.h> // Data and meta int main() { Data data; // Fill data boost::archive::xml_oarchive archive{std::cout}; archive << boost::serialization::make_nvp("data", data); return 0; }
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="14"> <data class_id="0" tracking_level="0" version="0"> <Base1 class_id="1" tracking_level="0" version="0"> <field1>1</field1> <field2>1</field2> </Base1> <Base2 class_id="2" tracking_level="0" version="0"> <field3>Text</field3> </Base2> <field4>100</field4> <field5>String</field5> <field6 class_id="3" tracking_level="0" version="0"> <count>2</count> <item_version>0</item_version> <item class_id="4" tracking_level="0" version="0"> <first>key1</first> <second class_id="5" tracking_level="0" version="0"> <field>100</field> </second> </item> <item> <first>key2</first> <second> <field>200</field> </second> </item> </field6> </data> </boost_serialization>
// data.h namespace Service { namespace Data { using ID = std::string; struct Human { std::string name; std::string lastName; std::uint32_t age = 0; }; enum class Position { Unknown, Developer, Manager }; struct Employee : public Human { Position position = Position::Unknown; }; using Employees = std::map<ID, Employee>; } // namespace Data } // namespace Service
// meta/data.h namespace Service { namespace Data { namespace Meta { using namespace ::Service::Data; MIF_REFLECT_BEGIN(Human) MIF_REFLECT_FIELD(name) MIF_REFLECT_FIELD(lastName) MIF_REFLECT_FIELD(age) MIF_REFLECT_END() MIF_REFLECT_BEGIN(Position) MIF_REFLECT_FIELD(Unknown) MIF_REFLECT_FIELD(Developer) MIF_REFLECT_FIELD(Manager) MIF_REFLECT_END() MIF_REFLECT_BEGIN(Employee, Human) MIF_REFLECT_FIELD(position) MIF_REFLECT_END() } // namespace Meta } // namespace Data } // namespace Service MIF_REGISTER_REFLECTED_TYPE(::Service::Data::Meta::Human) MIF_REGISTER_REFLECTED_TYPE(::Service::Data::Meta::Position) MIF_REGISTER_REFLECTED_TYPE(::Service::Data::Meta::Employee)
// imy_company.h namespace Service { struct IMyCompany : public Mif::Service::Inherit<Mif::Service::IService> { virtual Data::ID AddEmployee(Data::Employee const &employee) = 0; virtual void RemoveAccount(Data::ID const &id) = 0; virtual Data::Employees GetEmployees() const = 0; }; } // namespace Service
// ps/imy_company.h namespace Service { namespace Meta { using namespace ::Service; MIF_REMOTE_PS_BEGIN(IMyCompany) MIF_REMOTE_METHOD(AddEmployee) MIF_REMOTE_METHOD(RemoveAccount) MIF_REMOTE_METHOD(GetEmployees) MIF_REMOTE_PS_END() } // namespace Meta } // namespace Service MIF_REMOTE_REGISTER_PS(Service::Meta::IMyCompany)
// id/service.h namespace Service { namespace Id { enum { MyCompany = Mif::Common::Crc32("MyCompany") }; } // namespace Id } // namespace Service
// service.cpp // MIF #include <mif/common/log.h> #include <mif/reflection/reflection.h> #include <mif/service/creator.h> // COMMON #include "common/id/service.h" #include "common/interface/imy_company.h" #include "common/meta/data.h" namespace Service { namespace Detail { namespace { class MyCompany : public Mif::Service::Inherit<IMyCompany> { public: // … private: // … // IMyCompany virtual Data::ID AddEmployee(Data::Employee const &employee) override final { // ... } virtual void RemoveAccount(Data::ID const &id) override final { // ... } } virtual Data::Employees GetEmployees() const override final { // ... } }; } // namespace } // namespace Detail } // namespace Service MIF_SERVICE_CREATOR ( ::Service::Id::MyCompany, ::Service::Detail::MyCompany )
// MIF #include <mif/application/tcp_service.h> // COMMON #include "common/id/service.h" #include "common/ps/imy_company.h" class Application : public Mif::Application::TcpService { public: using TcpService::TcpService; private: // Mif.Application.Application virtual void Init(Mif::Service::FactoryPtr factory) override final { factory->AddClass<::Service::Id::MyCompany>(); } }; int main(int argc, char const **argv) { return Mif::Application::Run<Application>(argc, argv); }
// MIF #include <mif/application/tcp_service_client.h> #include <mif/common/log.h> // COMMON #include "common/id/service.h" #include "common/ps/imy_company.h" class Application : public Mif::Application::TcpServiceClient { public: using TcpServiceClient::TcpServiceClient; private: void ShowEmployees(Service::Data::Employees const &employees) const { // ... } // Mif.Application.TcpServiceClient virtual void Init(Mif::Service::IFactoryPtr factory) override final { auto service = factory->Create<Service::IMyCompany>(Service::Id::MyCompany); { Service::Data::Employee e; e.name = "Ivan"; e.lastName = "Ivanov"; e.age = 25; e.position = Service::Data::Position::Manager; auto const eId = service->AddEmployee(e); MIF_LOG(Info) << "Employee Id: " << eId; } { Service::Data::Employee e; e.name = "Petr"; e.lastName = "Petrov"; e.age = 30; e.position = Service::Data::Position::Developer; auto const eId = service->AddEmployee(e); MIF_LOG(Info) << "Employee Id: " << eId; } auto const &employees = service->GetEmployees(); ShowEmployees(employees); if (!employees.empty()) { auto id = std::begin(employees)->first; service->RemoveAccount(id); MIF_LOG(Info) << "Removed account " << id; auto const &employees = service->GetEmployees(); ShowEmployees(employees); try { MIF_LOG(Info) << "Removed again account " << id; service->RemoveAccount(id); } catch (std::exception const &e) { MIF_LOG(Warning) << "Error: " << e.what(); } } } }; int main(int argc, char const **argv) { return Mif::Application::Run<Application>(argc, argv); }
2017-08-09T14:01:23.404663 [INFO]: Starting network application on 0.0.0.0:55555 2017-08-09T14:01:23.404713 [INFO]: Starting server on 0.0.0.0:55555 2017-08-09T14:01:23.405442 [INFO]: Server is successfully started. 2017-08-09T14:01:23.405463 [INFO]: Network application is successfully started. Press 'Enter' for quit. 2017-08-09T14:01:29.032171 [INFO]: MyCompany 2017-08-09T14:01:29.041704 [INFO]: AddEmployee. Name: Ivan LastName: Ivanov Age: 25 Position: Manager 2017-08-09T14:01:29.042948 [INFO]: AddEmployee. Name: Petr LastName: Petrov Age: 30 Position: Developer 2017-08-09T14:01:29.043616 [INFO]: GetEmployees. 2017-08-09T14:01:29.043640 [INFO]: Id: 0 Name: Ivan LastName: Ivanov Age: 25 Position: Manager 2017-08-09T14:01:29.043656 [INFO]: Id: 1 Name: Petr LastName: Petrov Age: 30 Position: Developer 2017-08-09T14:01:29.044481 [INFO]: Removed employee account for Id: 0 Name: Ivan LastName: Ivanov Age: 25 Position: Manager 2017-08-09T14:01:29.045121 [INFO]: GetEmployees. 2017-08-09T14:01:29.045147 [INFO]: Id: 1 Name: Petr LastName: Petrov Age: 30 Position: Developer 2017-08-09T14:01:29.045845 [WARNING]: RemoveAccount. Employee with id 0 not found. 2017-08-09T14:01:29.046652 [INFO]: ~MyCompany 2017-08-09T14:02:05.766072 [INFO]: Stopping network application ... 2017-08-09T14:02:05.766169 [INFO]: Stopping server ... 2017-08-09T14:02:05.767180 [INFO]: Server is successfully stopped. 2017-08-09T14:02:05.767238 [INFO]: Network application is successfully stopped.
2017-08-09T14:01:29.028821 [INFO]: Starting network application on 0.0.0.0:55555 2017-08-09T14:01:29.028885 [INFO]: Starting client on 0.0.0.0:55555 2017-08-09T14:01:29.042510 [INFO]: Employee Id: 0 2017-08-09T14:01:29.043296 [INFO]: Employee Id: 1 2017-08-09T14:01:29.044082 [INFO]: Employee. Id: 0 Name: Ivan LastName: Ivanov Age: 25 Position: Manager 2017-08-09T14:01:29.044111 [INFO]: Employee. Id: 1 Name: Petr LastName: Petrov Age: 30 Position: Developer 2017-08-09T14:01:29.044818 [INFO]: Removed account 0 2017-08-09T14:01:29.045517 [INFO]: Employee. Id: 1 Name: Petr LastName: Petrov Age: 30 Position: Developer 2017-08-09T14:01:29.045544 [INFO]: Removed again account 0 2017-08-09T14:01:29.046357 [WARNING]: Error: [Mif::Remote::Proxy::RemoteCall] Failed to call remote method "IMyCompany::RemoveAccount" for instance with id "411bdde0-f186-402e-a170-4f899311a33d". Error: RemoveAccount. Employee with id 0 not found. 2017-08-09T14:01:29.046949 [INFO]: Client is successfully started. 2017-08-09T14:01:29.047311 [INFO]: Network application is successfully started. Press 'Enter' for quit. 2017-08-09T14:02:02.901773 [INFO]: Stopping network application ... 2017-08-09T14:02:02.901864 [INFO]: Stopping client ... 2017-08-09T14:02:02.901913 [INFO]: Client is successfully stopped. 2017-08-09T14:02:02.901959 [INFO]: Network application is successfully stopped.
[WARNING]: Error: [Mif::Remote::Proxy::RemoteCall] Failed to call remote method "IMyCompany::RemoveAccount" for instance with id "411bdde0-f186-402e-a170-4f899311a33d". Error: RemoveAccount. Employee with id 0 not found.
// MIF #include <mif/application/http_server.h> #include <mif/common/log.h> #include <mif/net/http/constants.h> class Application : public Mif::Application::HttpServer { public: using HttpServer::HttpServer; private: // Mif.Application.HttpServer virtual void Init(Mif::Net::Http::ServerHandlers &handlers) override final { handlers["/"] = [] (Mif::Net::Http::IInputPack const &request, Mif::Net::Http::IOutputPack &response) { auto data = request.GetData(); MIF_LOG(Info) << "Process request \"" << request.GetPath() << request.GetQuery() << "\"\t Data: " << (data.empty() ? std::string{"null"} : std::string{std::begin(data), std::end(data)}); response.SetCode(Mif::Net::Http::Code::Ok); response.SetHeader( Mif::Net::Http::Constants::Header::Connection::GetString(), Mif::Net::Http::Constants::Value::Connection::Close::GetString()); response.SetData(std::move(data)); }; } }; int main(int argc, char const **argv) { return Mif::Application::Run<Application>(argc, argv); }
curl -iv -X POST "http://localhost:55555/" -d 'Test data'
// STD #include <cstdlib> #include <future> #include <iostream> #include <string> // MIF #include <mif/net/http/connection.h> #include <mif/net/http/constants.h> int main() { try { std::string const host = "localhost"; std::string const port = "55555"; std::string const resource = "/"; std::promise<std::string> promise; auto future = promise.get_future(); Mif::Net::Http::Connection connection{host, port, [&promise] (Mif::Net::Http::IInputPack const &pack) { if (pack.GetCode() == Mif::Net::Http::Code::Ok) { auto const data = pack.GetData(); promise.set_value({std::begin(data), std::end(data)}); } else { promise.set_exception(std::make_exception_ptr( std::runtime_error{ "Failed to get response from server. Error: " + pack.GetReason() })); } } }; auto request = connection.CreateRequest(); request->SetHeader(Mif::Net::Http::Constants::Header::Connection::GetString(), Mif::Net::Http::Constants::Value::Connection::Close::GetString()); std::string data = "Test data!"; request->SetData({std::begin(data), std::end(data)}); connection.MakeRequest(Mif::Net::Http::Method::Type::Post, resource, std::move(request)); std::cout << "Response from server: " << future.get() << std::endl; } catch (std::exception const &e) { std::cerr << "Error: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
namespace Service { struct IAdmin : public Mif::Service::Inherit<Mif::Service::IService> { virtual void SetTitle(std::string const &title) = 0; virtual void SetBody(std::string const &body) = 0; virtual std::string GetPage() const = 0; }; } // namespace Service
class Application : public Mif::Application::HttpServer { //... private: // Mif.Application.HttpService virtual void Init(Mif::Net::Http::ServerHandlers &handlers) override final { std::string const adminLocation = "/admin"; std::string const viewLocation = "/view"; auto service = Mif::Service::Create<Service::Id::Service>(viewLocation); auto webService = Mif::Service::Cast<Mif::Net::Http::IWebService>(service); auto factory = Mif::Service::Make<Mif::Service::Factory, Mif::Service::Factory>(); factory->AddInstance(Service::Id::Service, service); std::chrono::microseconds const timeout{10000000}; auto clientFactory = Service::Ipc::MakeClientFactory(timeout, factory); handlers.emplace(adminLocation, Mif::Net::Http::MakeServlet(clientFactory)); handlers.emplace(viewLocation, Mif::Net::Http::MakeWebService(webService)); } };
namespace Service { namespace Detail { namespace { class WebService : public Mif::Service::Inherit < IAdmin, Mif::Net::Http::WebService > { public: WebService(std::string const &pathPrefix) { AddHandler(pathPrefix + "/stat", this, &WebService::Stat); AddHandler(pathPrefix + "/main-page", this, &WebService::MainPage); } private: // … // IAdmin virtual void SetTitle(std::string const &title) override final { // ... } // … // Web hadlers Result<Mif::Net::Http::JsonSerializer> Stat() { // ... std::map<std::string, std::int64_t> resp; // Fill resp return resp; } Result<Mif::Net::Http::PlainTextSerializer> MainPage(Prm<std::string, Name("format")> const &format) { // ... } }; } // namespace } // namespace Detail } // namespace Service MIF_SERVICE_CREATOR ( ::Service::Id::Service, ::Service::Detail::WebService, std::string )
curl "http://localhost:55555/view/main-page?format=text" curl "http://localhost:55555/view/main-page?format=html" curl "http://localhost:55555/view/main-page?format=json"
Source: https://habr.com/ru/post/239571/
All Articles