diff --git a/CMakeLists.txt b/CMakeLists.txt index 148a7872..d50a9696 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,4 +64,4 @@ add_subdirectory(test) find_package(Doxygen) if(DOXYGEN_FOUND) add_subdirectory(docs) -endif(DOXYGEN_FOUND) +endif(DOXYGEN_FOUND) \ No newline at end of file diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index a69b798d..adfab455 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -16,4 +16,4 @@ if(DOXYGEN_FOUND) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION doc OPTIONAL) else (DOXYGEN_FOUND) message("Doxygen need to be installed to generate the doxygen documentation") -endif (DOXYGEN_FOUND) +endif (DOXYGEN_FOUND) \ No newline at end of file diff --git a/src/snl/snippets/app/src/CMakeLists.txt b/src/snl/snippets/app/src/CMakeLists.txt index b46eb3fe..562e86dd 100644 --- a/src/snl/snippets/app/src/CMakeLists.txt +++ b/src/snl/snippets/app/src/CMakeLists.txt @@ -2,6 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -add_executable(snl_app SNLSnippet.cpp) +add_executable(snl_app SNLSnippet.cpp SNLUniverseSnippet.cpp) target_include_directories(snl_app SYSTEM BEFORE PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(snl_app Naja::SNL) \ No newline at end of file diff --git a/src/snl/snippets/app/src/SNLReceiver.cpp b/src/snl/snippets/app/src/SNLReceiver.cpp new file mode 100644 index 00000000..0cc5265b --- /dev/null +++ b/src/snl/snippets/app/src/SNLReceiver.cpp @@ -0,0 +1,69 @@ +#include + +#include "SNLDB.h" +#include "SNLCapnP.h" + +using namespace naja::SNL; + +namespace { + +void displayDesign(const SNLDesign* design) { + std::cout << design->getDescription() << std::endl; + for (auto term: design->getTerms()) { + std::cout << term->getDescription() << std::endl; + } + for (auto net: design->getNets()) { + std::cout << net->getDescription() << std::endl; + } + for (auto instance: design->getInstances()) { + std::cout << instance->getDescription() << std::endl; + } +} + +void displayLibrary(const SNLLibrary* lib) { + std::cout << lib->getDescription() << std::endl; + for (auto design: lib->getDesigns()) { + displayDesign(design); + } +} + +void displayDB(const SNLDB* db) { + std::cout << db->getDescription() << std::endl; + for (auto lib: db->getLibraries()) { + displayLibrary(lib); + } +} + +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + exit(34); + } + int port = std::stoi(argv[1]); + + SNLDB* db = SNLCapnP::receive(port); + if (db) { + std::cout << "Received " << db->getString() << std::endl; + displayDB(db); + } else { + std::cout << "No DB received" << std::endl; + } + return 0; +/* + auto topIns1 = top->getInstance(SNLName("ins1")); + std::cout << topIns1->getName().getString() << " instance terminals:" << std::endl; + for (auto instTerm: topIns1->getInstTerms()) { + std::cout << " - " << instTerm->getTerm()->getName().getString() << std::endl; + } + + auto topNet1 = top->getScalarNet(0); // net1 is an anonymous net at ID 0 + std::cout << topNet1->getString() << " components:" << std::endl; + for (auto component: topNet1->getComponents()) { + std::cout << " - " << component->getString() << std::endl; + } + +*/ + + return 0; +} diff --git a/src/snl/snippets/app/src/SNLSender.cpp b/src/snl/snippets/app/src/SNLSender.cpp new file mode 100644 index 00000000..df6bddf8 --- /dev/null +++ b/src/snl/snippets/app/src/SNLSender.cpp @@ -0,0 +1,41 @@ +#include + +#include "SNLUniverse.h" +#include "SNLCapnP.h" +#include "SNLUniverseSnippet.h" + +using namespace naja::SNL; + +int main(int argc, char* argv[]) { + if (argc != 3) { + exit(34); + } + std::string ipAddress = argv[1]; + int port = std::stoi(argv[2]); + + SNLUniverseSnippet::create(); + auto universe = SNLUniverse::get(); + assert(universe); + auto db = universe->getDB(1); + assert(db); + + std::cout << "Sending " << db->getString() << std::endl; + SNLCapnP::send(db, ipAddress, port); + return 0; +/* + auto topIns1 = top->getInstance(SNLName("ins1")); + std::cout << topIns1->getName().getString() << " instance terminals:" << std::endl; + for (auto instTerm: topIns1->getInstTerms()) { + std::cout << " - " << instTerm->getTerm()->getName().getString() << std::endl; + } + + auto topNet1 = top->getScalarNet(0); // net1 is an anonymous net at ID 0 + std::cout << topNet1->getString() << " components:" << std::endl; + for (auto component: topNet1->getComponents()) { + std::cout << " - " << component->getString() << std::endl; + } + +*/ + + return 0; +} diff --git a/src/snl/snippets/app/src/SNLSnippet.cpp b/src/snl/snippets/app/src/SNLSnippet.cpp index 8adfbae9..78a8e83f 100644 --- a/src/snl/snippets/app/src/SNLSnippet.cpp +++ b/src/snl/snippets/app/src/SNLSnippet.cpp @@ -2,79 +2,9 @@ // // SPDX-License-Identifier: Apache-2.0 -#include - -#include "SNLUniverse.h" -#include "SNLScalarNet.h" -#include "SNLScalarTerm.h" -#include "SNLBusTerm.h" -#include "SNLBusTermBit.h" -#include "SNLInstTerm.h" - -using namespace naja::SNL; +#include "SNLUniverseSnippet.h" int main() { - SNLUniverse::create(); - auto db = SNLDB::create(SNLUniverse::get()); - auto primLib = SNLLibrary::create(db, SNLLibrary::Type::Primitives, SNLName("primitives")); - auto prim0 = SNLDesign::create(primLib, SNLDesign::Type::Primitive); - auto prim1 = SNLDesign::create(primLib, SNLDesign::Type::Primitive); - - auto mylib = SNLLibrary::create(db, SNLName("mylib")); - - auto model1 = SNLDesign::create(mylib, SNLName("Model1")); - { - SNLScalarTerm::create(model1, SNLTerm::Direction::Input, SNLName("i0")); - SNLScalarTerm::create(model1, SNLTerm::Direction::Input, SNLName("i1")); - SNLScalarTerm::create(model1, SNLTerm::Direction::Output, SNLName("o")); - SNLParameter::create(model1, SNLName("PARAM0"), SNLParameter::Type::Decimal, "18"); - SNLParameter::create(model1, SNLName("PARAM1"), SNLParameter::Type::String, "OPTION2"); - SNLInstance::create(model1, prim0); // anonymous - SNLInstance::create(model1, prim1, SNLName("ins")); - } - - std::cout << model1->getName().getString() << " terms:" << std::endl; - for (auto term: model1->getTerms()) { - std::cout << " - " << term->getString() << std::endl; - } - - auto model2 = SNLDesign::create(mylib, SNLName("Model2")); - SNLBusTerm::create(model2, SNLTerm::Direction::Input, 4, 0, SNLName("i0")); - SNLScalarTerm::create(model2, SNLTerm::Direction::Input, SNLName("i1")); - SNLBusTerm::create(model2, SNLTerm::Direction::Output, 31, 0, SNLName("o")); - std::cout << model2->getName().getString() << " terms:" << std::endl; - for (auto term: model2->getTerms()) { - std::cout << " - " << term->getString() << std::endl; - } - - auto top = SNLDesign::create(mylib, SNLName("top")); - { - auto i = SNLScalarTerm::create(top, SNLTerm::Direction::Input, SNLName("i")); - auto o = SNLScalarTerm::create(top, SNLTerm::Direction::Input, SNLName("o")); - auto ins1 = SNLInstance::create(top, model1, SNLName("ins1")); - auto ins2 = SNLInstance::create(top, model2, SNLName("ins2")); - auto net1 = SNLScalarNet::create(top); //anonymous - auto net2 = SNLScalarNet::create(top); //anonymous - auto net3 = SNLScalarNet::create(top, SNLName("n")); - i->setNet(net1); - ins1->getInstTerm(ins1->getModel()->getScalarTerm(SNLName("i0")))->setNet(net1); - ins1->getInstTerm(ins1->getModel()->getScalarTerm(SNLName("i1")))->setNet(net3); - ins2->getInstTerm(ins2->getModel()->getScalarTerm(SNLName("i1")))->setNet(net3); - ins2->getInstTerm(ins2->getModel()->getBusTerm(SNLName("o"))->getBit(0))->setNet(net3); - o->setNet(net2); - } - - auto topIns1 = top->getInstance(SNLName("ins1")); - std::cout << topIns1->getName().getString() << " instance terminals:" << std::endl; - for (auto instTerm: topIns1->getInstTerms()) { - std::cout << " - " << instTerm->getTerm()->getName().getString() << std::endl; - } - - auto topNet1 = top->getScalarNet(0); // net1 is an anonymous net at ID 0 - std::cout << topNet1->getString() << " components:" << std::endl; - for (auto component: topNet1->getComponents()) { - std::cout << " - " << component->getString() << std::endl; - } - + SNLUniverseSnippet::create(); return 0; } \ No newline at end of file diff --git a/src/snl/snippets/app/src/SNLUniverseSnippet.cpp b/src/snl/snippets/app/src/SNLUniverseSnippet.cpp new file mode 100644 index 00000000..5a2a9520 --- /dev/null +++ b/src/snl/snippets/app/src/SNLUniverseSnippet.cpp @@ -0,0 +1,76 @@ +#include "SNLUniverseSnippet.h" + +#include + +#include "SNLUniverse.h" +#include "SNLScalarTerm.h" +#include "SNLBusTerm.h" +#include "SNLBusTermBit.h" +#include "SNLScalarNet.h" +#include "SNLInstTerm.h" + +using namespace naja::SNL; + +void SNLUniverseSnippet::create() { + SNLUniverse::create(); + auto db = SNLDB::create(SNLUniverse::get()); + auto primLib = SNLLibrary::create(db, SNLLibrary::Type::Primitives, SNLName("primitives")); + auto prim0 = SNLDesign::create(primLib, SNLDesign::Type::Primitive); + auto prim1 = SNLDesign::create(primLib, SNLDesign::Type::Primitive); + + auto mylib = SNLLibrary::create(db, SNLName("mylib")); + + auto model1 = SNLDesign::create(mylib, SNLName("Model1")); + { + SNLScalarTerm::create(model1, SNLTerm::Direction::Input, SNLName("i0")); + SNLScalarTerm::create(model1, SNLTerm::Direction::Input, SNLName("i1")); + SNLScalarTerm::create(model1, SNLTerm::Direction::Output, SNLName("o")); + SNLParameter::create(model1, SNLName("PARAM0"), SNLParameter::Type::Decimal, "18"); + SNLParameter::create(model1, SNLName("PARAM1"), SNLParameter::Type::String, "OPTION2"); + SNLInstance::create(model1, prim0); // anonymous + SNLInstance::create(model1, prim1, SNLName("ins")); + } + + std::cout << model1->getName().getString() << " terms:" << std::endl; + for (auto term: model1->getTerms()) { + std::cout << " - " << term->getString() << std::endl; + } + + auto model2 = SNLDesign::create(mylib, SNLName("Model2")); + SNLBusTerm::create(model2, SNLTerm::Direction::Input, 4, 0, SNLName("i0")); + SNLScalarTerm::create(model2, SNLTerm::Direction::Input, SNLName("i1")); + SNLBusTerm::create(model2, SNLTerm::Direction::Output, 31, 0, SNLName("o")); + std::cout << model2->getName().getString() << " terms:" << std::endl; + for (auto term: model2->getTerms()) { + std::cout << " - " << term->getString() << std::endl; + } + + auto top = SNLDesign::create(mylib, SNLName("top")); + { + auto i = SNLScalarTerm::create(top, SNLTerm::Direction::Input, SNLName("i")); + auto o = SNLScalarTerm::create(top, SNLTerm::Direction::Input, SNLName("o")); + auto ins1 = SNLInstance::create(top, model1, SNLName("ins1")); + auto ins2 = SNLInstance::create(top, model2, SNLName("ins2")); + auto net1 = SNLScalarNet::create(top); //anonymous + auto net2 = SNLScalarNet::create(top); //anonymous + auto net3 = SNLScalarNet::create(top, SNLName("n")); + i->setNet(net1); + ins1->getInstTerm(ins1->getModel()->getScalarTerm(SNLName("i0")))->setNet(net1); + ins1->getInstTerm(ins1->getModel()->getScalarTerm(SNLName("i1")))->setNet(net3); + ins2->getInstTerm(ins2->getModel()->getScalarTerm(SNLName("i1")))->setNet(net3); + ins2->getInstTerm(ins2->getModel()->getBusTerm(SNLName("o"))->getBit(0))->setNet(net3); + o->setNet(net2); + } + + auto topIns1 = top->getInstance(SNLName("ins1")); + std::cout << topIns1->getName().getString() << " instance terminals:" << std::endl; + for (auto instTerm: topIns1->getInstTerms()) { + std::cout << " - " << instTerm->getTerm()->getName().getString() << std::endl; + } + + auto topNet1 = top->getScalarNet(0); // net1 is an anonymous net at ID 0 + std::cout << topNet1->getString() << " components:" << std::endl; + for (auto component: topNet1->getComponents()) { + std::cout << " - " << component->getString() << std::endl; + } +} diff --git a/src/snl/snippets/app/src/SNLUniverseSnippet.h b/src/snl/snippets/app/src/SNLUniverseSnippet.h new file mode 100644 index 00000000..38d929df --- /dev/null +++ b/src/snl/snippets/app/src/SNLUniverseSnippet.h @@ -0,0 +1,9 @@ +#ifndef __SNL_UNIVERSE_SNIPPET_H_ +#define __SNL_UNIVERSE_SNIPPET_H_ + +class SNLUniverseSnippet { + public: + static void create(); +}; + +#endif /* __SNL_UNIVERSE_SNIPPET_H_ */ diff --git a/src/snl/snippets/cpp/CMakeLists.txt b/src/snl/snippets/cpp/CMakeLists.txt index 6a252405..fe5a9aea 100644 --- a/src/snl/snippets/cpp/CMakeLists.txt +++ b/src/snl/snippets/cpp/CMakeLists.txt @@ -2,5 +2,19 @@ # # SPDX-License-Identifier: Apache-2.0 -add_executable(snl_snippet ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLSnippet.cpp) -target_link_libraries(snl_snippet naja_snl) \ No newline at end of file +add_executable(snl_snippet + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLUniverseSnippet.cpp + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLSnippet.cpp +) +add_executable(snl_receiver + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLUniverseSnippet.cpp + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLReceiver.cpp +) +add_executable(snl_sender + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLUniverseSnippet.cpp + ${PROJECT_SOURCE_DIR}/src/snl/snippets/app/src/SNLSender.cpp +) + +target_link_libraries(snl_snippet naja_snl) +target_link_libraries(snl_receiver naja_snl_dump) +target_link_libraries(snl_sender naja_snl_dump) \ No newline at end of file diff --git a/src/snl/snl/kernel/SNLDB.cpp b/src/snl/snl/kernel/SNLDB.cpp index 354cc054..c4cc803b 100644 --- a/src/snl/snl/kernel/SNLDB.cpp +++ b/src/snl/snl/kernel/SNLDB.cpp @@ -12,6 +12,7 @@ #include "SNLUniverse.h" #include "SNLDB0.h" #include "SNLException.h" +#include "SNLMacros.h" namespace naja { namespace SNL { @@ -173,6 +174,15 @@ SNLID SNLDB::getSNLID() const { return SNLID(id_); } +void SNLDB::setID(SNLID::DBID id) { + if (SNLUniverse::get()->isDB0(this)) { + //error + } + SNLUniverse::get()->removeDB(this); + id_ = id; + SNLUniverse::get()->addDB(this); +} + bool SNLDB::isTopDB() const { return SNLUniverse::get()->getTopDB() == this; } @@ -192,6 +202,12 @@ void SNLDB::setTopDesign(SNLDesign* design) { topDesign_ = design; } +bool SNLDB::deepCompare(const SNLDB* other, std::string& reason) const { + //don't compare SNLDB ID + DEEP_COMPARE_MEMBER(Libraries) + return true; +} + void SNLDB::mergeAssigns() { for (auto library: getLibraries()) { if (not library->isPrimitives()) { diff --git a/src/snl/snl/kernel/SNLDB.h b/src/snl/snl/kernel/SNLDB.h index 56977904..4b2cff66 100644 --- a/src/snl/snl/kernel/SNLDB.h +++ b/src/snl/snl/kernel/SNLDB.h @@ -31,6 +31,12 @@ class SNLDB final: public SNLObject { SNLID::DBID getID() const { return id_; } SNLID getSNLID() const; + ///\brief Change the SNLDB id. Main purpose: compare DBs after save and load. + ///\param id new DBID + ///\warning use with caution: all DB objects SNLIDs will be modified, as the DB id part of SNLID will + ///be modified. + void setID(SNLID::DBID id); + ///\return the SNLLibrary in this SNLDB with SNLID::LibraryID:id SNLLibrary* getLibrary(SNLID::LibraryID id) const; ///\return the SNLLibrary in this SNLDB with SNLName:name @@ -62,6 +68,9 @@ class SNLDB final: public SNLObject { bool operator<(const SNLDB &rdb) const { return getSNLID() < rdb.getSNLID(); } + + bool deepCompare(const SNLDB* db, std::string& reason) const; + private: SNLDB() = default; SNLDB(SNLID::DBID id); diff --git a/src/snl/snl/kernel/SNLDesign.cpp b/src/snl/snl/kernel/SNLDesign.cpp index 6416882e..734d3052 100644 --- a/src/snl/snl/kernel/SNLDesign.cpp +++ b/src/snl/snl/kernel/SNLDesign.cpp @@ -480,6 +480,21 @@ bool SNLDesign::isTopDesign() const { return getDB()->getTopDesign() == this; } +bool SNLDesign::deepCompare(const SNLDesign* other, std::string& reason) const { + if (getID() not_eq other->getID()) { + return false; + } + if (name_ not_eq other->getName()) { + return false; + } + if (type_ not_eq other->getType()) { + return false; + } + DEEP_COMPARE_MEMBER(Parameters) + DEEP_COMPARE_MEMBER(Instances) + return true; +} + SNLID SNLDesign::getSNLID() const { return SNLID(getDB()->getID(), library_->getID(), getID()); } diff --git a/src/snl/snl/kernel/SNLDesign.h b/src/snl/snl/kernel/SNLDesign.h index f35f2bd7..a026bb58 100644 --- a/src/snl/snl/kernel/SNLDesign.h +++ b/src/snl/snl/kernel/SNLDesign.h @@ -156,9 +156,10 @@ class SNLDesign final: public SNLObject { bool isPrimitive() const { return type_ == Type::Primitive; } ///\return true if this SNLDesign is a hierarchy leaf (blackbox or primitive). bool isLeaf() const { return isBlackBox() or isPrimitive(); } - + ///\return true if this SNLDesign is a top design. bool isTopDesign() const; + bool deepCompare(const SNLDesign* design, std::string& reason) const; void mergeAssigns(); const char* getTypeName() const override; diff --git a/src/snl/snl/kernel/SNLInstParameter.cpp b/src/snl/snl/kernel/SNLInstParameter.cpp index 447950fc..dbef1b40 100644 --- a/src/snl/snl/kernel/SNLInstParameter.cpp +++ b/src/snl/snl/kernel/SNLInstParameter.cpp @@ -54,6 +54,19 @@ SNLName SNLInstParameter::getName() const { return parameter_->getName(); } +bool SNLInstParameter::deepCompare(const SNLInstParameter* other, std::string& reason) const { + if (getName() not_eq other->getName()) { + reason += "In " + getInstance()->getDescription(); + reason += ", different instance parameters: "; + reason += getDescription() + " and " + other->getDescription(); + return false; + } + if (getValue() not_eq other->getValue()) { + return false; + } + return true; +} + //LCOV_EXCL_START const char* SNLInstParameter::getTypeName() const { return "SNLInstParameter"; diff --git a/src/snl/snl/kernel/SNLInstParameter.h b/src/snl/snl/kernel/SNLInstParameter.h index 588b8e68..a3621f73 100644 --- a/src/snl/snl/kernel/SNLInstParameter.h +++ b/src/snl/snl/kernel/SNLInstParameter.h @@ -44,6 +44,7 @@ class SNLInstParameter { return lp.getName() < rn; } }; + bool deepCompare(const SNLInstParameter* other, std::string& reason) const; private: SNLInstParameter(SNLInstance* instance, SNLParameter* parameter, const std::string& value); static void preCreate(SNLInstance* instance, SNLParameter* parameter); diff --git a/src/snl/snl/kernel/SNLInstance.cpp b/src/snl/snl/kernel/SNLInstance.cpp index bfebb9f0..5f69ff8c 100644 --- a/src/snl/snl/kernel/SNLInstance.cpp +++ b/src/snl/snl/kernel/SNLInstance.cpp @@ -128,6 +128,18 @@ void SNLInstance::postCreate() { commonPostCreate(); } +bool SNLInstance::deepCompare(const SNLInstance* other, std::string& reason) const { + if (getID() not_eq other->getID()) { + return false; + } + if (name_ not_eq other->getName()) { + return false; + } + //FIXME compare models: same library id, same id + DEEP_COMPARE_MEMBER(InstParameters) + return true; +} + void SNLInstance::createInstTerm(SNLBitTerm* term) { instTerms_.push_back(SNLInstTerm::create(this, term)); } diff --git a/src/snl/snl/kernel/SNLInstance.h b/src/snl/snl/kernel/SNLInstance.h index 7eca2016..2d311bee 100644 --- a/src/snl/snl/kernel/SNLInstance.h +++ b/src/snl/snl/kernel/SNLInstance.h @@ -57,6 +57,7 @@ class SNLInstance final: public SNLDesignObject { SNLID::DesignObjectID getID() const { return id_; } SNLID getSNLID() const override; SNLID::DesignObjectReference getReference() const; + bool deepCompare(const SNLInstance* other, std::string& reason) const; SNLName getName() const { return name_; } void setName(const SNLName& name); diff --git a/src/snl/snl/kernel/SNLLibrary.cpp b/src/snl/snl/kernel/SNLLibrary.cpp index 0ce90075..f54c4596 100644 --- a/src/snl/snl/kernel/SNLLibrary.cpp +++ b/src/snl/snl/kernel/SNLLibrary.cpp @@ -10,6 +10,7 @@ #include "SNLDB.h" #include "SNLException.h" +#include "SNLMacros.h" namespace naja { namespace SNL { @@ -296,6 +297,20 @@ void SNLLibrary::removeDesign(SNLDesign* design) { designs_.erase(*design); } +bool SNLLibrary::deepCompare(const SNLLibrary* other, std::string& reason) const { + if (getID() not_eq other->getID()) { + return false; + } + if (name_ not_eq other->getName()) { + return false; + } + if (type_ not_eq other->getType()) { + return false; + } + DEEP_COMPARE_MEMBER(Designs) + return true; +} + void SNLLibrary::mergeAssigns() { if (isPrimitives()) { return; @@ -350,4 +365,4 @@ SNLID SNLLibrary::getSNLID() const { return SNLID(getDB()->getID(), getID()); } -}} // namespace SNL // namespace naja +}} // namespace SNL // namespace naja \ No newline at end of file diff --git a/src/snl/snl/kernel/SNLLibrary.h b/src/snl/snl/kernel/SNLLibrary.h index b90b5273..47aafcf2 100644 --- a/src/snl/snl/kernel/SNLLibrary.h +++ b/src/snl/snl/kernel/SNLLibrary.h @@ -81,6 +81,8 @@ class SNLLibrary final: public SNLObject { friend bool operator< (const SNLLibrary &ll, const SNLLibrary &rl) { return ll.getSNLID() < rl.getSNLID(); } + + bool deepCompare(const SNLLibrary* library, std::string& reason) const; private: static void preCreate(SNLDB* db, Type type, const SNLName& name); static void preCreate(SNLDB* db, SNLID::LibraryID id, const Type type, const SNLName& name); diff --git a/src/snl/snl/kernel/SNLMacros.h b/src/snl/snl/kernel/SNLMacros.h index aca351f9..97d5efc0 100644 --- a/src/snl/snl/kernel/SNLMacros.h +++ b/src/snl/snl/kernel/SNLMacros.h @@ -41,6 +41,30 @@ void TYPE::setNet(SNLNet* net) { \ } \ } +#define DEEP_COMPARE_MEMBER(MEMBER) \ +{ \ + auto this##MEMBER##It = get##MEMBER().begin(); \ + auto other##MEMBER##It = other->get##MEMBER().begin(); \ + while (this##MEMBER##It not_eq get##MEMBER().end()) { \ + if (other##MEMBER##It == other->get##MEMBER().end()) { \ + reason += "In " + getDescription() + ", different size of " #MEMBER + ":" ; \ + reason += std::to_string(get##MEMBER().size()) + " vs "; \ + reason += std::to_string(other->get##MEMBER().size()); \ + return false; \ + } \ + auto this##MEMBER = *this##MEMBER##It; \ + auto other##MEMBER = *other##MEMBER##It; \ + if (not this##MEMBER->deepCompare(other##MEMBER, reason)) { \ + return false; \ + } \ + ++this##MEMBER##It; \ + ++other##MEMBER##It; \ + } \ + if (other##MEMBER##It not_eq other->get##MEMBER().end()) { \ + return false; \ + } \ +} + #define DESIGN_OBJECT_SET_NAME(TYPE, METHOD_TYPE, STRING) \ void TYPE::setName(const SNLName& name) { \ if (name_ == name) { \ diff --git a/src/snl/snl/kernel/SNLParameter.cpp b/src/snl/snl/kernel/SNLParameter.cpp index 5eac35a2..01b73984 100644 --- a/src/snl/snl/kernel/SNLParameter.cpp +++ b/src/snl/snl/kernel/SNLParameter.cpp @@ -59,6 +59,16 @@ void SNLParameter::destroyFromDesign() { delete this; } +bool SNLParameter::deepCompare(const SNLParameter* other, std::string& reason) const { + if (getName() != other->getName()) { + return false; + } + if (getValue() not_eq other->getValue()) { + return false; + } + return true; +} + //LCOV_EXCL_START const char* SNLParameter::getTypeName() const { return "SNLParameter"; diff --git a/src/snl/snl/kernel/SNLParameter.h b/src/snl/snl/kernel/SNLParameter.h index c61f8576..1e6851e6 100644 --- a/src/snl/snl/kernel/SNLParameter.h +++ b/src/snl/snl/kernel/SNLParameter.h @@ -58,6 +58,7 @@ class SNLParameter { return lp.getName() < rn; } }; + bool deepCompare(const SNLParameter* other, std::string& reason) const; private: SNLParameter(SNLDesign* design, const SNLName& name, Type type, const std::string& value); static void preCreate(SNLDesign* design, const SNLName& name); diff --git a/src/snl/snl/serialization/capnp/SNLCapnP.cpp b/src/snl/snl/serialization/capnp/SNLCapnP.cpp index 2b501743..367ba1c0 100644 --- a/src/snl/snl/serialization/capnp/SNLCapnP.cpp +++ b/src/snl/snl/serialization/capnp/SNLCapnP.cpp @@ -6,6 +6,9 @@ #include "SNLCapnP.h" #include "SNLDumpManifest.h" +#include "SNLDB.h" + +using boost::asio::ip::tcp; namespace naja { namespace SNL { @@ -16,10 +19,45 @@ void SNLCapnP::dump(const SNLDB* db, const std::filesystem::path& path) { dumpImplementation(db, path/ImplementationName); } +void SNLCapnP::send(const SNLDB* db, const std::string& ipAddress, uint16_t port) { + send(db, ipAddress, port, db->getID()); +} + +void SNLCapnP::send(const SNLDB* db, const std::string& ipAddress, uint16_t port, SNLID::DBID forceDBID) { + boost::asio::io_service io_service; + //socket creation + tcp::socket socket(io_service); + socket.connect(tcp::endpoint(boost::asio::ip::address::from_string(ipAddress), port)); + sendInterface(db, socket, forceDBID); + sendImplementation(db, socket, forceDBID); +} + SNLDB* SNLCapnP::load(const std::filesystem::path& path) { loadInterface(path/InterfaceName); SNLDB* db = loadImplementation(path/ImplementationName); return db; } -}} // namespace SNL // namespace naja \ No newline at end of file +boost::asio::ip::tcp::socket SNLCapnP::getSocket(uint16_t port) { + boost::asio::io_service io_service; + //listen for new connection + tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port)); + //socket creation + tcp::socket socket(io_service); + //waiting for connection + acceptor.accept(socket); + return std::move(socket); +} + +SNLDB* SNLCapnP::receive(boost::asio::ip::tcp::socket& socket) { + receiveInterface(socket); + SNLDB* db = receiveImplementation(socket); + return db; +} + +SNLDB* SNLCapnP::receive(uint16_t port) { + auto socket = getSocket(port); + return receive(socket); +} + +}} // namespace SNL // namespace naja diff --git a/src/snl/snl/serialization/capnp/SNLCapnP.h b/src/snl/snl/serialization/capnp/SNLCapnP.h index 3847cdf4..2b0640ad 100644 --- a/src/snl/snl/serialization/capnp/SNLCapnP.h +++ b/src/snl/snl/serialization/capnp/SNLCapnP.h @@ -8,6 +8,8 @@ #define __SNL_CAPNP_H_ #include +#include +#include "SNLID.h" namespace naja { namespace SNL { @@ -15,14 +17,39 @@ class SNLDB; class SNLCapnP { public: + static boost::asio::ip::tcp::socket getSocket(uint16_t port=0); static constexpr std::string_view InterfaceName = "db_interface.snl"; static constexpr std::string_view ImplementationName = "db_implementation.snl"; static void dump(const SNLDB* db, const std::filesystem::path& dumpPath); + static void send(const SNLDB* db, const std::string& ipAddress, uint16_t port); + static void send(const SNLDB* db, const std::string& ipAddress, uint16_t port, SNLID::DBID forceDBID); static SNLDB* load(const std::filesystem::path& dumpPath); - static void dumpInterface(const SNLDB* snlDB, const std::filesystem::path& interfacePath); + static SNLDB* receive(boost::asio::ip::tcp::socket& socket); + static SNLDB* receive(uint16_t port); + + static void dumpInterface(const SNLDB* db, int fileDescriptor); + static void dumpInterface(const SNLDB* db, int fileDescriptor, SNLID::DBID forceDBID); + static void dumpInterface(const SNLDB* db, const std::filesystem::path& interfacePath); + static void sendInterface(const SNLDB* db, const std::string& ipAddress, uint16_t port); + static void sendInterface(const SNLDB* db, boost::asio::ip::tcp::socket& socket); + static void sendInterface(const SNLDB* db, boost::asio::ip::tcp::socket& socket, SNLID::DBID forceDBID); + + static SNLDB* loadInterface(int fileDescriptor); static SNLDB* loadInterface(const std::filesystem::path& interfacePath); + static SNLDB* receiveInterface(uint16_t port); + static SNLDB* receiveInterface(boost::asio::ip::tcp::socket& socket); + + static void dumpImplementation(const SNLDB* db, int fileDescriptor); + static void dumpImplementation(const SNLDB* db, int fileDescriptor, SNLID::DBID forceDBID); static void dumpImplementation(const SNLDB* db, const std::filesystem::path& implementationPath); + static void sendImplementation(const SNLDB* db, const std::string& ipAddress, uint16_t port); + static void sendImplementation(const SNLDB* db, boost::asio::ip::tcp::socket& socket); + static void sendImplementation(const SNLDB* db, boost::asio::ip::tcp::socket& socket, SNLID::DBID forceDBID); + + static SNLDB* loadImplementation(int fileDescriptor); static SNLDB* loadImplementation(const std::filesystem::path& implementationPath); + static SNLDB* receiveImplementation(uint16_t port); + static SNLDB* receiveImplementation(boost::asio::ip::tcp::socket& socket); }; }} // namespace SNL // namespace naja diff --git a/src/snl/snl/serialization/capnp/SNLCapnPImplementation.cpp b/src/snl/snl/serialization/capnp/SNLCapnPImplementation.cpp index 75976858..6a253b2c 100644 --- a/src/snl/snl/serialization/capnp/SNLCapnPImplementation.cpp +++ b/src/snl/snl/serialization/capnp/SNLCapnPImplementation.cpp @@ -7,9 +7,11 @@ #include "SNLCapnP.h" #include +#include +#include +#include #include -#include #include #include @@ -26,10 +28,11 @@ #include "SNLInstTerm.h" #include "SNLException.h" +using boost::asio::ip::tcp; + namespace { using namespace naja::SNL; - void dumpInstParameter( DBImplementation::LibraryImplementation::DesignImplementation::Instance::InstParameter::Builder& instParameter, const SNLInstParameter* snlInstParameter) { @@ -50,11 +53,14 @@ void dumpInstance( modelReferenceBuilder.setDbID(modelReference.dbID_); modelReferenceBuilder.setLibraryID(modelReference.getDBDesignReference().libraryID_); modelReferenceBuilder.setDesignID(modelReference.getDBDesignReference().designID_); - size_t id = 0; - auto instParameters = instance.initInstParameters(snlInstance->getInstParameters().size()); - for (auto instParameter: snlInstance->getInstParameters()) { - auto instParameterBuilder = instParameters[id++]; - dumpInstParameter(instParameterBuilder, instParameter); + size_t instParametersSize = snlInstance->getInstParameters().size(); + if (instParametersSize > 0) { + auto instParameters = instance.initInstParameters(instParametersSize); + size_t id = 0; + for (auto instParameter: snlInstance->getInstParameters()) { + auto instParameterBuilder = instParameters[id++]; + dumpInstParameter(instParameterBuilder, instParameter); + } } } @@ -419,11 +425,15 @@ void loadLibraryImplementation(SNLDB* db, const DBImplementation::LibraryImpleme namespace naja { namespace SNL { -void SNLCapnP::dumpImplementation(const SNLDB* snlDB, const std::filesystem::path& implementationPath) { +void SNLCapnP::dumpImplementation(const SNLDB* snlDB, int fileDescriptor) { + dumpImplementation(snlDB, fileDescriptor, snlDB->getID()); +} + +void SNLCapnP::dumpImplementation(const SNLDB* snlDB, int fileDescriptor, SNLID::DBID forceDBID) { ::capnp::MallocMessageBuilder message; DBImplementation::Builder db = message.initRoot(); - db.setId(snlDB->getID()); + db.setId(forceDBID); auto libraries = db.initLibraryImplementations(snlDB->getLibraries().size()); size_t id = 0; @@ -431,19 +441,39 @@ void SNLCapnP::dumpImplementation(const SNLDB* snlDB, const std::filesystem::pat auto libraryImplementationBuilder = libraries[id++]; dumpLibraryImplementation(libraryImplementationBuilder, snlLibrary); } + writePackedMessageToFd(fileDescriptor, message); +} +void SNLCapnP::dumpImplementation(const SNLDB* snlDB, const std::filesystem::path& implementationPath) { int fd = open( implementationPath.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - writePackedMessageToFd(fd, message); + dumpImplementation(snlDB, fd); close(fd); } -SNLDB* SNLCapnP::loadImplementation(const std::filesystem::path& implementationPath) { - //FIXME: verify if file can be opened - int fd = open(implementationPath.c_str(), O_RDONLY); - ::capnp::PackedFdMessageReader message(fd); +void SNLCapnP::sendImplementation(const SNLDB* db, tcp::socket& socket) { + sendImplementation(db, socket, db->getID()); +} + +void SNLCapnP::sendImplementation(const SNLDB* db, tcp::socket& socket, SNLID::DBID forceDBID) { + dumpImplementation(db, socket.native_handle(), forceDBID); +} + +void SNLCapnP::sendImplementation( + const SNLDB* db, + const std::string& ipAddress, + uint16_t port) { + boost::asio::io_service io_service; + //socket creation + tcp::socket socket(io_service); + socket.connect(tcp::endpoint(boost::asio::ip::address::from_string(ipAddress), port)); + sendImplementation(db, socket); +} + +SNLDB* SNLCapnP::loadImplementation(int fileDescriptor) { + ::capnp::PackedFdMessageReader message(fileDescriptor); DBImplementation::Reader dbImplementation = message.getRoot(); auto dbID = dbImplementation.getId(); @@ -464,4 +494,26 @@ SNLDB* SNLCapnP::loadImplementation(const std::filesystem::path& implementationP return snldb; } +SNLDB* SNLCapnP::loadImplementation(const std::filesystem::path& implementationPath) { + //FIXME: verify if file can be opened + int fd = open(implementationPath.c_str(), O_RDONLY); + return loadImplementation(fd); +} + +SNLDB* SNLCapnP::receiveImplementation(tcp::socket& socket) { + return loadImplementation(socket.native_handle()); +} + +SNLDB* SNLCapnP::receiveImplementation(uint16_t port) { + boost::asio::io_service io_service; + //listen for new connection + tcp::acceptor acceptor_(io_service, tcp::endpoint(tcp::v4(), port)); + //socket creation + tcp::socket socket(io_service); + //waiting for connection + acceptor_.accept(socket); + SNLDB* db = receiveImplementation(socket); + return db; +} + }} // namespace SNL // namespace naja diff --git a/src/snl/snl/serialization/capnp/SNLCapnPInterface.cpp b/src/snl/snl/serialization/capnp/SNLCapnPInterface.cpp index 4c749ddf..c9996289 100644 --- a/src/snl/snl/serialization/capnp/SNLCapnPInterface.cpp +++ b/src/snl/snl/serialization/capnp/SNLCapnPInterface.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,8 @@ #include "SNLBusTerm.h" #include "SNLException.h" +using boost::asio::ip::tcp; + namespace { using namespace naja; @@ -131,22 +134,28 @@ void dumpDesignInterface( }; dumpProperties(designInterface, snlDesign, lambda); - size_t id = 0; - auto parameters = designInterface.initParameters(snlDesign->getParameters().size()); - for (auto parameter: snlDesign->getParameters()) { - auto parameterBuilder = parameters[id++]; - dumpParameter(parameterBuilder, parameter); + size_t parametersSize = snlDesign->getParameters().size(); + if (parametersSize > 0) { + size_t id = 0; + auto parameters = designInterface.initParameters(parametersSize); + for (auto parameter: snlDesign->getParameters()) { + auto parameterBuilder = parameters[id++]; + dumpParameter(parameterBuilder, parameter); + } } - id = 0; - auto terms = designInterface.initTerms(snlDesign->getTerms().size()); - for (auto term: snlDesign->getTerms()) { - auto termBuilder = terms[id++]; - if (auto scalarTerm = dynamic_cast(term)) { - dumpScalarTerm(termBuilder, scalarTerm); - } else { - auto busTerm = static_cast(term); - dumpBusTerm(termBuilder, busTerm); + size_t termsSize = snlDesign->getTerms().size(); + if (termsSize > 0) { + size_t id = 0; + auto terms = designInterface.initTerms(termsSize); + for (auto term: snlDesign->getTerms()) { + auto termBuilder = terms[id++]; + if (auto scalarTerm = dynamic_cast(term)) { + dumpScalarTerm(termBuilder, scalarTerm); + } else { + auto busTerm = static_cast(term); + dumpBusTerm(termBuilder, busTerm); + } } } } @@ -160,7 +169,7 @@ DBInterface::LibraryType SNLtoCapnPLibraryType(SNLLibrary::Type type) { //LCOV_EXCL_START case SNLLibrary::Type::InDB0: throw SNLException("Unexpected InDB0 Library type while loading Library"); - ////LCOV_EXCL_STOP + //LCOV_EXCL_STOP } return DBInterface::LibraryType::STANDARD; //LCOV_EXCL_LINE } @@ -359,11 +368,15 @@ void loadLibraryInterface(NajaObject* parent, const DBInterface::LibraryInterfac namespace naja { namespace SNL { -void SNLCapnP::dumpInterface(const SNLDB* snlDB, const std::filesystem::path& interfacePath) { +void SNLCapnP::dumpInterface(const SNLDB* snlDB, int fileDescriptor) { + dumpInterface(snlDB, fileDescriptor, snlDB->getID()); +} + +void SNLCapnP::dumpInterface(const SNLDB* snlDB, int fileDescriptor, SNLID::DBID forceDBID) { ::capnp::MallocMessageBuilder message; DBInterface::Builder db = message.initRoot(); - db.setId(snlDB->getID()); + db.setId(forceDBID); auto lambda = [](DBInterface::Builder& builder, size_t nbProperties) { return builder.initProperties(nbProperties); }; @@ -384,18 +397,40 @@ void SNLCapnP::dumpInterface(const SNLDB* snlDB, const std::filesystem::path& in designReferenceBuilder.setDesignID(designReference.getDBDesignReference().designID_); } + writePackedMessageToFd(fileDescriptor, message); +} + +void SNLCapnP::dumpInterface(const SNLDB* snlDB, const std::filesystem::path& interfacePath) { int fd = open( interfacePath.c_str(), O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - writePackedMessageToFd(fd, message); + + dumpInterface(snlDB, fd); close(fd); } -SNLDB* SNLCapnP::loadInterface(const std::filesystem::path& interfacePath) { - //FIXME: verify if file can be opened - int fd = open(interfacePath.c_str(), O_RDONLY); - ::capnp::PackedFdMessageReader message(fd); +void SNLCapnP::sendInterface(const SNLDB* db, tcp::socket& socket, SNLID::DBID forceDBID) { + dumpInterface(db, socket.native_handle(), forceDBID); +} + +void SNLCapnP::sendInterface(const SNLDB* db, tcp::socket& socket) { + sendInterface(db, socket, db->getID()); +} + +void SNLCapnP::sendInterface( + const SNLDB* db, + const std::string& ipAddress, + uint16_t port) { + boost::asio::io_service io_service; + //socket creation + tcp::socket socket(io_service); + socket.connect(tcp::endpoint( boost::asio::ip::address::from_string(ipAddress), port)); + sendInterface(db, socket); +} + +SNLDB* SNLCapnP::loadInterface(int fileDescriptor) { + ::capnp::PackedFdMessageReader message(fileDescriptor); DBInterface::Reader dbInterface = message.getRoot(); auto dbID = dbInterface.getId(); @@ -436,4 +471,26 @@ SNLDB* SNLCapnP::loadInterface(const std::filesystem::path& interfacePath) { return snldb; } +SNLDB* SNLCapnP::loadInterface(const std::filesystem::path& interfacePath) { + //FIXME: verify if file can be opened + int fd = open(interfacePath.c_str(), O_RDONLY); + return loadInterface(fd); +} + +SNLDB* SNLCapnP::receiveInterface(tcp::socket& socket) { + return loadInterface(socket.native_handle()); +} + +SNLDB* SNLCapnP::receiveInterface(uint16_t port) { + boost::asio::io_service io_service; + //listen for new connection + tcp::acceptor acceptor_(io_service, tcp::endpoint(tcp::v4(), port)); + //socket creation + tcp::socket socket(io_service); + //waiting for connection + acceptor_.accept(socket); + SNLDB* db = receiveInterface(socket); + return db; +} + }} // namespace SNL // namespace naja diff --git a/test/snl/python/snl_wrapping/test_snldb.py b/test/snl/python/snl_wrapping/test_snldb.py index 118ca843..8f2bb41d 100644 --- a/test/snl/python/snl_wrapping/test_snldb.py +++ b/test/snl/python/snl_wrapping/test_snldb.py @@ -19,7 +19,6 @@ def testCreationError(self): u = snl.SNLUniverse.get() with self.assertRaises(RuntimeError) as context: snl.SNLDB.create("ERROR") - def testDestroy(self): u = snl.SNLUniverse.get() db = snl.SNLDB.create(u) diff --git a/test/snl/snl/serialization/capnp/CMakeLists.txt b/test/snl/snl/serialization/capnp/CMakeLists.txt index 236c852d..9f10800b 100644 --- a/test/snl/snl/serialization/capnp/CMakeLists.txt +++ b/test/snl/snl/serialization/capnp/CMakeLists.txt @@ -4,10 +4,15 @@ set(snl_capnp_tests SNLDumpManifestTest.cpp SNLCapnPTest0.cpp SNLCapnPTest1.cpp + SNLCapnPStreamingReceiveTest.cpp ) +#add_executable(snlSenderTest SNLSender.cpp) add_executable(snlCapnPTests ${snl_capnp_tests}) + +#target_link_libraries(snlSenderTest naja_snl_dump) + target_compile_definitions(snlCapnPTests PRIVATE SNL_CAPNP_TEST_PATH="${CMAKE_CURRENT_BINARY_DIR}") target_link_libraries(snlCapnPTests naja_snl_dump gtest gmock gtest_main) diff --git a/test/snl/snl/serialization/capnp/SNLCapnPStreamingReceiveTest.cpp b/test/snl/snl/serialization/capnp/SNLCapnPStreamingReceiveTest.cpp new file mode 100644 index 00000000..af8cef64 --- /dev/null +++ b/test/snl/snl/serialization/capnp/SNLCapnPStreamingReceiveTest.cpp @@ -0,0 +1,73 @@ +#include "gtest/gtest.h" + +#include + +#include "SNLUniverse.h" +#include "SNLDB.h" +#include "SNLScalarTerm.h" +#include "SNLBusTerm.h" +#include "SNLBusTermBit.h" +#include "SNLScalarNet.h" +#include "SNLBusNet.h" +#include "SNLBusNetBit.h" +#include "SNLInstTerm.h" + +#include "SNLCapnP.h" + +using namespace naja::SNL; + +#ifndef SNL_CAPNP_TEST_PATH +#define SNL_CAPNP_TEST_PATH "Undefined" +#endif + +class SNLCapnPStreamingReceiveTest: public ::testing::Test { + //Test libraries + protected: + void SetUp() override { + SNLUniverse* universe = SNLUniverse::create(); + db_ = SNLDB::create(universe); + // + } + void TearDown() override { + if (SNLUniverse::get()) { + SNLUniverse::get()->destroy(); + } + } + protected: + SNLDB* db_; +}; + +using path = std::filesystem::path; + +namespace { + +SNLDB* receive(uint16_t port) { + return SNLCapnP::receive(port); +} + +} + +TEST_F(SNLCapnPStreamingReceiveTest, test0) { +#if 0 + SNLDB* db = nullptr; + std::thread receiverThread([&]{ std::cerr << "Starting receiver" << std::endl; db = SNLCapnP::receive(44444); }); + receiverThread.detach(); + std::this_thread::sleep_for(std::chrono::seconds(4)); + + ASSERT_NE(nullptr, db_); + std::cerr << "Sending DB" << std::endl; + SNLCapnP::send(db_, "127.0.0.1", 44444, 2); + + //Wait for DB to be received, max 5s + unsigned nbSecs = 0; + while (not db and nbSecs < 5) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + ++nbSecs; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + ASSERT_NE(nullptr, db); + std::string reason; + EXPECT_TRUE(db_->deepCompare(db, reason)); + EXPECT_TRUE(reason.empty()); +#endif +} \ No newline at end of file diff --git a/test/snl/snl/serialization/capnp/SNLCapnPTest0.cpp b/test/snl/snl/serialization/capnp/SNLCapnPTest0.cpp index 65355105..26a89b90 100644 --- a/test/snl/snl/serialization/capnp/SNLCapnPTest0.cpp +++ b/test/snl/snl/serialization/capnp/SNLCapnPTest0.cpp @@ -107,25 +107,29 @@ TEST_F(SNLCapNpTest0, test0) { } SNLCapnP::dump(db_, outPath); - db_->destroy(); - db_ = nullptr; - db_ = SNLCapnP::load(outPath); - ASSERT_TRUE(db_); - EXPECT_EQ(SNLID::DBID(1), db_->getID()); - EXPECT_EQ(1, db_->getProperties().size()); - EXPECT_TRUE(db_->hasProperty("TEST_PROPERTY")); + db_->setID(2); + + auto loadedDB = SNLCapnP::load(outPath); + ASSERT_TRUE(loadedDB); + std::string reason; + EXPECT_TRUE(db_->deepCompare(loadedDB, reason)) << reason; + EXPECT_TRUE(reason.empty()); + + EXPECT_EQ(SNLID::DBID(1), loadedDB->getID()); + EXPECT_EQ(1, loadedDB->getProperties().size()); + EXPECT_TRUE(loadedDB->hasProperty("TEST_PROPERTY")); auto testProperty = - dynamic_cast(db_->getProperty("TEST_PROPERTY")); + dynamic_cast(loadedDB->getProperty("TEST_PROPERTY")); ASSERT_NE(nullptr, testProperty); EXPECT_EQ("TEST_PROPERTY", testProperty->getName()); - EXPECT_EQ(db_, testProperty->getOwner()); + EXPECT_EQ(loadedDB, testProperty->getOwner()); testProperty->destroy(); testProperty = nullptr; - EXPECT_TRUE(db_->getProperties().empty()); - EXPECT_FALSE(db_->hasProperty("TEST_PROPERTY")); + EXPECT_TRUE(loadedDB->getProperties().empty()); + EXPECT_FALSE(loadedDB->hasProperty("TEST_PROPERTY")); - EXPECT_EQ(1, db_->getLibraries().size()); - auto library = *(db_->getLibraries().begin()); + EXPECT_EQ(1, loadedDB->getLibraries().size()); + auto library = *(loadedDB->getLibraries().begin()); ASSERT_TRUE(library); EXPECT_EQ(SNLID::LibraryID(0), library->getID()); EXPECT_EQ(SNLName("MYLIB"), library->getName()); @@ -156,7 +160,7 @@ TEST_F(SNLCapNpTest0, test0) { EXPECT_EQ(3, design->getTerms().size()); EXPECT_EQ(5, design->getNets().size()); EXPECT_EQ(4, design->getInstances().size()); - EXPECT_EQ(design, db_->getTopDesign()); + EXPECT_EQ(design, loadedDB->getTopDesign()); auto model = designs[1]; EXPECT_EQ(SNLID::DesignID(1), model->getID()); diff --git a/test/snl/snl/serialization/capnp/SNLSender.cpp b/test/snl/snl/serialization/capnp/SNLSender.cpp new file mode 100644 index 00000000..3e56e082 --- /dev/null +++ b/test/snl/snl/serialization/capnp/SNLSender.cpp @@ -0,0 +1,31 @@ +#include + +#include "SNLUniverseSnippet.h" + +using namespace naja::SNL; +using path = std::filesystem::path; + +int main(int argc, char* argv[]) { + std::ofstream logFile; + try { + if (argc != 4) { + exit(34); + } + std::string ipAddress = argv[1]; + int port = std::stoi(argv[2]); + std::string logFileStr = argv[3]; + + path logFilePath(logFileStr); + logFile.open(logFilePath, std::ios::out); + + auto db = SNLUniverseSnippet::create(); + + logFile << "Sending " << db->getString() << std::endl; + SNLCapnP::send(db, ipAddress, port); + } catch (const std::exception& e) { + logFile << "Exception: " << e.what () << std::endl; + } + + logFile.close(); + return 0; +}