diff --git a/slsDetectorSoftware/src/CtbConfig.cpp b/slsDetectorSoftware/src/CtbConfig.cpp new file mode 100644 index 000000000..d450ac5e6 --- /dev/null +++ b/slsDetectorSoftware/src/CtbConfig.cpp @@ -0,0 +1,72 @@ + +#include "CtbConfig.h" +#include "SharedMemory.h" +#include "sls/ToString.h" +#include "sls/string_utils.h" + +#include +#include +#include + +namespace sls { + +CtbConfig::CtbConfig(){ + for (size_t i=0; i!=num_dacs; ++i){ + setDacName(i, "dac"+ToString(i)); + } +} + +void CtbConfig::check_index(size_t i) const { + if (!(i < num_dacs)) { + std::ostringstream oss; + oss << "DAC index is too large needs to be below " << num_dacs; + throw RuntimeError(oss.str()); + } +} + +void CtbConfig::check_size(const std::string &name) const { + + if (name.empty()) + throw RuntimeError("Name needs to be at least one character"); + + // dacname_length -1 to account for \0 termination + if (!(name.size() < (name_length - 1))) { + std::ostringstream oss; + oss << "Length of name needs to be less than " << name_length - 1 + << " chars"; + throw RuntimeError(oss.str()); + } +} + +void CtbConfig::setDacName(size_t index, const std::string &name) { + + check_index(index); + check_size(name); + + char *dst = &dacnames[index * name_length]; + memset(dst, '\0', name_length); + memcpy(dst, &name[0], name.size()); +} + +void CtbConfig::setDacNames(const std::vector& names){ + for (size_t i = 0; i!=num_dacs; ++i){ + setDacName(i, names[i]); + } +} + +std::string CtbConfig::getDacName(size_t index) const { + return dacnames + index * name_length; +} + +std::vector CtbConfig::getDacNames() const { + std::vector names; + for (size_t i = 0; i != num_dacs; ++i) + names.push_back(getDacName(i)); + return names; +} + +const char* CtbConfig::shm_tag(){ + return shm_tag_; +} + +} // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/src/CtbConfig.h b/slsDetectorSoftware/src/CtbConfig.h new file mode 100644 index 000000000..6c17fadbf --- /dev/null +++ b/slsDetectorSoftware/src/CtbConfig.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include +namespace sls { + + +class CtbConfig { + static constexpr size_t name_length = 20; + static constexpr size_t num_dacs = 18; + static constexpr const char* shm_tag_ = "ctbdacs"; + char dacnames[name_length * num_dacs]{}; + + void check_index(size_t i) const; + void check_size(const std::string &name) const; + + public: + CtbConfig(); + CtbConfig(const CtbConfig&) = default; + CtbConfig(CtbConfig&&) = default; + CtbConfig& operator=(const CtbConfig&) = default; + ~CtbConfig() = default; + + void setDacNames(const std::vector &names); + void setDacName(size_t index, const std::string &name); + std::string getDacName(size_t index) const; + std::vector getDacNames() const; + static const char* shm_tag(); +}; + + +} // namespace sls diff --git a/slsDetectorSoftware/tests/test-CtbConfig.cpp b/slsDetectorSoftware/tests/test-CtbConfig.cpp new file mode 100644 index 000000000..15a22e852 --- /dev/null +++ b/slsDetectorSoftware/tests/test-CtbConfig.cpp @@ -0,0 +1,59 @@ +#include "catch.hpp" +#include + +#include + +#include "SharedMemory.h" +#include "CtbConfig.h" +using namespace sls; +#include + + +TEST_CASE("Default construction"){ + static_assert(sizeof(CtbConfig) == 360); // 18*20 + + CtbConfig c; + auto names = c.getDacNames(); + REQUIRE(names.size() == 18); + REQUIRE(names[0] == "dac0"); + REQUIRE(names[1] == "dac1"); + REQUIRE(names[2] == "dac2"); + REQUIRE(names[3] == "dac3"); +} + +TEST_CASE("Set and get a single dac name"){ + CtbConfig c; + c.setDacName(3, "vrf"); + auto names = c.getDacNames(); + + REQUIRE(c.getDacName(3) == "vrf"); + REQUIRE(names[3] == "vrf"); +} + +TEST_CASE("Set a name that is too large throws"){ + CtbConfig c; + REQUIRE_THROWS(c.setDacName(3, "somestringthatisreallytolongforadatac")); +} + +TEST_CASE("Length of dac name cannot be 0"){ + CtbConfig c; + REQUIRE_THROWS(c.setDacName(1, "")); +} + +TEST_CASE("Copy a CTB config"){ + CtbConfig c1; + c1.setDacName(5, "somename"); + + auto c2 = c1; + //change the name on the first object + //to detecto shallow copy + c1.setDacName(5, "someothername"); + REQUIRE(c2.getDacName(5) == "somename"); +} + +TEST_CASE("Move CtbConfig "){ + CtbConfig c1; + c1.setDacName(3, "yetanothername"); + CtbConfig c2(std::move(c1)); + REQUIRE(c2.getDacName(3) == "yetanothername"); +} \ No newline at end of file