diff --git a/CMakeLists.txt b/CMakeLists.txt index 380b0beb7cd858106dc28f1c4ead5fdbed40f280..b3acf67b2001b077ce3b3dc4bb1b4acba27775ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,9 +24,6 @@ else() get_target_property(SPDLOG_INCLUDE_DIR spdlog::spdlog INTERFACE_INCLUDE_DIRECTORIES) endif() -find_package(coda_et REQUIRED) -get_target_property(CODA_ET_INCLUDE_DIR coda_et::coda_et INTERFACE_INCLUDE_DIRECTORIES) - find_package(EVIO REQUIRED) get_target_property(EVIO_INCLUDE_DIR EVIO::EVIO INTERFACE_INCLUDE_DIRECTORIES) @@ -69,4 +66,3 @@ if(HCANA_BUILTIN_PODD) endif() add_subdirectory(src) add_subdirectory(cmake) -add_subdirectory(tools) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b632f04cebdae375592bdf19a2f72dd74f82564..9ffd6d9295148c640e6e4c91afdade8dce3b83f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,7 +8,7 @@ include(FindThreads) #---------------------------------------------------------------------------- # Sources and headers -file(GLOB src "*.cxx" "*.cpp") +file(GLOB src "*.cxx") file(GLOB allheaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h") list(REMOVE_ITEM allheaders "${CMAKE_CURRENT_SOURCE_DIR}/${LIBNAME}_LinkDef.h" @@ -66,7 +66,6 @@ target_include_directories(${LIBNAME} $<BUILD_INTERFACE:${SPDLOG_INCLUDE_DIR}> $<INSTALL_INTERFACE:${SPDLOG_INCLUDE_DIR}> $<BUILD_INTERFACE:${FMT_INCLUDE_DIR}> - $<BUILD_INTERFACE:${CODA_ET_INCLUDE_DIR}> ) target_compile_options(${LIBNAME} @@ -83,7 +82,6 @@ target_link_libraries(${LIBNAME} PUBLIC Podd::Podd Podd::Decode - coda_et::coda_et ) set_target_properties(${LIBNAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} @@ -109,7 +107,6 @@ build_root_dictionary(${LIBNAME} ${headers} INCLUDEDIRS $<BUILD_INTERFACE:-I${SPDLOG_INCLUDE_DIR}> $<BUILD_INTERFACE:-I${FMT_INCLUDE_DIR}> - $<BUILD_INTERFACE:-I${CODA_ET_INCLUDE_DIR}> -I${CMAKE_CURRENT_SOURCE_DIR} -I${CMAKE_CURRENT_SOURCE_DIR}/include -I${CMAKE_CURRENT_SOURCE_DIR}/include/hcana diff --git a/src/ConfigObject.cpp b/src/ConfigObject.cpp deleted file mode 100644 index ee18cd36afcc2b782b33a642e35618379256f7c6..0000000000000000000000000000000000000000 --- a/src/ConfigObject.cpp +++ /dev/null @@ -1,332 +0,0 @@ -//============================================================================// -// A class based on the support from ConfigParser and ConfigValue // -// It provides a simple way to read text file as configuration file, and read // -// or modify a parameter in the inherited class // -// The Configure() function should be overloaded according to specialized // -// requirements, and be called after the parameters being configured // -// // -// Chao Peng // -// 10/31/2016 // -//============================================================================// - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <algorithm> -#include "ConfigObject.h" - - - -//============================================================================// -// Constructor, Destructor // -//============================================================================// - -// constructor -ConfigObject::ConfigObject(const std::string &splitter, const std::string &ignore, bool case_ins) -: split_chars(splitter), ignore_chars(ignore), case_insensitive(case_ins), __empty_value("") -{ - // set default replace bracket - replace_pair = std::make_pair("{", "}"); -} - -// destructor -ConfigObject::~ConfigObject() -{ - // place holder -} - - -//============================================================================// -// Public Member Function // -//============================================================================// - -// configure the cluster method -void ConfigObject::Configure(const std::string &path) -{ - // save the path - config_path = path; - - // clear the map - config_map.clear(); - - // read configuration file in - ReadConfigFile(path); -} - -// clear all the loaded configuration values -void ConfigObject::ClearConfig() -{ - config_path = ""; - config_map.clear(); -} - -// read configuration file and build the configuration map -bool ConfigObject::ReadConfigFile(const std::string &path) -{ - ConfigParser c_parser; - c_parser.SetSplitters(split_chars); // self-defined splitters - - if (c_parser.ReadFile(path)) { - // current directory - parserProcess(c_parser, path); - return true; - } else { - std::cerr << "Cannot open configuration file " - << "\"" << path << "\"" - << std::endl; - return false; - } -} - -// read the configuration string directly -void ConfigObject::ReadConfigString(const std::string &content) -{ - ConfigParser c_parser; - c_parser.SetSplitters(split_chars); - - c_parser.ReadBuffer(content.c_str()); - - parserProcess(c_parser, "buffer_string"); -} - -// continue parse the terms -void ConfigObject::parserProcess(ConfigParser &c_parser, const std::string &source) -{ - std::string cur_dir = ConfigParser::decompose_path(source).dir; - - while (c_parser.ParseLine()) { - // possible control words - if (c_parser.NbofElements() == 1) { - std::string control = c_parser.TakeFirst(); - size_t pos = control.find("{THIS_DIR}"); - if(pos != std::string::npos) - control.replace(pos, 10, cur_dir); - parseControl(control); - // var_name and var_value - } else if (c_parser.NbofElements() == 2) { - std::string var_name, key, var_value; - c_parser >> var_name >> var_value; - size_t pos = var_value.find("{THIS_DIR}"); - if(pos != std::string::npos) - var_value.replace(pos, 10, cur_dir); - parseTerm(std::move(var_name), std::move(var_value)); - // unsupported format - } else { - std::cout << "Warning: Unsupported format at line " - << c_parser.LineNumber() << " from " << source << "\n" - << "\"" << c_parser.CurrentLine() << "\"" - << std::endl; - } - } -} - -// check if a certain term is configured -bool ConfigObject::HasKey(const std::string &var_name) -const -{ - auto key = formKey(var_name); - - if (config_map.find(key) != config_map.end()) - return true; - return false; -} - -// list all the existing configuration keys -void ConfigObject::ListKeys() -const -{ - for (auto &it : config_map) { - std::cout << it.first << std::endl; - } -} - -// get all the existing configuration keys -std::vector<std::string> ConfigObject::GetKeyList() -const -{ - std::vector<std::string> res; - - for (auto &it : config_map) { - res.push_back(it.first); - } - - return res; -} - -// save current configuration into a file -void ConfigObject::SaveConfig(const std::string &path) -const -{ - std::string save_path; - - if (path.empty()) - save_path = config_path; - if(save_path.empty()) - save_path = "latest.conf"; - - std::ofstream save(save_path); - for (auto &it : config_map) { - save << it.first - << " " << split_chars.front() << " " - << it.second - << std::endl; - } -} - -// get configuration value by its name/key -ConfigValue ConfigObject::GetConfigValue(const std::string &var_name) -const -{ - // convert to lower case and remove uninterested characters - auto key = formKey(var_name); - - auto it = config_map.find(key); - if (it == config_map.end()) { - return __empty_value; - } else { - ConfigValue result(it->second); - reform(result._value, replace_pair.first, replace_pair.second); - return result; - } -} - -// set configuration value by its name/key -void ConfigObject::SetConfigValue(const std::string &var_name, const ConfigValue &c_value) -{ - // convert to lower case and remove uninterested characters - auto key = formKey(var_name); - - config_map[key] = c_value; -} - - -// get configuration value from the map -// if no such config value exists, it will fill the default value in -ConfigValue ConfigObject::GetConfigValue(const std::string &var_name, const ConfigValue &def_value, bool verbose) -{ - auto key = formKey(var_name); - - auto it = config_map.find(key); - if (it == config_map.end()) { - if (def_value.IsEmpty()) - return __empty_value; - - if (verbose) { - std::cout << var_name << " (key: " << key << ")" - << " not defined in configuration file, set to default value " - << def_value - << std::endl; - } - config_map[key] = def_value; - return def_value; - } - - ConfigValue result(it->second); - reform(result._value, replace_pair.first, replace_pair.second); - return result; -} - - - -//============================================================================// -// Protected Member Function // -//============================================================================// - -// build the key -std::string ConfigObject::formKey(const std::string &rawKey) -const -{ - std::string key = ConfigParser::str_remove(rawKey, ignore_chars); - if (case_insensitive) { - key = ConfigParser::str_lower(key); - } - return key; -} - -// replace the contents inside replace_pair with the configuration value -void ConfigObject::reform(std::string &input, const std::string &op, const std::string &cl) -const -{ - // loop until no pair found - while (true) { - auto rpair = ConfigParser::find_pair(input, op, cl); - if (rpair.first != std::string::npos && rpair.second != std::string::npos) { - // get content inside the bracket - std::string var = input.substr(rpair.first + op.size(), - rpair.second - op.size() - rpair.first); - // deal with nested structure - reform(var, op, cl); - - // replace content - std::string val; - - // environment variable - if (rpair.first > 0 && input.at(rpair.first - 1) == '$') { - val = std::getenv(var.c_str()); - // replace $ mark also - rpair.first--; - // ConfigObject variable - } else { - val = GetConfigValue(var)._value; - } - - // replace variable with configuration value - input.replace(rpair.first, rpair.second - rpair.first + cl.size(), val); - } else { - // no pair found any more - return; - } - } -} - - - - -//============================================================================// -// Private Member Function // -//============================================================================// - -// parse the control word and respond -void ConfigObject::parseControl(const std::string &word) -{ - if (ConfigParser::str_upper(word.substr(0, 7)) == "INCLUDE") { - // need the most outer pair - auto p = ConfigParser::find_pair(word, "(", ")"); - // not find pair - if (p.first == std::string::npos || p.second == std::string::npos) { - std::cout << "Unsupported control word format: " << word << "." - << "Expected: INCLUDE(path)" - << std::endl; - return; - } - - int begin = p.first + 1; - int length = p.second - begin; - - std::string new_path = word.substr(begin, length); - reform(new_path, replace_pair.first, replace_pair.second); - - ReadConfigFile(new_path); - } - else { - std::cout << "Unsupported control word: " << word << std::endl; - } -} - -// parse the configuration term -void ConfigObject::parseTerm(std::string &&var_name, std::string &&var_value) -{ - // convert to lower case and remove uninterested characters - auto key = formKey(var_name); - - if (key.back() == '+') { - key.pop_back(); - auto it = config_map.find(key); - if (it != config_map.end()) - it->second += var_value; - else - config_map[key] = var_value; - } else { - config_map[key] = var_value; - } -} diff --git a/src/ConfigObject.h b/src/ConfigObject.h deleted file mode 100644 index aa3bd1c82e8582cd994dca214d910b6edaf9076c..0000000000000000000000000000000000000000 --- a/src/ConfigObject.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef CONFIG_OBJECT_H -#define CONFIG_OBJECT_H - -#include <string> -#include <utility> -#include <vector> -#include <unordered_map> -#include "ConfigParser.h" - - -#define CONF_CONN(val, str, def, warn) val=GetConfigValue<decltype(val)>(str, def, warn) -#define CONF_CONN2(val, def, warn) val=GetConfiValue<decltype(val)>(str, def, warn) -#define GET_CONF(obj, val, str, def, warn) val=obj.GetConfiValue<decltype(val)>(str, def, warn) -#define GET_CONF2(obj, val, def, warn) val=GetConfiValue<decltype(val)>(#val, def, warn) - - -class ConfigObject -{ -public: - // constructor, desctructor - ConfigObject(const std::string &spliiter = ":=", const std::string &ignore = " _\t", bool case_ins = true); - - virtual ~ConfigObject(); - - // public member functions - void ClearConfig(); - void SaveConfig(const std::string &path = "") const; - void ListKeys() const; - bool HasKey(const std::string &name) const; - - bool ReadConfigFile(const std::string &path); - void ReadConfigString(const std::string &content); - void SetConfigValue(const std::string &var_name, const ConfigValue &c_value); - void SetIgnoreChars(const std::string &ignore) {ignore_chars = ignore;} - void SetSplitChars(const std::string &splitter) {split_chars = splitter;} - void SetReplacePair(const std::string &open, const std::string &close) - { - replace_pair = std::make_pair(open, close); - } - - // get members - ConfigValue GetConfigValue(const std::string &var_name) const; - template<typename T> - T GetConfigValue(const std::string &var_name) - const - { - return GetConfigValue(var_name).Convert<T>(); - } - - ConfigValue GetConfigValue(const std::string &var_name, const ConfigValue &def_value, bool verbose = true); - template<typename T> - T GetConfigValue(const std::string &var_name, const T &val, bool verbose = true) - { - return GetConfigValue(var_name, ConfigValue(val), verbose).Convert<T>(); - } - - const std::string &GetConfigPath() const {return config_path;} - const std::string &GetSplitChars() const {return split_chars;} - const std::string &GetSpaceChars() const {return ignore_chars;} - const std::pair<std::string, std::string> &GetReplacePair() const {return replace_pair;} - std::vector<std::string> GetKeyList() const; - - - // functions that to be overloaded - virtual void Configure(const std::string &path = ""); - -protected: - // protected member functions - void reform(std::string &input, const std::string &open, const std::string &close) const; - std::string formKey(const std::string &raw_key) const; - -private: - void parserProcess(ConfigParser &p, const std::string &source); - void parseControl(const std::string &control_word); - void parseTerm(std::string &&var_name, std::string &&var_value); - -protected: - std::string split_chars; - std::string ignore_chars; - bool case_insensitive; - std::pair<std::string, std::string> replace_pair; - std::string config_path; - std::unordered_map<std::string, std::string> config_map; - - // return this reference when there is no value found in the map - ConfigValue __empty_value; -}; - -#endif diff --git a/src/ConfigOption.cpp b/src/ConfigOption.cpp deleted file mode 100644 index a9b6744d82738bf93020b6c3d1c1cc8d91a02cb8..0000000000000000000000000000000000000000 --- a/src/ConfigOption.cpp +++ /dev/null @@ -1,218 +0,0 @@ -//============================================================================// -// A class to simplify the argument parsing procedure // -// // -// Chao Peng // -// 07/26/2017 // -//============================================================================// - -#include "ConfigOption.h" -#include "ConfigParser.h" -#include <iostream> -#include <cstring> - - - -ConfigOption::ConfigOption() -{ - // place holder -} - -ConfigOption::~ConfigOption() -{ - // place holder -} - -void ConfigOption::AddOpt(OptType type, char s_term) -{ - AddOpt(type, s_term, s_term); -} - -void ConfigOption::AddLongOpt(OptType type, const char *l_term) -{ - AddLongOpt(type, l_term, *l_term); -} - -void ConfigOption::AddOpts(OptType type, char s_term, const char *l_term) -{ - AddOpts(type, s_term, l_term, s_term); -} - -void ConfigOption::AddOpt(OptType type, char s_term, char mark) -{ - if(s_opt_map.find(s_term) != s_opt_map.end()) { - std::cerr << "ConfigOption: Short option " << s_term - << " has already been added, abort AddOpt." - << std::endl; - return; - } - - s_opt_map[s_term] = Opt(mark, type); -} - -void ConfigOption::AddLongOpt(OptType type, const char *l_term, char mark) -{ - if(l_opt_map.find(l_term) != l_opt_map.end()) { - std::cerr << "ConfigOption: Long option " << l_term - << " has already been added, abort AddOpt." - << std::endl; - return; - } - - l_opt_map[l_term] = Opt(mark, type); -} - -void ConfigOption::AddOpts(OptType type, char s_term, const char *l_term, char mark) -{ - AddOpt(type, s_term, mark); - AddLongOpt(type, l_term, mark); -} - -bool ConfigOption::parseLongOpt(const char *arg) -{ - auto vars = ConfigParser::split(arg, strlen(arg), "="); - - std::string key = std::move(vars.front()); - vars.pop_front(); - auto it = l_opt_map.find(key); - - if(it == l_opt_map.end()) { - std::cerr << "Unknown option --" << key << std::endl; - return false; - } - - switch(it->second.type) - { - case arg_require: - if(vars.empty()) { - std::cerr << "Lack of argument for option --" << key << std::endl; - return false; - } - opt_pack.emplace_back(it->second.mark, it->second.type, std::move(vars.front())); - break; - case arg_none: - opt_pack.emplace_back(it->second.mark, it->second.type); - break; - case help_message: - return false; - } - - return true; -} - -bool ConfigOption::parseShortOpt(char key, int argc, char *argv[], int &idx) -{ - auto it = s_opt_map.find(key); - if(it == s_opt_map.end()) { - std::cerr << "Unknown option -" << key << std::endl; - return false; - } - - switch(it->second.type) - { - case arg_require: - if((idx + 1) >= argc || *argv[idx + 1] == '-') { - std::cerr << "Lack of argument for option -" << key << std::endl; - return false; - } - opt_pack.emplace_back(it->second.mark, it->second.type, ConfigValue(argv[++idx])); - break; - case arg_none: - opt_pack.emplace_back(it->second.mark, it->second.type); - break; - case help_message: - return false; - } - - return true; -} - -bool ConfigOption::ParseArgs(int argc, char *argv[]) -{ - if (argc < 1) - return false; - - argv0 = argv[0]; - - bool success = true; - arg_pack.clear(); - opt_pack.clear(); - - for(int i = 1; i < argc; ++i) - { - char* ptr = argv[i]; - // option - if(*ptr == '-') { - // long option - if(*(ptr + 1) == '-') { - success &= parseLongOpt(ptr + 2); - // short option - } else { - success &= parseShortOpt(*(ptr + 1), argc, argv, i); - } - // arguments - } else { - arg_pack.emplace_back(ptr); - } - } - - return success; -} - -void ConfigOption::SetDesc(const char *desc) -{ - base_desc = desc; -} - -void ConfigOption::SetDesc(char mark, const char *desc) -{ - std::string option; - bool found_mark = false; - for(auto &it : s_opt_map) - { - if(it.second.mark != mark) continue; - option = " - "; - option.back() = it.first; - if(it.second.type == arg_require) - option += " <arg>"; - option += ","; - found_mark = true; - } - - for(auto &it : l_opt_map) - { - if(it.second.mark != mark) continue; - option += " --" + it.first; - if(it.second.type == arg_require) - option += "=<arg>"; - option += ","; - found_mark = true; - } - - if(!found_mark) { - std::cerr << "Config Option: Cannot find any option with mark <" - << mark << ">, abort adding description." << std::endl; - return; - } - - option.back() = ':'; - option += " "; - option += desc; - option_desc.emplace_back(option); -} - -std::string ConfigOption::GetInstruction() -{ - std::string res = base_desc + "\noptions:\n"; - - auto pvar = res.find("%0"); - if (pvar != std::string::npos) { - res.replace(pvar, 2, argv0); - } - - for(auto &option : option_desc) - { - res += "\t" + option + "\n"; - } - return res; -} - diff --git a/src/ConfigOption.h b/src/ConfigOption.h deleted file mode 100644 index 1ca1f7c158b6ccbc853f3226ad079dd08dc63877..0000000000000000000000000000000000000000 --- a/src/ConfigOption.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef CONFIG_OPTION_H -#define CONFIG_OPTION_H - -#include "ConfigValue.h" -#include <vector> -#include <string> -#include <unordered_map> - -class ConfigOption -{ -public: - enum OptType : int - { - arg_none = 0, - arg_require, - help_message, - }; - - struct Opt - { - char mark; - OptType type; - ConfigValue var; - - Opt() : mark(-1), type(arg_none) {} - Opt(char m, OptType t) : mark(m), type(t) {} - Opt(char m, OptType t, ConfigValue v) : mark(m), type(t), var(v) {} - }; - -public: - ConfigOption(); - virtual ~ConfigOption(); - - void AddOpt(OptType type, char s_term); - void AddOpt(OptType type, char s_term, char mark); - void AddLongOpt(OptType type, const char *l_term); - void AddLongOpt(OptType type, const char *l_term, char mark); - void AddOpts(OptType type, char s_term, const char *l_term); - void AddOpts(OptType type, char s_term, const char *l_term, char mark); - void SetDesc(const char *desc); - void SetDesc(char mark, const char *desc); - std::string GetInstruction(); - bool ParseArgs(int argc, char *argv[]); - size_t NbofArgs() const {return arg_pack.size();} - size_t NbofOpts() const {return opt_pack.size();} - const std::string &GetArgv0() {return argv0;} - const ConfigValue &GetArgument(size_t i) {return arg_pack.at(i);} - const std::vector<ConfigValue> &GetArguments() {return arg_pack;} - const std::vector<Opt> &GetOptions() {return opt_pack;} - -private: - bool parseLongOpt(const char *arg); - bool parseShortOpt(char key, int argc, char *argv[], int &idx); - -private: - std::unordered_map<char, Opt> s_opt_map; - std::unordered_map<std::string, Opt> l_opt_map; - std::vector<Opt> opt_pack; - std::vector<ConfigValue> arg_pack; - std::string argv0; - std::string base_desc; - std::vector<std::string> option_desc; -}; - - -#endif // CONFIG_OPTION_H diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp deleted file mode 100644 index ad496d48e13bfeacdfda01dd92178482dd778c69..0000000000000000000000000000000000000000 --- a/src/ConfigParser.cpp +++ /dev/null @@ -1,966 +0,0 @@ -//============================================================================// -// A simple parser class to read text file and deal with strings // -// // -// Chao Peng // -// 06/07/2016 // -//============================================================================// - -#include "ConfigParser.h" -#include <cstring> -#include <climits> -#include <algorithm> - -using namespace std; - - - -//============================================================================// -// Constructors, Destructor, Assignment Operators // -//============================================================================// - -// constructor, with format input -ConfigParser::ConfigParser(Format f) -: form(f), line_number(0) -{ - // place holder -} - -// copy constructor, only copy format -ConfigParser::ConfigParser(const ConfigParser &that) -: form(that.form), line_number(0) -{ - // place holder -} - -// move constructor, only move format -ConfigParser::ConfigParser(ConfigParser &&that) -: form(that.form), line_number(0) -{ - // place holder -} - -// desctructor -ConfigParser::~ConfigParser() -{ - CloseFile(); -} - -// copy assignment operator -ConfigParser &ConfigParser::operator = (const ConfigParser &rhs) -{ - form = rhs.form; - return *this; -} - -// move assignment operator -ConfigParser &ConfigParser::operator = (ConfigParser &&rhs) -{ - form = rhs.form; - return *this; -} - -//============================================================================// -// Public Member Function // -//============================================================================// - -// open a file for future parsing -bool ConfigParser::OpenFile(const string &path, size_t cap) -{ - Clear(); - - infile.open(path); - - if(!infile.is_open()) - return false; - - buf.data.resize(cap); - - // success! - return true; -} - -// read the whole file into a buffer and break it into lines -bool ConfigParser::ReadFile(const string &path) -{ - Clear(); - - infile.open(path); - - if(!infile.is_open()) - return false; - - infile.seekg(0, ios::end); - buf.end = infile.tellg(); - buf.data.resize(buf.end); - infile.seekg(0, ios::beg); - - infile.read(&buf.data[0], buf.end); - infile.close(); - - return true; -} - -// close file -void ConfigParser::CloseFile() -{ - return infile.close(); -} - -// clear stored lines -void ConfigParser::Clear() -{ - buf.Reset(); - - // reset line - line_number = 0; - cur_line.Reset(); - - // close file - CloseFile(); -} - -// read a buffer in -void ConfigParser::ReadBuffer(const char *buf_in) -{ - Clear(); - - buf.end = strlen(buf_in); - buf.data.resize(buf.end + 2); - - strncpy(&buf.data[0], buf_in, buf.end); -} - -// parse a line from the file or buffer -// if the line is empty (all white spaces or comments), it will be skipped -// return false if reached the end -bool ConfigParser::ParseLine() -{ - elements.clear(); - - while(elements.empty()) - { - if(!getLine(cur_line)) - return false; - - // count the line number - ++line_number; - - parseBuffer(cur_line); - } - - return true; -} - -// parse the whole file or buffer -// return false if nothing was found -bool ConfigParser::ParseAll() -{ - elements.clear(); - - while(true) - { - if(!getLine(cur_line)) - return !elements.empty(); - - // count the line number - ++line_number; - - parseBuffer(cur_line); - } -} - -// parse an input string, split the string into elements -// the trail white spaces in the elements will be trimmed -int ConfigParser::ParseString(const string &line) -{ - deque<string> eles = split(line.c_str(), line.size(), form.split); - - int count = 0; - for(auto &ele : eles) - { - string trim_ele = trim(ele, form.white); - if(!trim_ele.empty()) { - elements.emplace_back(move(trim_ele)); - count++; - } - } - - return count; -} - -// check if the current elemtns number is in the range [num, num + optional] -// output a warning message if not -bool ConfigParser::CheckElements(int num, int optional) -{ - string num_str; - - if(optional > 0) { - if((elements.size() >= (size_t)num) && - (elements.size() <= (size_t)(num + optional))) { - return true; - } - - num_str = to_string(num) + " - " + to_string(num + optional); - - } else if(optional == 0) { - - if(elements.size() == (size_t)num) { - return true; - } - - num_str = to_string(num); - - } else { // optional < 0 - if(elements.size() >= (size_t)num) { - return true; - } - - num_str = " >= " + to_string(num); - } - - - cout << "Config Parser Warning: Wrong format at line " - << line_number - << ", expecting " << num_str << " elements. " - << endl - << "\"" << cur_line.String() << "\"" - << endl; - return false; -} - - -// take the first element -ConfigValue ConfigParser::TakeFirst() -{ - if(elements.empty()) { - cout << "Config Parser Warning: Trying to take elements while there is " - << "nothing, 0 value returned." << endl; - return ConfigValue("0"); - } - - ConfigValue output(move(elements.front())); - elements.pop_front(); - - return output; -} - - - -//============================================================================// -// Private Member Function // -//============================================================================// - -// get buffer from the file or the input buffer -// return false if reached input end -bool ConfigParser::getBuffer() -{ - if(buf.begin < buf.end) - return true; - - if(!infile.is_open() || infile.bad() || infile.eof()) - return false; - - infile.read(&buf.data[0], buf.data.size()); - - buf.begin = 0; - buf.end = infile.gcount(); - - return true; -} - -// trim white spaces -inline void trimbuf(const vector<char> &buf, size_t &begin, size_t &end, const string &w) -{ - while(begin < end) - { - if(w.find(buf[begin]) == string::npos) - break; - - begin++; - } - - while(end > begin) - { - if(w.find(buf[end - 1]) == string::npos) - break; - - end--; - } -} - -inline bool compare(const char ch, const string &str, size_t &c1) -{ - if(str.empty()) - return false; - - c1 = (ch == str[c1]) ? (c1 + 1) : 0; - - return (c1 >= str.size()); -} - -inline bool rcompare(const ConfigParser::CharBuffer &buf, const string &str) -{ - if(str.empty() || buf.end <= buf.begin || buf.end - buf.begin < str.size()) - return false; - - for(size_t i = 1; i <= str.size(); ++i) - { - if(str[str.size() - i] != buf[buf.end - i]) - return false; - } - - return true; -} - -// a helper structure to check context status -struct TextStatus -{ - int val; - size_t cmt1, cmt2, delim; - - TextStatus() : val(0), cmt1(0), cmt2(0), delim(0) {} - inline void Set(int i) {val = i; cmt1 = 0; cmt2 = 0;} -}; - -// get a line from the file or buffer -// it deals with comments, white spaces -// return false if reached the end -bool ConfigParser::getLine(CharBuffer &line_buf, bool recursive) -{ - if(!recursive) - line_buf.Reset(); - bool success = false; - TextStatus stat; - - while(getBuffer()) - { - success = true; - - while(buf.begin < buf.end) - { - auto &ch = buf[buf.begin++]; - switch(stat.val) - { - default: - case 0: - line_buf.Add(ch); - // check if it is the end - if(compare(ch, form.delim, stat.delim)) { - line_buf.end -= form.delim.size(); - trimbuf(line_buf.data, line_buf.begin, line_buf.end, form.white); - // glue lines - if(rcompare(line_buf, form.glue)) { - line_buf.end -= form.glue.size(); - return getLine(line_buf, true); - } else { - return success; - } - } else if(compare(ch, form.cmtopen, stat.cmt1)) { - stat.Set(1); - line_buf.end -= form.cmtopen.size(); - } else if(compare(ch, form.cmtmark, stat.cmt2)) { - stat.Set(2); - line_buf.end -= form.cmtmark.size(); - } - break; - case 1: - if(compare(ch, form.cmtclose, stat.cmt1)) { - stat.Set(0); - } - break; - case 2: - if(ch == '\n') { - stat.Set(0); - buf.begin -= 1; - } - break; - } - } - } - - trimbuf(line_buf.data, line_buf.begin, line_buf.end, form.white); - return success; -} - -// parse an input char buffer, split the string into elements -// the trail white spaces in the elements will be trimmed -int ConfigParser::parseBuffer(const CharBuffer &line) -{ - if(line.begin >= line.end) - return 0; - - size_t ele_begin = line.begin; - int count = 0; - - // intended to visit i == line.end, so the rest of the string get parsed - for(size_t i = 0; i <= line.end; ++i) - { - if(i == line.end || form.split.find(line[i]) != string::npos) { - size_t ele_end = i; - trimbuf(line.data, ele_begin, ele_end, form.white); - if(ele_begin < ele_end) { - elements.emplace_back(&line[ele_begin], ele_end - ele_begin); - count++; - } - ele_begin = i + 1; - } - } - - return count; -} - -//============================================================================// -// Public Static Function // -//============================================================================// - -// comment out a string, remove chars from the comment mark to the line break -void ConfigParser::comment_line(string &str, const string &c, const string &b) -{ - // no need to continue - if(str.empty() || c.empty() || b.empty()) - return; - - // loop until no marks found - while(true) - { - size_t c_begin = str.find(c); - if(c_begin != string::npos) { - size_t c_end = str.find(b, c_begin + c.size()); - // found, comment out until the line break - if(c_end != string::npos) { - // do not remove line break - str.erase(c_begin, c_end - c_begin); - // not found, comment out until the end - } else { - str.erase(c_begin); - // can stop now, since everything afterwards is removed - return; - } - } else { - // comment marks not found - return; - } - } -} - -// comment out between a pair of comment marks -// NOTICE: does not support nested structure of comment marks -void ConfigParser::comment_between(string &str, const string &open, const string &close) -{ - // no need to continue - if(str.empty() || open.empty() || close.empty()) - return; - - while(true) - { - // find the openning comment mark - size_t pos1 = str.find(open); - if(pos1 != string::npos) { - size_t pos2 = str.find(close, pos1 + open.size()); - // found pair - if(pos2 != string::npos) { - // remove everything between, including this pair - str.erase(pos1, pos2 + close.size() - pos1); - // comment pair not found - } else { - return; - } - } else { - // comment pair not found - return; - } - } -} - -// trim all the characters defined as white space at both ends -string ConfigParser::trim(const string &str, const string &w) -{ - - const auto strBegin = str.find_first_not_of(w); - if (strBegin == string::npos) - return ""; // no content - - const auto strEnd = str.find_last_not_of(w); - - const auto strRange = strEnd - strBegin + 1; - return str.substr(strBegin, strRange); -} - -// split a string into several pieces by all the characters defined as splitter -deque<string> ConfigParser::split(const string &str, const string &s) -{ - deque<string> eles; - - char *cstr = new char[str.length() + 1]; - - strcpy(cstr, str.c_str()); - - char *pch = strtok(cstr, s.c_str()); - - while(pch != nullptr) - { - eles.emplace_back(pch); - pch = strtok(nullptr, s.c_str()); - } - - delete[] cstr; - - return eles; -} - -// split a char array into several pieces -deque<string> ConfigParser::split(const char* str, const size_t &len, const string &s) -{ - deque<string> eles; - - char *str_cpy = new char[len + 1]; - - strncpy(str_cpy, str, len); - // end of C string - str_cpy[len] = '\0'; - - char *pch = strtok(str_cpy, s.c_str()); - - while(pch != nullptr) - { - eles.emplace_back(pch); - pch = strtok(nullptr, s.c_str()); - } - - delete[] str_cpy; - - return eles; -} - -// split a string and convert all parts to float numbers -vector<int> ConfigParser::stois(const string &str, const string &s, const string &w) -{ - vector<int> res; - for(auto &val : split(str, s)) - { - res.push_back(stoi(trim(val, w))); - } - return res; -} - -// split a string and convert all parts to float numbers -vector<float> ConfigParser::stofs(const string &str, const string &s, const string &w) -{ - vector<float> res; - for(auto &val : split(str, s)) - { - res.push_back(stof(trim(val, w))); - } - return res; -} - -// split a string and convert all parts to double numbers -vector<double> ConfigParser::stods(const string &str, const string &s, const string &w) -{ - vector<double> res; - for(auto &val : split(str, s)) - { - res.push_back(stod(trim(val, w))); - } - return res; -} - -// get the split part at num -string ConfigParser::get_split_part(int num, const char *str, const char &s) -{ - // unavailable - if(num < 0) return ""; - - int beg = 0, cur = 0; - while(str[cur] != '\0') - { - if(str[cur] == s) { - // number macthed - if(num-- == 0) { - return string(&str[beg], cur - beg); - // update segment - } else { - beg = cur + 1; - } - } - ++cur; - } - - // last element - if(num == 0) - return string(&str[beg], cur - beg); - - return ""; -} - -// check if the short string is the same with the first part of a long string -bool cstr_cmp_helper(const char *cmp, const char *str, int size) -{ - for(int i = 0; i < size; ++i) - { - if(cmp[i] != str[i] || cmp[i] == '\0' || str[i] == '\0') - return false; - } - - if(cmp[size] != '\0') - return false; - - return true; -} - -// split a long string and find if a short string is belong to its elements -int ConfigParser::get_part_count(const char *cmp, const char *str, const char &s) -{ - int cnt = 0, beg = 0, cur = 0; - while(str[cur] != '\0') - { - if(str[cur] == s) { - if(cstr_cmp_helper(cmp, &str[beg], cur - beg)) { - return cnt; - } - - ++cnt; - beg = cur + 1; - } - ++cur; - } - - if(cstr_cmp_helper(cmp, &str[beg], cur-beg)) - return cnt; - - return -1; -} - -// find the integer in a string -int ConfigParser::find_integer(const string &str, const size_t &pos) -{ - vector<int> integers = find_integers(str); - if(pos >= integers.size()) - { - cerr << "Config Parser: Cannot find " << pos + 1 << " integers from " - << "\"" << str << "\"." - << endl; - return 0; - } - - return integers.at(pos); -} - -// find all the integers in a string -vector<int> ConfigParser::find_integers(const string &str) -{ - vector<int> result; - - find_integer_helper(str, result); - - return result; -} - -// helper function for finding a integer -void ConfigParser::find_integer_helper(const string &str, vector<int> &result) -{ - if(str.empty()) - return; - - int negative = 1; - auto numBeg = str.find_first_of("-0123456789"); - if(numBeg == string::npos) - return; - - // check negative sign - string str2 = str.substr(numBeg); - - if(str2.at(0) == '-') - { - negative = -1; - int num_check; - - do { - str2.erase(0, 1); - - if(str2.empty()) - return; - - num_check = str2.at(0) - '0'; - } while (num_check > 9 || num_check < 0); - } - - auto numEnd = str2.find_first_not_of("0123456789"); - if(numEnd == string::npos) - numEnd = str2.size(); - - int num = 0; - size_t i = 0; - - for(; i < numEnd; ++i) - { - if( (num > INT_MAX/10) || - (num == INT_MAX/10 && ((str2.at(i) - '0') > (INT_MAX - num*10))) ) - { - ++i; - break; - } - - num = num*10 + str2.at(i) - '0'; - } - - result.push_back(negative*num); - find_integer_helper(str2.substr(i), result); -} - -// return the lower case of this string -string ConfigParser::str_lower(const string &str) -{ - string res = str; - for(auto &c : res) - { - c = tolower(c); - } - return res; -} - -// return the upper case of this string -string ConfigParser::str_upper(const string &str) -{ - string res = str; - for(auto &c : res) - { - c = toupper(c); - } - return res; -} - -// remove characters in ignore list -string ConfigParser::str_remove(const string &str, const string &iignore) -{ - string res = str; - - for(auto &c : iignore) - { - res.erase(remove(res.begin(), res.end(), c), res.end()); - } - return res; -} - -// replace characters in the list with certain char -string ConfigParser::str_replace(const string &str, const string &list, const char &rc) -{ - if(list.empty()) - return str; - - string res = str; - - for(auto &c : res) - { - if(list.find(c) != string::npos) - c = rc; - } - - return res; -} - -// compare two strings, can be case insensitive -bool ConfigParser::case_ins_equal(const string &str1, const string &str2) -{ - if(str1.size() != str2.size()) { - return false; - } - - for(auto c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) - { - if(tolower(*c1) != tolower(*c2)) { - return false; - } - } - - return true; -} - -// find the first pair position in a string -// it will return the most outer pair if the first pair was in a nested structure -pair<size_t, size_t> ConfigParser::find_pair(const string &str, - const string &open, - const string &close, - size_t pos) -{ - pair<size_t, size_t> res(string::npos, string::npos); - - if(open.empty() || close.empty() || str.size() <= pos) - return res; - - res.first = str.find(open, pos); - - // pair not found - if(res.first == string::npos) { - return res; - } - - int open_bracket = 1; - size_t search_beg = res.first + open.size(); - - // loop for nested structure - while(open_bracket > 0) - { - size_t next_close = str.find(close, search_beg); - - // pair not found - if(next_close == string::npos) { - // change back to npos for the not-found indication - res.first = string::npos; - return res; - } - - // check for nested structure - size_t next_open = str.find(open, search_beg); - - // the comparison is based on the definition of string::npos - // npos for not found is size_t = -1, which is the biggest size_t value - // find another open before close - if(next_open < next_close) { - open_bracket++; - search_beg = next_open + open.size(); - // else cases - // 1. close mark found before open mark - // 2. close mark found, open mark not - // 3. close mark is the same as open mark, so the position is the same - } else { - open_bracket--; - search_beg = next_close + close.size(); - res.second = next_close; - } - } - - return res; -} - -// get file name and directory from a path -ConfigParser::PathInfo ConfigParser::decompose_path(const string &path) -{ - PathInfo res; - if(path.empty()) return res; - - // find directory - auto dir_pos = path.find_last_of("/"); - - if(dir_pos != string::npos) { - res.dir = path.substr(0, dir_pos); - res.name = path.substr(dir_pos + 1); - } else { - res.name = path; - } - - // find extension - auto ext_pos = res.name.find_last_of("."); - if(ext_pos != string::npos) { - res.ext = res.name.substr(ext_pos + 1); - res.name = res.name.substr(0, ext_pos); - } - - return res; -} - -// form the path -string ConfigParser::compose_path(const ConfigParser::PathInfo &path) -{ - string res(path.dir); - res.reserve(path.dir.size() + path.name.size() + path.ext.size() + 2); - - if(!res.empty() && res.back() != '/') - res += '/'; - - res += path.name; - - if(!path.ext.empty()) - res += "." + path.ext; - - return res; -} - -// form a path from given directory and file name, automatically add / if it is missing -string ConfigParser::form_path(const string &dir, const string &file) -{ - string file_path; - file_path.reserve(dir.size() + file.size() + 1); - - file_path = dir; - if(file_path.size() && file_path.back() != '/') file_path += "/"; - file_path += file; - - return file_path; -} - -// read a file and return its content in a char string -string ConfigParser::file_to_string(const string &path) -{ - ifstream inf(path); - - if(!inf.is_open()) - return ""; - - // read the whole file in - string str; - - inf.seekg(0, ios::end); - str.reserve(inf.tellg()); - inf.seekg(0, ios::beg); - - str.assign((istreambuf_iterator<char>(inf)), istreambuf_iterator<char>()); - inf.close(); - - return str; -} - -// break text file into several blocks in the format -// <label> <open_mark> <content> <close_mark> -// return extracted <residual> {<label> <content>} -ConfigParser::TextBlocks ConfigParser::break_into_blocks(const string &buf, - const string &open, - const string &close, - const string &seps) -{ - TextBlocks result; - - if(buf.empty() || open.empty() || close.empty()) - return result; - - size_t last_end = 0; - // loop until no blocks found - while(true) - { - // find the contents in block brackets - auto p = find_pair(buf, open, close, last_end); - - // no pair found anymore - if(p.first == string::npos || p.second == string::npos) - break; - - // add content - TextBlock block; - block.content = trim(buf.substr(p.first + open.size(), p.second - p.first - open.size()), seps); - - // find label - string head = buf.substr(last_end, p.first - last_end); - if(head.empty()) { - block.label = ""; - } else { - // find end of label - auto end = head.find_last_not_of(seps); - if(end == string::npos) end = head.size() - 1; - // find begin of label - auto beg = head.find_last_of(seps, end); - if(beg == string::npos) beg = 0; - // add label - block.label = trim(head.substr(beg, end - beg + 1), seps); - // other content goes to residual - result.residual += head.substr(0, beg); - } - // combine blocks - result.blocks.emplace_back(move(block)); - last_end = p.second + close.size(); - } - - // trim - result.residual = trim(result.residual, seps); - - return result; -} diff --git a/src/ConfigParser.h b/src/ConfigParser.h deleted file mode 100644 index 5e2810b4b0ea14d3f0167fa05e9089c5542eed1d..0000000000000000000000000000000000000000 --- a/src/ConfigParser.h +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef CONFIG_PARSER_H -#define CONFIG_PARSER_H - -#include <string> -#include <vector> -#include <deque> -#include <fstream> -#include "ConfigValue.h" - -// a macro to auto generate enum2str and str2enum -// name mapping begins at bias and continuously increase, split by '|' -// an example: -// enum ABC {a = 3, b, c}; -// ENUM_MAP(ABC, 3, "a|b|c") -// ABC2str(3) = "a" -// str2ABC("b") = 4 -#define ENUM_MAP(type, bias, strings) \ - static std::string type ## 2str(int T) \ - { \ - return ConfigParser::get_split_part(T - (bias), strings, '|'); \ - }; \ - static type str2 ## type(const char *str) \ - { \ - return static_cast<type>(bias + ConfigParser::get_part_count(str, strings, '|')); \ - } - -// config parser class -class ConfigParser -{ - typedef std::pair<std::string, std::string> string_pair; - -public: - struct Format - { - std::string split; // element splitters (chars) - std::string white; // white spaces (chars) - std::string delim; // line delimiter (string) - std::string glue; // line glue (string) - std::string cmtmark; // comment marks (string), until the line breaker '\n' - std::string cmtopen; // comment-block opening mark (string) - std::string cmtclose; // comment-block closing mark (string) - - static Format Basic() {return {" \t,", " \t", "\n", "", "", "", ""};} - static Format BashLike() {return {" \t,", " \t", "\n", "\\", "#", "\'", "\'"};} - static Format CLike() {return {" \t,\n", " \t\n", ";", "", "//", "/*", "*/"};} - }; - - struct CharBuffer - { - std::vector<char> data; - size_t begin, end; - - CharBuffer(size_t cap = 256) : begin(0), end(0) - { - data.resize(cap); - } - - void Reset() {begin = 0; end = 0; data.clear();} - void Add(char ch) - { - if(data.size() <= end) - data.resize(2*data.size()); - - data[end++] = ch; - } - - std::string String() - const - { - std::string str; - if(end > begin) - str.assign(&data[begin], end - begin); - return str; - } - - inline const char &operator [] (size_t idx) const {return data[idx];} - inline char &operator [] (size_t idx) {return data[idx];} - }; - -public: - ConfigParser(Format f = Format::BashLike()); - - ConfigParser(ConfigParser &&that); - ConfigParser(const ConfigParser &that); - - virtual ~ConfigParser(); - - ConfigParser &operator = (ConfigParser &&rhs); - ConfigParser &operator = (const ConfigParser &rhs); - - // format related - inline void SetFormat(Format &&f) {form = f;} - inline void SetFormat(const Format &f) {form = f;} - inline void SetSplitters(std::string s) {form.split = s;} - inline void SetWhiteSpaces(std::string w) {form.white = w;} - inline void SetCommentMark(std::string c) {form.cmtmark = c;} - inline void SetCommentPair(std::string o, std::string c) {form.cmtopen = o; form.cmtclose = c;} - inline void SetLineGlues(std::string g) {form.glue = g;} - inline void SetLineBreaks(std::string b) {form.delim = b;} - - const Format &GetFormat() const {return form;} - - // dealing with file/buffer - bool OpenFile(const std::string &path, size_t cap = 64*1024); - bool ReadFile(const std::string &path); - void ReadBuffer(const char*); - void CloseFile(); - void Clear(); - - // parse line, return false if no more line to parse - bool ParseLine(); - // parse the whole file or buffer, return false if no elements found - bool ParseAll(); - // parse a string, trim and split it into elements - int ParseString(const std::string &line); - - // get current parsing status - bool CheckElements(int num, int optional = 0); - int NbofElements() const {return elements.size();} - int LineNumber() const {return line_number;} - std::string CurrentLine() const {return cur_line.String();} - - // take the elements - ConfigValue TakeFirst(); - - template<typename T> - T TakeFirst() - { - return TakeFirst().Convert<T>(); - } - - template<typename T> - ConfigParser &operator >>(T &t) - { - t = (*this).TakeFirst().Convert<T>(); - return *this; - } - - template<class BidirIt> - int Take(BidirIt first, BidirIt last) - { - int count = 0; - for(auto it = first; it != last; ++it, ++count) - { - if(elements.empty()) - break; - - *it = elements.front(); - elements.pop_front(); - } - return count; - } - - template<template<class, class> class Container> - Container<ConfigValue, std::allocator<ConfigValue>> TakeAll() - { - Container<ConfigValue, std::allocator<ConfigValue>> res; - while(elements.size()) - { - res.emplace_back(std::move(elements.front())); - elements.pop_front(); - } - return res; - } - - template<template<class, class> class Container, class T> - Container<T, std::allocator<T>> TakeAll() - { - Container<T, std::allocator<T>> res; - while(elements.size()) - { - ConfigValue tmp(std::move(elements.front())); - elements.pop_front(); - res.emplace_back(tmp.Convert<T>()); - } - return res; - } - - -private: - // private functions - bool getBuffer(); - bool getLine(CharBuffer &line_buf, bool recursive = false); - int parseBuffer(const CharBuffer &line); - -private: - // private members - Format form; - std::ifstream infile; - CharBuffer buf, cur_line; - int line_number; - std::deque<std::string> elements; - -public: - // static functions - static void comment_line(std::string &str, const std::string &cmt, const std::string &brk); - static void comment_between(std::string &str, const std::string &open, const std::string &close); - static std::string trim(const std::string &str, const std::string &w); - static std::deque<std::string> split(const std::string &str, const std::string &s); - static std::deque<std::string> split(const char* str, const size_t &len, const std::string &s); - static std::string get_split_part(int num, const char *str, const char &s); - static int get_part_count(const char *cmp, const char *str, const char &s); - static std::vector<int> stois(const std::string &str, const std::string &s, const std::string &w); - static std::vector<float> stofs(const std::string &str, const std::string &s, const std::string &w); - static std::vector<double> stods(const std::string &str, const std::string &s, const std::string &w); - static std::string str_remove(const std::string &str, const std::string &ignore); - static std::string str_replace(const std::string &str, const std::string &ignore, const char &rc = ' '); - static std::string str_lower(const std::string &str); - static std::string str_upper(const std::string &str); - static std::pair<size_t, size_t> find_pair(const std::string &str, - const std::string &open, - const std::string &close, - size_t pos = 0); - static bool case_ins_equal(const std::string &str1, const std::string &str2); - static int find_integer(const std::string &str, const size_t &pos = 0); - static std::vector<int> find_integers(const std::string &str); - static void find_integer_helper(const std::string &str, std::vector<int> &result); - struct PathInfo { std::string dir, name, ext; }; - static PathInfo decompose_path(const std::string &path); - static std::string compose_path(const PathInfo &path); - static std::string form_path(const std::string &dir, const std::string &file); - static std::string file_to_string(const std::string &path); - // break text file into several blocks in the format - // <label> <open_mark> <content> <close_mark>, this structure can be separated by sep characters - // return extracted <residual> {<label> <content>} with white characters trimmed - struct TextBlock {std::string label, content;}; - struct TextBlocks {std::string residual; std::vector<TextBlock> blocks;}; - static TextBlocks break_into_blocks(const std::string &buf, - const std::string &open = "{", - const std::string &close = "}", - const std::string &seps = " \t\n"); - -}; - -#endif diff --git a/src/ConfigValue.cpp b/src/ConfigValue.cpp deleted file mode 100644 index 96bd4b2ead9db0fe957b8cb11cb1c260f4e75fae..0000000000000000000000000000000000000000 --- a/src/ConfigValue.cpp +++ /dev/null @@ -1,317 +0,0 @@ -//============================================================================// -// A string wrapper class that convert string to other data types // -// // -// Chao Peng // -// 06/07/2016 // -//============================================================================// - -#include "ConfigValue.h" -#include "ConfigParser.h" -#include <climits> -#include <algorithm> - -using namespace std; - - - -//============================================================================// -// Constructors, Destructor and Assignment Operators // -//============================================================================// - -ConfigValue::ConfigValue(const string &value) -: _value(value) -{} - -ConfigValue::ConfigValue(string &&value) -: _value(move(value)) -{} - -ConfigValue::ConfigValue(const char *value) -: _value(value) -{} - -ConfigValue::ConfigValue(const bool &value) -{ - if(value) - _value = "1"; - else - _value = "0"; -} - -ConfigValue::ConfigValue(const int &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const long &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const long long &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const unsigned &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const unsigned long &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const unsigned long long &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const float &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const double &value) -: _value(to_string(value)) -{} - -ConfigValue::ConfigValue(const long double &value) -: _value(to_string(value)) -{} - -ConfigValue &ConfigValue::operator =(const string &str) -{ - (*this)._value = str; - return *this; -} - -ConfigValue &ConfigValue::operator =(string &&str) -{ - (*this)._value = move(str); - return *this; -} - - -//============================================================================// -// Public Member functions // -//============================================================================// - -bool ConfigValue::Bool() -const -{ - if((_value == "1") || - (ConfigParser::case_ins_equal(_value, "T")) || - (ConfigParser::case_ins_equal(_value, "True")) || - (ConfigParser::case_ins_equal(_value, "Y")) || - (ConfigParser::case_ins_equal(_value, "Yes"))) - return true; - - if((_value == "0") || - (ConfigParser::case_ins_equal(_value, "F")) || - (ConfigParser::case_ins_equal(_value, "False")) || - (ConfigParser::case_ins_equal(_value, "N")) || - (ConfigParser::case_ins_equal(_value, "No"))) - return false; - - cout << "Config Value: Failed to convert " - << _value << " to bool type. Return false." - << endl; - return false; -} - -char ConfigValue::Char() -const -{ - try { - int value = stoi(_value); - if(value > CHAR_MAX) - cout << "Config Value: Limit exceeded while converting " - << _value << " to char." << endl; - return (char) value; - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to char. 0 returned." << endl; - return 0; - } -} - -unsigned char ConfigValue::UChar() -const -{ - try { - unsigned long value = stoul(_value); - if(value > UCHAR_MAX) - cout << "Config Value: Limit exceeded while converting " - << _value << " to unsigned char." << endl; - return (unsigned char) value; - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to unsigned char. 0 returned." << endl; - return 0; - } -} - -short ConfigValue::Short() -const -{ - try { - int value = stoi(_value); - if(value > SHRT_MAX) - cout << "Config Value: Limit exceeded while converting " - << _value << " to short." << endl; - return (short) value; - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to short. 0 returned." << endl; - return 0; - } -} - -unsigned short ConfigValue::UShort() -const -{ - try { - unsigned long value = stoul(_value); - if(value > USHRT_MAX) - cout << "Config Value: Limit exceeded while converting " - << _value << " to unsigned short." << endl; - return (unsigned short) value; - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to unsigned short. 0 returned." << endl; - return 0; - } -} - -int ConfigValue::Int() -const -{ - try { - return stoi(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to int. 0 returned." << endl; - return 0; - } -} - -unsigned int ConfigValue::UInt() -const -{ - try { - return (unsigned int)stoul(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to unsigned int. 0 returned." << endl; - return 0; - } -} - -long ConfigValue::Long() -const -{ - try { - return stol(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to long. 0 returned." << endl; - return 0; - } -} - -long long ConfigValue::LongLong() -const -{ - try { - return stoll(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to long long. 0 returned." << endl; - return 0; - } -} - -unsigned long ConfigValue::ULong() -const -{ - try { - return stoul(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to unsigned long. 0 returned." << endl; - return 0; - } -} - -unsigned long long ConfigValue::ULongLong() -const -{ - try { - return stoull(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to unsigned long long. 0 returned." << endl; - return 0; - } -} - -float ConfigValue::Float() -const -{ - try { - return stof(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to float. 0 returned." << endl; - return 0; - } -} - -double ConfigValue::Double() -const -{ - try { - return stod(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to double. 0 returned." << endl; - return 0; - } -} - -long double ConfigValue::LongDouble() -const -{ - try { - return stold(_value); - } catch (exception &e) { - cerr << e.what() << endl; - cerr << "Config Value: Failed to convert " - << _value << " to long double. 0 returned." << endl; - return 0; - } -} - -const char *ConfigValue::c_str() -const -{ - return _value.c_str(); -} - - - -//============================================================================// -// Other functions // -//============================================================================// - -ostream &operator << (ostream &os, const ConfigValue &b) -{ - return os << b.c_str(); -} diff --git a/src/ConfigValue.h b/src/ConfigValue.h deleted file mode 100644 index aaf3a36103cf96af200f2b68f1f330278a8ae46a..0000000000000000000000000000000000000000 --- a/src/ConfigValue.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef CONFIG_VALUE_H -#define CONFIG_VALUE_H - -#include <string> -#include <iostream> -#include <sstream> -#include <utility> -#include <typeinfo> - -// demangle type name -#ifdef __GNUG__ -#include <cstdlib> -#include <memory> -#include <cxxabi.h> -// gnu compiler needs to demangle type info -static inline std::string demangle(const char* name) -{ - - int status = 0; - - //enable c++11 by passing the flag -std=c++11 to g++ - std::unique_ptr<char, void(*)(void*)> res { - abi::__cxa_demangle(name, NULL, NULL, &status), - std::free - }; - - return (status==0) ? res.get() : name ; -} -#else -// do nothing if not gnu compiler -static inline std::string demangle(const char* name) -{ - return name; -} -#endif - -// this helps template specialization in class -template <typename T> -struct __cv_id { typedef T type; }; - -class ConfigValue -{ -public: - friend class ConfigParser; - friend class ConfigObject; - -public: - ConfigValue() {} - - ConfigValue(const std::string &value); - ConfigValue(std::string &&value); - ConfigValue(const int &value); - ConfigValue(const double &value); - explicit ConfigValue(const char *value); - explicit ConfigValue(const bool &value); - explicit ConfigValue(const long &value); - explicit ConfigValue(const long long &value); - explicit ConfigValue(const unsigned &value); - explicit ConfigValue(const unsigned long &value); - explicit ConfigValue(const unsigned long long &value); - explicit ConfigValue(const float &value); - explicit ConfigValue(const long double &value); - - ConfigValue &operator =(const std::string &str); - ConfigValue &operator =(std::string &&str); - - bool Bool() const; - char Char() const; - unsigned char UChar() const; - short Short() const; - unsigned short UShort() const; - int Int() const; - unsigned int UInt() const; - long Long() const; - long long LongLong() const; - unsigned long ULong() const; - unsigned long long ULongLong() const; - float Float() const; - double Double() const; - long double LongDouble() const; - const char *c_str() const; - const std::string &String() const {return _value;} - bool IsEmpty() const {return _value.empty();} - - operator std::string() - const - { - return _value; - } - - bool operator ==(const std::string &rhs) - const - { - return _value == rhs; - } - - template<typename T> - T Convert() - const - { - return convert( __cv_id<T>()); - } - -private: - std::string _value; - - template<typename T> - T convert(__cv_id<T> &&) - const - { - std::stringstream iss(_value); - T _cvalue; - - if(!(iss >> _cvalue)) { - std::cerr << "Config Value Warning: Undefined value returned, failed to convert " - << _value - << " to " - << demangle(typeid(T).name()) - << std::endl; - } - - return _cvalue; - } - - ConfigValue convert(__cv_id<ConfigValue>) const {return *this;} - bool convert(__cv_id<bool> &&) const {return (*this).Bool();} - float convert(__cv_id<float> &&) const {return (*this).Float();} - double convert(__cv_id<double> &&) const {return (*this).Double();} - long double convert(__cv_id<long double> &&) const {return (*this).LongDouble();} - std::string convert(__cv_id<std::string> &&) const {return (*this)._value;} - const char* convert(__cv_id<const char*> &&) const {return (*this)._value.c_str();} - -}; - -// show string content of the config value to ostream -std::ostream &operator << (std::ostream &os, const ConfigValue &b); - -#endif diff --git a/src/PRadETChannel.cxx b/src/PRadETChannel.cxx deleted file mode 100644 index fe698b6ee553f9a08dab927a84f2ef1c24767e27..0000000000000000000000000000000000000000 --- a/src/PRadETChannel.cxx +++ /dev/null @@ -1,350 +0,0 @@ -//============================================================================// -// A C++ wrapper class for C based ET // -// // -// Chao Peng // -// 02/27/2016 // -//============================================================================// - -#include "PRadETChannel.h" -#include "PRadETStation.h" -#include <iostream> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> -#include <time.h> -#include <pthread.h> - -using namespace std; - -PRadETChannel::PRadETChannel(size_t size) -: curr_stat(nullptr), et_id(nullptr), bufferSize(size) -{ - buffer = new uint32_t[bufferSize]; -} - -PRadETChannel::~PRadETChannel() -{ - if(buffer != nullptr) - delete[](buffer), buffer = nullptr; - - // force close ET - ForceClose(); -} - -// Close ET connection -void PRadETChannel::ForceClose() -{ - if((et_id != nullptr) && et_alive(et_id)) { - et_forcedclose(et_id); - et_id = nullptr; - } -} - -// Open ET -void PRadETChannel::Open(const char* ipAddr, int tcpPort, const char* etFile) -{ - // Use a direct connection to the ET system - config.SetCast(ET_DIRECT); - - // Set the ip address and tcp port - config.SetHost(ipAddr); - config.SetServerPort(tcpPort); - - int charSize = strlen(etFile)+1; - char *fileName = new char[charSize]; - strncpy(fileName, etFile, charSize); - - // Open et client - int status = et_open(&et_id, fileName, config.Get()); - delete fileName; - - if(status != ET_OK) { - throw(PRadException(PRadException::ET_CONNECT_ERROR, "et_client: cannot open et client!")); - } - - /* set level of debug output */ - et_system_setdebug(et_id, ET_DEBUG_INFO); -} - -void PRadETChannel::NewStation(const string &name, int mode) -{ - auto it = stations.find(name); - if(it == stations.end()) { - curr_stat = new PRadETStation(this, name, mode); - stations[string(name)] = curr_stat; - } -} - -void PRadETChannel::SwitchStation(const string &name) -{ - auto it = stations.find(name); - if(it != stations.end()) { - curr_stat = it->second; - } else { - cout << "ET Channel Warning: station " << name << " does not exist!" << endl; - } -} - -void PRadETChannel::RemoveStation(const string &name) -{ - try { - if(et_id != nullptr && et_alive(et_id)) { - auto it = stations.find(name); - if(it != stations.end()) { - it->second->Remove(); - stations.erase(it); - } else { - cout << "ET Channel Warning: station " << name << " does not exist!" << endl; - } - } else { - cout << "ET Channel Warning: cannot remove station while disconnected from ET!" << endl; - } - } catch (PRadException e) { - throw e; - } -} - -PRadETStation* PRadETChannel::GetStation(const string &name) -{ - auto it = stations.find(name); - if(it != stations.end()) { - return it->second; - } else { - return nullptr; - } -} - -// Attach station -void PRadETChannel::AttachStation() -{ - try { - curr_stat->Create(); - curr_stat->Attach(); - } catch (PRadException e) { - throw(e); - } - cout << "Successfully attached to ET!" << endl; -} - - -// Read one event from ET station, return true if success -bool PRadETChannel::Read() -{ - // check if et is opened or alive - if(et_id == nullptr || !et_alive(et_id)) - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is not opened or dead!")); - - et_att_id att = curr_stat->GetAttachID(); - - // get the event - int status = et_event_get(et_id, att, &etEvent, ET_ASYNC, nullptr); - - switch(status) - { - case ET_OK: - break; - case ET_ERROR_EMPTY: - return false; - case ET_ERROR_DEAD: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is dead!")); - case ET_ERROR_TIMEOUT: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: got timeout!!")); - case ET_ERROR_BUSY: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: station is busy!")); - case ET_ERROR_WAKEUP: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: someone told me to wake up.")); - default: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: unkown error!")); - } - - // copy the data buffer - copyEvent(); - - // put back the event - status = et_event_put(et_id, att, etEvent); - - switch(status) - { - case ET_OK: - break; - case ET_ERROR_DEAD: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is dead!")); - default: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: unkown error!")); - } - - return true; -} - - -bool PRadETChannel::Write(void *buf, int nbytes) -{ - // check if et is opened or alive - if(et_id == nullptr || !et_alive(et_id)) - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is not opened or dead!")); - - et_att_id att = curr_stat->GetAttachID(); - - int status = et_event_new(et_id, att, &etEvent, ET_SLEEP, nullptr, nbytes); - - switch(status) { - case ET_OK: - break; - case ET_ERROR_EMPTY: - return false; - case ET_ERROR_DEAD: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is dead!")); - case ET_ERROR_TIMEOUT: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: got timeout!!")); - case ET_ERROR_BUSY: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: station is busy!")); - case ET_ERROR_WAKEUP: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: someone told me to wake up.")); - default: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: unkown error!")); - } - - // build et event - void *data; - et_event_getdata(etEvent, &data); - memcpy((void *) data, (const void *) buf, nbytes); - et_event_setlength(etEvent, nbytes); - - // put back the event - status = et_event_put(et_id, att, etEvent); - - switch(status) - { - case ET_OK: - break; - case ET_ERROR_DEAD: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: et is dead!")); - default: - throw(PRadException(PRadException::ET_READ_ERROR,"et_client: unkown error!")); - } - - return true; -} - -void PRadETChannel::copyEvent() -{ - void *data; - et_event_getdata(etEvent, &data); - et_event_getlength(etEvent, &bufferSize); - bufferSize /= 4; // from byte to int32 words - - uint32_t *data_buffer = (uint32_t*) data; - size_t index = 0; - // check if it is a block header - if(bufferSize >= 8 && data_buffer[7] == 0xc0da0100) { - index += 8; - bufferSize -= 8; - } - - for(size_t i = 0; i < bufferSize; ++i) - { - buffer[i] = data_buffer[index+i]; - } -} - - -// nested config classes -// et_openconfig -PRadETChannel::Configuration::Configuration() -{ - Initialize(); -} - -PRadETChannel::Configuration::~Configuration() -{ - et_open_config_destroy(config); -} - -// wrapper functions -void PRadETChannel::Configuration::Initialize() -{ - et_open_config_init(&config); -} - -void PRadETChannel::Configuration::SetWait(int val) -{ - et_open_config_setwait(config, val); -} - -void PRadETChannel::Configuration::SetTimeOut(struct timespec val) -{ - et_open_config_settimeout(config, val); -} - -void PRadETChannel::Configuration::SetHost(const char *val) -{ - et_open_config_sethost(config, val); -} - -void PRadETChannel::Configuration::SetCast(int val) -{ - et_open_config_setcast(config, val); -} - -void PRadETChannel::Configuration::SetTTL(int val) -{ - et_open_config_setTTL(config, val); -} - -void PRadETChannel::Configuration::SetPort(unsigned short val) -{ - et_open_config_setport(config, val); -} - -void PRadETChannel::Configuration::SetServerPort(unsigned short val) -{ - et_open_config_setserverport(config, val); -} - -void PRadETChannel::Configuration::AddBroadCast(const char *val) -{ - et_open_config_addbroadcast(config, val); -} - -void PRadETChannel::Configuration::RemoveBroadCast(const char *val) -{ - et_open_config_removebroadcast(config, val); -} - -void PRadETChannel::Configuration::AddMultiCast(const char *val) -{ - et_open_config_addmulticast(config, val); -} - -void PRadETChannel::Configuration::RemoveMultiCast(const char *val) -{ - et_open_config_removemulticast(config, val); -} - -void PRadETChannel::Configuration::SetPolicy(int val) -{ - et_open_config_setpolicy(config, val); -} - -void PRadETChannel::Configuration::SetMode(int val) -{ - et_open_config_setmode(config, val); -} - -void PRadETChannel::Configuration::SetDebugDefault(int val) -{ - et_open_config_setdebugdefault(config, val); -} - -void PRadETChannel::Configuration::SetInterface(const char *val) -{ - et_open_config_setinterface(config, val); -} - -void PRadETChannel::Configuration::SetTCP(int rBufSize, int sBufSize, int noDelay) -{ - et_open_config_settcp(config, rBufSize, sBufSize, noDelay); -} - diff --git a/src/PRadETChannel.h b/src/PRadETChannel.h deleted file mode 100644 index 0f67aef5a82b8a2410c0b15a4bb8057c79d4ff77..0000000000000000000000000000000000000000 --- a/src/PRadETChannel.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef PRAD_ET_CHANNEL_H -#define PRAD_ET_CHANNEL_H - -#include <unordered_map> -#include <string> -#include <stdint.h> -#include "et.h" -#include "PRadException.h" -#include "PRadETStation.h" - -#define ET_CHUNK_SIZE 500 - -class PRadETChannel -{ - -public: - class Configuration - { - public: - Configuration(); - virtual ~Configuration(); - - et_openconfig &Get() {return config;} - - // wrapper functions - void Initialize(); - void SetWait(int val); - void SetTimeOut(struct timespec val); - void SetHost(const char *val); - void SetCast(int val); - void SetTTL(int val); - void SetPort(unsigned short val); - void SetServerPort(unsigned short val); - void AddBroadCast(const char *val); - void RemoveBroadCast(const char *val); - void AddMultiCast(const char *val); - void RemoveMultiCast(const char *val); - void SetPolicy(int val); - void SetMode(int val); - void SetDebugDefault(int val); - void SetInterface(const char *val); - void SetTCP(int rBufSize, int sBufSize, int noDelay); - - private: - et_openconfig config; - }; - - -public: - PRadETChannel(size_t size = 1048576); - virtual ~PRadETChannel(); - void Open(const char *ipAddr, int tcpPort, const char *etFile); - void NewStation(const std::string &name, int mode=2); - void SwitchStation(const std::string &name); - void RemoveStation(const std::string &name); - void AttachStation(); - void DetachStation(); - void ForceClose(); - bool Read(); - bool Write(void *buf, int nbytes); - void *GetBuffer() {return (void*) buffer;} - size_t GetBufferLength() {return bufferSize;} - Configuration &GetConfig() {return config;} - et_sys_id &GetID() {return et_id;} - PRadETStation *GetCurrentStation() {return curr_stat;} - PRadETStation *GetStation(const std::string &name); - -private: - Configuration config; - PRadETStation *curr_stat; - std::unordered_map<std::string, PRadETStation*> stations; - et_sys_id et_id; - et_event *etEvent; - uint32_t *buffer; - size_t bufferSize; - void copyEvent(); -}; - -#endif diff --git a/src/PRadETStation.cxx b/src/PRadETStation.cxx deleted file mode 100644 index 4c814f71a170496aa28b1ed583ef622a0116c037..0000000000000000000000000000000000000000 --- a/src/PRadETStation.cxx +++ /dev/null @@ -1,189 +0,0 @@ -//============================================================================// -// A C++ wrapper class for C based ET station // -// // -// Chao Peng // -// 04/01/2016 // -//============================================================================// - -#include "PRadETStation.h" -#include "PRadETChannel.h" - - -PRadETStation::PRadETStation(PRadETChannel *p, std::string n, int mode) -: et_system(p), name(n) -{ - PreSetting(mode); -} - -PRadETStation::~PRadETStation() -{ - Remove(); -} - -void PRadETStation::PreSetting(int mode) -{ - // Generic settings - config.SetUser(ET_STATION_USER_MULTI); - config.SetRestore(ET_STATION_RESTORE_OUT); - config.SetPrescale(1); - config.SetCUE(ET_CHUNK_SIZE); - - // TODO, change to meaningful settings - int selections[] = {17,15,-1,-1}; - char fName[] = "et_my_function"; - char libName[] = "libet_user.so"; - - // some pre-defined settings - // TODO, make these settings selectable - switch(mode) - { - case 1: - config.SetSelect(ET_STATION_SELECT_ALL); - config.SetBlock(ET_STATION_BLOCKING); - break; - case 2: - config.SetSelect(ET_STATION_SELECT_ALL); - config.SetBlock(ET_STATION_NONBLOCKING); - break; - case 3: - config.SetSelect(ET_STATION_SELECT_MATCH); - config.SetBlock(ET_STATION_BLOCKING); - config.SetSelectWords(selections); - break; - case 4: - config.SetSelect(ET_STATION_SELECT_MATCH); - config.SetBlock(ET_STATION_NONBLOCKING); - config.SetSelectWords(selections); - break; - case 5: - config.SetSelect(ET_STATION_SELECT_USER); - config.SetBlock(ET_STATION_BLOCKING); - config.SetSelectWords(selections); - config.SetFunction(fName); - config.SetLib(libName); - break; - case 6: - config.SetSelect(ET_STATION_SELECT_USER); - config.SetBlock(ET_STATION_NONBLOCKING); - config.SetSelectWords(selections); - config.SetFunction(fName); - config.SetLib(libName); - break; - } -} - -// Create station -void PRadETStation::Create() -{ - char s_name[256]; - strcpy(s_name, name.c_str()); - - /* create the station */ - int status = et_station_create(et_system->GetID(), &station_id, s_name, config.Get()); - - if(status < ET_OK) { - if(status == ET_ERROR_EXISTS) { - /* station_id contains pointer to existing station */; - throw(PRadException(PRadException::ET_STATION_CREATE_ERROR, "et_client: station already exists!")); - } else if(status == ET_ERROR_TOOMANY) { - throw(PRadException(PRadException::ET_STATION_CREATE_ERROR, "et_client: too many stations created!")); - } else { - throw(PRadException(PRadException::ET_STATION_CREATE_ERROR, "et_client: error in station creation!")); - } - } -} - -void PRadETStation::Attach() -{ - if(et_station_attach(et_system->GetID(), station_id, &attach_id) < ET_OK) { - throw(PRadException(PRadException::ET_STATION_ATTACH_ERROR, "et_client: error in station attach!")); - } -} - -void PRadETStation::Detach() -{ - if(et_station_detach(et_system->GetID(), attach_id) < ET_OK) { - throw(PRadException(PRadException::ET_STATION_ATTACH_ERROR, "et_client: error in station dettach!")); - } -} - -void PRadETStation::Remove() -{ - if(et_station_remove(et_system->GetID(), station_id) < ET_OK) { - throw(PRadException(PRadException::ET_STATION_ATTACH_ERROR, "et_client: error in station remove!")); - } -} - - -// et_station_config -PRadETStation::Configuration::Configuration() -{ - Initialize(); -} - -PRadETStation::Configuration::~Configuration() -{ - et_station_config_destroy(config); -} - -// wrapper functions -void PRadETStation::Configuration::Initialize() -{ - et_station_config_init(&config); -} - -void PRadETStation::Configuration::SetBlock(int val) -{ - et_station_config_setblock(config, val); -} - -void PRadETStation::Configuration::SetFlow(int val) -{ - et_station_config_setflow(config, val); -} - -void PRadETStation::Configuration::SetSelect(int val) -{ - et_station_config_setselect(config, val); -} - -void PRadETStation::Configuration::SetUser(int val) -{ - et_station_config_setuser(config, val); -} - -void PRadETStation::Configuration::SetRestore(int val) -{ - et_station_config_setrestore(config, val); -} - -void PRadETStation::Configuration::SetCUE(int val) -{ - et_station_config_setcue(config, val); -} - -void PRadETStation::Configuration::SetPrescale(int val) -{ - et_station_config_setprescale(config, val); -} - -void PRadETStation::Configuration::SetSelectWords(int val[]) -{ - et_station_config_setselectwords(config, val); -} - -void PRadETStation::Configuration::SetFunction(const char *val) -{ - et_station_config_setfunction(config, val); -} - -void PRadETStation::Configuration::SetLib(const char *val) -{ - et_station_config_setlib(config, val); -} - -void PRadETStation::Configuration::SetClass(const char *val) -{ - et_station_config_setclass(config, val); -} - diff --git a/src/PRadETStation.h b/src/PRadETStation.h deleted file mode 100644 index 8745dc4a0c137b6a8614ed452025273d69c867ed..0000000000000000000000000000000000000000 --- a/src/PRadETStation.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef PRAD_ET_STATION_H -#define PRAD_ET_STATION_H - -#include "et.h" -#include "PRadException.h" -#include <string> - -class PRadETChannel; - -class PRadETStation -{ -public: - class Configuration - { - public: - Configuration(); - virtual ~Configuration(); - - et_statconfig &Get() {return config;} - - //wrapper functions - void Initialize(); - void SetBlock(int val); - void SetFlow(int val); - void SetSelect(int val); - void SetUser(int val); - void SetRestore(int val); - void SetCUE(int val); - void SetPrescale(int val); - void SetSelectWords(int val[]); - void SetFunction(const char *val); - void SetLib(const char *val); - void SetClass(const char *val); - - private: - et_statconfig config; - }; - -public: - PRadETStation(PRadETChannel *p, std::string n, int mode = 2); - virtual ~PRadETStation(); - Configuration &GetConfig() {return config;} - et_stat_id &GetID() {return station_id;} - et_att_id &GetAttachID() {return attach_id;} - std::string GetName() {return name;} - void PreSetting(int mode); - void Create(); - void Attach(); - void Detach(); - void Remove(); - -private: - PRadETChannel *et_system; - std::string name; - et_att_id attach_id; - et_stat_id station_id; - Configuration config; -}; - -#endif diff --git a/src/PRadException.cxx b/src/PRadException.cxx deleted file mode 100644 index e27e420616524730582ade6cad1cfbb7b995296c..0000000000000000000000000000000000000000 --- a/src/PRadException.cxx +++ /dev/null @@ -1,83 +0,0 @@ -//============================================================================// -// A exception class for PRad Event Viewer // -// // -// Chao Peng // -// 02/27/2016 // -//============================================================================// - -#include "PRadException.h" - -using namespace std; - -PRadException::PRadException(const string &typ, const string &txt, const string &aux) -: title(typ), text(txt), auxText(aux) -{ -} - -PRadException::PRadException(PRadExceptionType typ, const string &txt, const string &aux) -: type(typ), text(txt), auxText(aux) -{ -} - -PRadException::PRadException(PRadExceptionType typ, const string &txt, const string &file, const string &func, int line) -: type(typ), text(txt) -{ - ostringstream oss; - oss << " evioException occured in file " << file << ", function " << func << ", line " << line; - auxText=oss.str(); -} - - -string PRadException::FailureDesc(void) const -{ - ostringstream oss; - oss << text << endl - << auxText; - return(oss.str()); -} - -string PRadException::FailureType(void) const -{ - if(!title.empty()) - return title; - - string oss; - switch(type) - { - case ET_CONNECT_ERROR: - oss = "ET CONNECT ERROR"; - break; - case ET_CONFIG_ERROR: - oss = "ET CONFIG ERROR"; - break; - case ET_STATION_CONFIG_ERROR: - oss = "ET STATION CONFIG ERROR"; - break; - case ET_STATION_CREATE_ERROR: - oss = "ET STATION CREATE ERROR"; - break; - case ET_STATION_ATTACH_ERROR: - oss = "ET ATTACH ERROR"; - break; - case ET_READ_ERROR: - oss = "ET READ ERROR"; - break; - case ET_PUT_ERROR: - oss = "ET PUT ERROR"; - break; - case HIGH_VOLTAGE_ERROR: - oss = "HIGH VOLTAGE SYSTEM ERROR"; - break; - default: - oss = "UNKNOWN ERROR"; - break; - } - - return(oss); -} - -const char* PRadException::what() const noexcept -{ - string failure = FailureType() + ": " + FailureDesc(); - return failure.c_str(); -} diff --git a/src/PRadException.h b/src/PRadException.h deleted file mode 100644 index ca721b3b2d8be2087e15904601f3235ff7151622..0000000000000000000000000000000000000000 --- a/src/PRadException.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PRAD_EXCEPTION_H -#define PRAD_EXCEPTION_H - - -#include <stdlib.h> -#include <string.h> -#include <exception> -#include <string> -#include <sstream> - -class PRadException : public std::exception -{ -public: - enum PRadExceptionType - { - UNKNOWN_ERROR, - ET_CONNECT_ERROR, - ET_CONFIG_ERROR, - ET_STATION_CONFIG_ERROR, - ET_STATION_CREATE_ERROR, - ET_STATION_ATTACH_ERROR, - ET_READ_ERROR, - ET_PUT_ERROR, - HIGH_VOLTAGE_ERROR, - }; - PRadException(const std::string &typ, const std::string &txt = "", const std::string &aux = ""); - PRadException(PRadExceptionType typ = UNKNOWN_ERROR, const std::string &txt = "", const std::string &aux = ""); - PRadException(PRadExceptionType typ, const std::string &txt, const std::string &file, const std::string &func, int line); - virtual ~PRadException(void) {} - virtual std::string FailureDesc(void) const; - virtual std::string FailureType(void) const; - const char *what() const noexcept; - -public: - PRadExceptionType type; // exception type - std::string title; - std::string text; // primary text - std::string auxText; // auxiliary text -}; - -#endif - - diff --git a/src/THcOnlineRun.cxx b/src/THcOnlineRun.cxx deleted file mode 100644 index 521961bbb7d9dd9fb3c8e03e09228e4eec6425d4..0000000000000000000000000000000000000000 --- a/src/THcOnlineRun.cxx +++ /dev/null @@ -1,274 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Class THcOnlineRun // -// Read event from ET instead of CODA file // -// // -// Developer: // -// Chao Peng // -// 11/22/2019 // -/////////////////////////////////////////////////////////////////////////////// - -#include "THcOnlineRun.h" -#include "THcGlobals.h" -#include <string> - - -template<class Interval> -auto get_next_time(Interval itvl) -{ - return std::chrono::system_clock::now() + itvl; -} - -std::string et_error_to_string(int error) -{ - switch(error) { - case ET_ERROR_EMPTY: return "et_client: empty et event."; - case ET_ERROR_DEAD: return "et client: et is dead!"; - case ET_ERROR_TIMEOUT: return "et client: got timeout!"; - case ET_ERROR_BUSY: return "et client: et is busy!"; - case ET_ERROR_WAKEUP: return "et_client: et is waking up."; - default: break; - } - return "et_client: unknown et error."; -} - -// Constructors -THcOnlineRun::THcOnlineRun(UInt_t size, std::chrono::milliseconds itvl, Int_t mtries, Int_t vers) -: THcRun(), version(vers), bSize(size), eSize(0), interval(itvl), max_tries(mtries), - et_id(nullptr), stat_id(ID_NULL), att_id(ID_NULL) -{ - buffer = new UInt_t[size]; - clock = get_next_time(itvl); -} - -// Copy constructor -THcOnlineRun::THcOnlineRun(const THcOnlineRun& rhs) -: THcRun(rhs) -{ - interval = rhs.interval; - max_tries = rhs.max_tries; - // do not copy the ownership of et system - et_id = nullptr; - stat_id = ID_NULL; - att_id = ID_NULL; -} - -// Missing move constructor, not implementing for consistency with the analyzer - -// Copy assignment operator -THcOnlineRun& THcOnlineRun::operator=(const THcOnlineRun& rhs) -{ - if (this != &rhs) { - interval = rhs.interval; - max_tries = rhs.max_tries; - et_id = nullptr; - stat_id = ID_NULL; - att_id = ID_NULL; - THcRun::operator=(rhs); - } - return *this; -} - -// Missing move assignment operator, not implementing for consistency with the analyzer - -// Destructor. -THcOnlineRun::~THcOnlineRun() -{ - // delete buffer - if (buffer != nullptr) { - delete[](buffer), buffer = nullptr; - } - // do not touch et_event as it is managed by the et system - Close(); -} - -// Connect a ET system and create a monitor station with pre-settings -Int_t THcOnlineRun::Connect(const char *ip_addr, int port, const char *et_file, const char *s_name) -{ - // open et system - auto conf = PRadETChannel::Configuration(); - // use a direct connection to the ET system - conf.SetCast(ET_DIRECT); - conf.SetHost(ip_addr); - conf.SetServerPort(port); - - auto status = Open(et_file, conf); - if (status < ET_OK) { - _logger->error("THcOnlineRun::Connect : Failed to open ET system, abort connection."); - Close(); - return status; - } - - // create a station - auto sconf = PRadETStation::Configuration(); - sconf.SetUser(ET_STATION_USER_MULTI); - sconf.SetRestore(ET_STATION_RESTORE_OUT); - sconf.SetPrescale(1); - sconf.SetCUE(ET_CHUNK_SIZE); - sconf.SetSelect(ET_STATION_SELECT_ALL); - sconf.SetBlock(ET_STATION_NONBLOCKING); - - status = CreateStation(s_name, sconf); - if (status < ET_OK) { - _logger->error("THcOnlineRun::Connect : Failed to create a station, abort connection."); - Close(); - return status; - } - - status = Attach(); - if (status < ET_OK) { - _logger->error("THcOnlineRun::Connect : Failed to attach to the station, abort connection."); - Close(); - return status; - } - - return ET_OK; -} - -// Open ET from configuration -Int_t THcOnlineRun::Open(const char *et_file, PRadETChannel::Configuration conf) -{ - if (IsOpen()) { - _logger->warn("THcOnlineRun::Open : ET system is already opened, close it before re-open"); - return ID_NULL; - } - - char fname[256]; - strncpy(fname, et_file, 256); - return et_open(&et_id, fname, conf.Get()); -} - -// Close ET -Int_t THcOnlineRun::Close() -{ - if ( (et_id != nullptr) && IsOpen() ) { - et_forcedclose(et_id); - et_id = nullptr; - return 1; - } - return 0; -} - -// create a station from configuration -Int_t THcOnlineRun::CreateStation(const char *station_name, PRadETStation::Configuration conf) -{ - if (!IsOpen()) { - _logger->warn("THcOnlineRun::CreateStation : ET System is not opened, abort creating a station."); - return ID_NULL; - } else if (stat_id != ID_NULL) { - _logger->warn("THcOnlineRun::CreateStation : A station has alreadly been created, remove it before re-create a station."); - return ID_NULL; - } - - char sname[256]; - strncpy(sname, station_name, 256); - return et_station_create(et_id, &stat_id, sname, conf.Get()); -} - -// remove the station from et system -Int_t THcOnlineRun::RemoveStation() -{ - if (IsOpen() && (stat_id != ID_NULL)) { - auto status = et_station_remove(et_id, stat_id); - if (status == ET_OK) { - stat_id = ID_NULL; - return status; - } - } - return ID_NULL; -} - -// Attach to a station -Int_t THcOnlineRun::Attach() -{ - return Attach(stat_id); -} - -// Attach to a station with station id -Int_t THcOnlineRun::Attach(et_stat_id sid) -{ - if (!IsOpen()) { - _logger->warn("THcOnlineRun::Attach : ET System is not opened, abort attaching to a station."); - return ID_NULL; - } - return et_station_attach(et_id, sid, &att_id); -} - -// Detach the station -Int_t THcOnlineRun::Detach() -{ - if (IsOpen() && (att_id != ID_NULL)) { - auto status = et_station_detach(et_id, att_id); - if (status == ET_OK) { - att_id = ID_NULL; - return status; - } - } - return ID_NULL; -} - -// copy event to the buffer -bool THcOnlineRun::copyEvent() -{ - void *data; - size_t size; - et_event_getdata(ev, &data); - et_event_getlength(ev, &size); - - // from byte to the buffer type - auto *dBuffer = (decltype(buffer)) data; - size_t bytes = sizeof(decltype(buffer[0])); - eSize = size/bytes + ((size % bytes) ? 1 : 0); - - if (eSize > bSize) { - _logger->warn("THcOnlineRun::copyEvent et event size {} exceeds the buffer size {}.", eSize, bSize); - return false; - } - - for (UInt_t i = 0; i < eSize; ++i) { - buffer[i] = dBuffer[i]; - } - return true; -} - -// read event from et channel -Int_t THcOnlineRun::ReadEvent() -{ - const char *here = "THcOnlineRun::ReadEvent"; - UInt_t ntries = 0; - if (!IsOpen() || att_id == ID_NULL) { - _logger->error("{} Did not connect to an ET system, abort Reading.", here); - return THaRunBase::READ_FATAL; - } - - Int_t read = THaRunBase::READ_OK; - - while(ntries++ < max_tries) { - std::this_thread::sleep_until(clock); - clock = get_next_time(interval); - - auto status = et_event_get(et_id, att_id, &ev, ET_ASYNC, nullptr); - - switch(status) { - case ET_OK: - // copy event to buffer - if (!copyEvent()) { - read = THaRunBase::READ_EMPTY; - } - // put back the event - if (et_event_put(et_id, att_id, ev) != ET_OK) { - _logger->error("{} failed to put back et_event to ET system, abort monitoring.", here); - read = THaRunBase::READ_EOF; - } - return read; - case ET_ERROR_EMPTY: - break; - default: - _logger->error("{} {}", here, et_error_to_string(status).c_str()); - return THaRunBase::READ_FATAL; - } - } - - _logger->info("THcOnlineRun::ReadEvent : Tried {} times and no event obtained from ET.", max_tries); - return THaRunBase::READ_EMPTY; -} - diff --git a/src/THcOnlineRun.h b/src/THcOnlineRun.h deleted file mode 100644 index 021b741e62c467c4ff67cbc7a07a9d4bfb3d121b..0000000000000000000000000000000000000000 --- a/src/THcOnlineRun.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef ROOT_THcOnlineRun -#define ROOT_THcOnlineRun - -//////////////////////////////////////////////////////////////////////////////// -// THcOnline Run // -// a class inherited from THcRun <- THaRun <- THaCodaRun <- THaRunBase so it // -// The main purpose is to overwrite the communication with ThaCodaData // -// directly read events from the ET channel // -// // -// Chao Peng, 11/22/2019 // -//////////////////////////////////////////////////////////////////////////////// - -#include "THcRun.h" -#include "THcParmList.h" -#include "PRadETChannel.h" -#include "PRadETStation.h" -#include <chrono> - - -#define ID_NULL -9999 - -class THcOnlineRun : public THcRun -{ -public: - THcOnlineRun(UInt_t size = 1048576, std::chrono::milliseconds itvl = std::chrono::milliseconds(100), - Int_t mtries = 10, Int_t vers = 2); - THcOnlineRun(const THcOnlineRun &rhs); - THcOnlineRun& operator=(const THcOnlineRun& rhs); - - virtual ~THcOnlineRun(); - - virtual Int_t Connect(const char *ip, int port, const char *etfile, const char *sname = "Monitor"); - virtual Int_t Open(const char *etfile, PRadETChannel::Configuration conf); - virtual Int_t Close(); - virtual Int_t CreateStation(const char *sname, PRadETStation::Configuration conf); - virtual Int_t RemoveStation(); - virtual Int_t Attach(); - virtual Int_t Attach(et_stat_id sid); - virtual Int_t Detach(); - - virtual Bool_t IsOpen() const { return (et_id != nullptr) && et_alive(et_id); } - - virtual const UInt_t *GetEvBuffer() const { return buffer; } - virtual const UInt_t &GetEvLength() const { return eSize; } - virtual Int_t ReadEvent(); - virtual Int_t SkipToEndOfFile(Int_t skip_max = -1) { return 1; } - virtual Int_t GetDataVersion() { return version; } - virtual Int_t SetDataVersion(Int_t vers) { version = vers; return 1; } - -private: - bool copyEvent(); - - std::chrono::milliseconds interval; - std::chrono::time_point<std::chrono::system_clock> clock; - et_event *ev; - Int_t version; - UInt_t *buffer; - UInt_t max_tries, bSize, eSize; - et_sys_id et_id; - et_stat_id stat_id; - et_att_id att_id; - ClassDef(THcOnlineRun, 2); -}; - -#endif // ROOT_THcOnlineRun diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt deleted file mode 100644 index 5913b619cf79375dbab3c0c2e0b40dc1071ad82c..0000000000000000000000000000000000000000 --- a/tools/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ - -file(GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_LIST_DIR} "*.cpp") -foreach(exe_src ${APP_SOURCES}) - string(REPLACE ".cpp" "" exe ${exe_src}) - add_executable(${exe} ${exe_src}) - - target_include_directories(${exe} - PUBLIC #$<INSTALL_INTERFACE:include> - $<INSTALL_INTERFACE:include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/hcana> - $<BUILD_INTERFACE:${Podd_DIR}/../../include/podd2> - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # for hc_compiledata.h - $<BUILD_INTERFACE:${SPDLOG_INCLUDE_DIR}> - $<INSTALL_INTERFACE:${SPDLOG_INCLUDE_DIR}> - $<BUILD_INTERFACE:${FMT_INCLUDE_DIR}> - $<BUILD_INTERFACE:${CODA_ET_INCLUDE_DIR}> - $<BUILD_INTERFACE:${EVIO_INCLUDE_DIR}> - ) - - target_link_libraries(${exe} - PUBLIC - ${PROJECT_NAME}::HallC - Podd::Podd - Podd::Decode - coda_et::coda_et - EVIO::evioxx - ) - install(TARGETS ${exe} DESTINATION ${CMAKE_INSTALL_BINDIR}) -endforeach(exe_src ${APP_SOURCES}) - diff --git a/tools/et_catcher.cpp b/tools/et_catcher.cpp deleted file mode 100644 index 22053751cb7efdf6c87b0543da704850d0507230..0000000000000000000000000000000000000000 --- a/tools/et_catcher.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "ConfigOption.h" -#include "PRadETChannel.h" -#include "et.h" -#include <csignal> -#include <thread> -#include <chrono> -#include <iostream> - -#define PROGRESS_COUNT 10 - -using namespace std::chrono; - - -volatile std::sig_atomic_t gSignalStatus; - - -void signal_handler(int signal) { - gSignalStatus = signal; -} - - -int main(int argc, char* argv[]) try -{ - // setup input arguments - ConfigOption conf_opt; - conf_opt.AddLongOpt(ConfigOption::help_message, "help"); - conf_opt.AddOpt(ConfigOption::arg_require, 'h'); - conf_opt.AddOpt(ConfigOption::arg_require, 'p'); - conf_opt.AddOpt(ConfigOption::arg_require, 'f'); - conf_opt.AddOpt(ConfigOption::arg_require, 'i'); - - conf_opt.SetDesc("usage: %0"); - conf_opt.SetDesc('h', "host address of the ET system, default \"localhost\"."); - conf_opt.SetDesc('p', "port to connect, default 11111."); - conf_opt.SetDesc('f', "memory mapped et file, default \"/tmp/et_feeder\"."); - conf_opt.SetDesc('i', "interval in milliseconds to write data, default \"100\""); - - if (!conf_opt.ParseArgs(argc, argv) || conf_opt.NbofArgs() != 0) { - std::cout << conf_opt.GetInstruction() << std::endl; - return -1; - } - - std::string host = "localhost"; - int port = 11111; - std::string etf = "/tmp/et_feeder"; - int interval = 100; - - for (auto &opt : conf_opt.GetOptions()) { - switch (opt.mark) { - case 'h': - host = opt.var.String(); - break; - case 'c': - port = opt.var.Int(); - break; - case 'f': - etf = opt.var.String(); - break; - case 'i': - interval = opt.var.Int(); - break; - default : - std::cout << conf_opt.GetInstruction() << std::endl; - return -1; - } - } - - // attach to ET system - auto ch = new PRadETChannel; - ch->Open(host.c_str(), port, etf.c_str()); - ch->NewStation("Data Catcher"); - ch->AttachStation(); - - // install signal handler - std::signal(SIGINT, signal_handler); - int count = 0; - while (true) { - if (gSignalStatus == SIGINT) { - std::cout << "Received control-C, exiting..." << std::endl; - ch->ForceClose(); - break; - } - system_clock::time_point start(system_clock::now()); - system_clock::time_point next(start + std::chrono::milliseconds(interval)); - count += ch->Read(); - - std::cout << "Read " << count << " events from ET." << "\r" << std::flush; - - std::this_thread::sleep_until(next); - } - std::cout << "Read " << count << " events from ET." << std::endl; - return 0; - -} catch (PRadException e) { - std::cerr << e.FailureType() << ": " << e.FailureDesc() << std::endl; - return -1; -} catch (...) { - std::cerr << "?unknown exception" << std::endl; -} - diff --git a/tools/et_consumer.cpp b/tools/et_consumer.cpp deleted file mode 100644 index c8d7855924407facc2b984ab85af42b9643f7d99..0000000000000000000000000000000000000000 --- a/tools/et_consumer.cpp +++ /dev/null @@ -1,679 +0,0 @@ -/*----------------------------------------------------------------------------* - * Copyright (c) 1998 Southeastern Universities Research Association, * - * Thomas Jefferson National Accelerator Facility * - * * - * This software was developed under a United States Government license * - * described in the NOTICE file included as part of this distribution. * - * * - * Author: Carl Timmer * - * timmer@jlab.org Jefferson Lab, MS-12B3 * - * Phone: (757) 269-5130 12000 Jefferson Ave. * - * Fax: (757) 269-6248 Newport News, VA 23606 * - * * - *----------------------------------------------------------------------------* - * - * Description: - * ET system sample event consumer - * - *----------------------------------------------------------------------------*/ - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/time.h> -#include <getopt.h> -#include <limits.h> -#include <time.h> - -#include "et.h" - -/* prototype */ -static void *signal_thread (void *arg); - - -int main(int argc,char **argv) { - - int i, j, c, i_tmp, status, numRead, locality; - int flowMode=ET_STATION_SERIAL, position=ET_END, pposition=ET_END; - int errflg=0, chunk=1, qSize=0, verbose=0, remote=0, blocking=1, dump=0, readData=0; - int multicast=0, broadcast=0, broadAndMulticast=0; - int con[ET_STATION_SELECT_INTS]; - int sendBufSize=0, recvBufSize=0, noDelay=0; - int debugLevel = ET_DEBUG_ERROR; - unsigned short port=0; - char stationName[ET_STATNAME_LENGTH], et_name[ET_FILENAME_LENGTH], host[256], interface[16]; - char localAddr[16]; - - int mcastAddrCount = 0, mcastAddrMax = 10; - char mcastAddr[mcastAddrMax][16]; - - pthread_t tid; - et_att_id attach1; - et_stat_id my_stat; - et_sys_id id; - et_statconfig sconfig; - et_event **pe; - et_openconfig openconfig; - sigset_t sigblock; - struct timespec timeout; -#if defined __APPLE__ - struct timeval t1, t2; -#else - struct timespec t1, t2; -#endif - - /* statistics variables */ - double rate=0.0, avgRate=0.0; - int64_t count=0, totalCount=0, totalT=0, time, time1, time2, bytes=0, totalBytes=0; - - - /* 4 multiple character command-line options */ - static struct option long_options[] = - { {"host", 1, NULL, 1}, - {"nb", 0, NULL, 2}, - {"pos", 1, NULL, 3}, - {"ppos", 1, NULL, 4}, - {"rb", 1, NULL, 5}, - {"sb", 1, NULL, 6}, - {"nd", 0, NULL, 7}, - {"dump", 0, NULL, 8}, - {"read", 0, NULL, 9}, - {0,0,0,0}}; - - memset(host, 0, 256); - memset(interface, 0, 16); - memset(mcastAddr, 0, (size_t) mcastAddrMax*16); - memset(et_name, 0, ET_FILENAME_LENGTH); - memset(stationName, 0, ET_STATNAME_LENGTH); - - while ((c = getopt_long_only(argc, argv, "vbmhrn:s:p:f:c:q:a:i:", long_options, 0)) != EOF) { - - if (c == -1) - break; - - switch (c) { - case 'c': - i_tmp = atoi(optarg); - if (i_tmp > 0 && i_tmp < 1001) { - chunk = i_tmp; - printf("Setting chunk to %d\n", chunk); - } else { - printf("Invalid argument to -c. Must < 1001 & > 0.\n"); - exit(-1); - } - break; - - case 'q': - i_tmp = atoi(optarg); - if (i_tmp > 0) { - qSize = i_tmp; - printf("Setting queue size to %d\n", qSize); - } else { - printf("Invalid argument to -q. Must > 0.\n"); - exit(-1); - } - break; - - case 's': - if (strlen(optarg) >= ET_STATNAME_LENGTH) { - fprintf(stderr, "Station name is too long\n"); - exit(-1); - } - strcpy(stationName, optarg); - break; - - case 'p': - i_tmp = atoi(optarg); - if (i_tmp > 1023 && i_tmp < 65535) { - port = (unsigned short)i_tmp; - } else { - printf("Invalid argument to -p. Must be < 65535 & > 1023.\n"); - exit(-1); - } - break; - - case 'f': - if (strlen(optarg) >= ET_FILENAME_LENGTH) { - fprintf(stderr, "ET file name is too long\n"); - exit(-1); - } - strcpy(et_name, optarg); - break; - - case 'i': - if (strlen(optarg) > 15 || strlen(optarg) < 7) { - fprintf(stderr, "interface address is bad\n"); - exit(-1); - } - strcpy(interface, optarg); - break; - - case 'a': - if (strlen(optarg) >= 16) { - fprintf(stderr, "Multicast address is too long\n"); - exit(-1); - } - if (mcastAddrCount >= mcastAddrMax) break; - strcpy(mcastAddr[mcastAddrCount++], optarg); - multicast = 1; - break; - - /* case host: */ - case 1: - if (strlen(optarg) >= 255) { - fprintf(stderr, "host name is too long\n"); - exit(-1); - } - strcpy(host, optarg); - break; - - /* case nb: */ - case 2: - blocking = 0; - break; - - /* case pos: */ - case 3: - i_tmp = atoi(optarg); - if (i_tmp > 0) { - position = i_tmp; - } else { - printf("Invalid argument to -pos. Must be > 0.\n"); - exit(-1); - } - break; - - /* case ppos: */ - case 4: - i_tmp = atoi(optarg); - if (i_tmp > -3 && i_tmp != 0) { - pposition = i_tmp; - flowMode=ET_STATION_PARALLEL; - } else { - printf("Invalid argument to -ppos. Must be > -3 and != 0.\n"); - exit(-1); - } - break; - - /* case rb */ - case 5: - i_tmp = atoi(optarg); - if (i_tmp < 1) { - printf("Invalid argument to -rb. Recv buffer size must be > 0.\n"); - exit(-1); - } - recvBufSize = i_tmp; - break; - - /* case sb */ - case 6: - i_tmp = atoi(optarg); - if (i_tmp < 1) { - printf("Invalid argument to -sb. Send buffer size must be > 0.\n"); - exit(-1); - } - sendBufSize = i_tmp; - break; - - /* case nd */ - case 7: - noDelay = 1; - break; - - /* case dump */ - case 8: - dump = 1; - break; - - /* case read */ - case 9: - readData = 1; - break; - - case 'v': - verbose = 1; - debugLevel = ET_DEBUG_INFO; - break; - - case 'r': - remote = 1; - break; - - case 'm': - multicast = 1; - break; - - case 'b': - broadcast = 1; - break; - - case ':': - case 'h': - case '?': - default: - errflg++; - } - } - - if (!multicast && !broadcast) { - /* Default to local host if direct connection */ - if (strlen(host) < 1) { - strcpy(host, ET_HOST_LOCAL); - } - } - - if (optind < argc || errflg || strlen(et_name) < 1) { - fprintf(stderr, - "\nusage: %s %s\n%s\n%s\n%s\n%s\n%s\n%s\n\n", - argv[0], "-f <ET name> -s <station name>", - " [-h] [-v] [-nb] [-r] [-m] [-b] [-nd] [-read] [-dump]", - " [-host <ET host>] [-p <ET port>]", - " [-c <chunk size>] [-q <Q size>]", - " [-pos <station pos>] [-ppos <parallel station pos>]", - " [-i <interface address>] [-a <mcast addr>]", - " [-rb <buf size>] [-sb <buf size>]"); - - fprintf(stderr, " -f ET system's (memory-mapped file) name\n"); - fprintf(stderr, " -host ET system's host if direct connection (default to local)\n"); - fprintf(stderr, " -s create station of this name\n"); - fprintf(stderr, " -h help\n\n"); - - fprintf(stderr, " -v verbose output (also prints data if reading with -read)\n"); - fprintf(stderr, " -read read data (1 int for each event)\n"); - fprintf(stderr, " -dump dump events back into ET (go directly to GC) instead of put\n"); - fprintf(stderr, " -c number of events in one get/put array\n"); - fprintf(stderr, " -r act as remote (TCP) client even if ET system is local\n"); - fprintf(stderr, " -p port, TCP if direct, else UDP\n\n"); - - fprintf(stderr, " -nb make station non-blocking\n"); - fprintf(stderr, " -q queue size if creating non-blocking station\n"); - fprintf(stderr, " -pos position of station (1,2,...)\n"); - fprintf(stderr, " -ppos position of within a group of parallel stations (-1=end, -2=head)\n\n"); - - fprintf(stderr, " -i outgoing network interface address (dot-decimal)\n"); - fprintf(stderr, " -a multicast address(es) (dot-decimal), may use multiple times\n"); - fprintf(stderr, " -m multicast to find ET (use default address if -a unused)\n"); - fprintf(stderr, " -b broadcast to find ET\n\n"); - - fprintf(stderr, " -rb TCP receive buffer size (bytes)\n"); - fprintf(stderr, " -sb TCP send buffer size (bytes)\n"); - fprintf(stderr, " -nd use TCP_NODELAY option\n\n"); - - fprintf(stderr, " This consumer works by making a direct connection to the\n"); - fprintf(stderr, " ET system's server port and host unless at least one multicast address\n"); - fprintf(stderr, " is specified with -a, the -m option is used, or the -b option is used\n"); - fprintf(stderr, " in which case multi/broadcasting used to find the ET system.\n"); - fprintf(stderr, " If multi/broadcasting fails, look locally to find the ET system.\n"); - fprintf(stderr, " This program gets all events from the given station and puts them back.\n\n"); - - exit(2); - } - - - timeout.tv_sec = 2; - timeout.tv_nsec = 0; - - /* allocate some memory */ - pe = (et_event **) calloc((size_t)chunk, sizeof(et_event *)); - if (pe == NULL) { - printf("%s: out of memory\n", argv[0]); - exit(1); - } - - /*************************/ - /* setup signal handling */ - /*************************/ - /* block all signals */ - sigfillset(&sigblock); - status = pthread_sigmask(SIG_BLOCK, &sigblock, NULL); - if (status != 0) { - printf("%s: pthread_sigmask failure\n", argv[0]); - exit(1); - } - - /* spawn signal handling thread */ - pthread_create(&tid, NULL, signal_thread, (void *)NULL); - - - /******************/ - /* open ET system */ - /******************/ - et_open_config_init(&openconfig); - - if (broadcast && multicast) { - broadAndMulticast = 1; - } - - /* if multicasting to find ET */ - if (multicast) { - if (mcastAddrCount < 1) { - /* Use default mcast address if not given on command line */ - status = et_open_config_addmulticast(openconfig, ET_MULTICAST_ADDR); - } - else { - /* add multicast addresses to use */ - for (j = 0; j < mcastAddrCount; j++) { - if (strlen(mcastAddr[j]) > 7) { - status = et_open_config_addmulticast(openconfig, mcastAddr[j]); - if (status != ET_OK) { - printf("%s: bad multicast address argument\n", argv[0]); - exit(1); - } - printf("%s: adding multicast address %s\n", argv[0], mcastAddr[j]); - } - } - } - } - - if (broadAndMulticast) { - printf("Broad and Multicasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_BROADANDMULTICAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else if (multicast) { - printf("Multicasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_MULTICAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else if (broadcast) { - printf("Broadcasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_BROADCAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else { - if (port == 0) { - port = ET_SERVER_PORT; - } - et_open_config_setserverport(openconfig, port); - et_open_config_setcast(openconfig, ET_DIRECT); - if (strlen(host) > 0) { - et_open_config_sethost(openconfig, host); - } - et_open_config_gethost(openconfig, host); - printf("Direct connection to %s\n", host); - } - - /* Defaults are to use operating system default buffer sizes and turn off TCP_NODELAY */ - et_open_config_settcp(openconfig, recvBufSize, sendBufSize, noDelay); - if (strlen(interface) > 6) { - et_open_config_setinterface(openconfig, interface); - } - - if (remote) { - printf("Set as remote\n"); - et_open_config_setmode(openconfig, ET_HOST_AS_REMOTE); - } - - /* If responses from different ET systems, return error. */ - et_open_config_setpolicy(openconfig, ET_POLICY_ERROR); - - /* debug level */ - et_open_config_setdebugdefault(openconfig, debugLevel); - - et_open_config_setwait(openconfig, ET_OPEN_WAIT); - if (et_open(&id, et_name, openconfig) != ET_OK) { - printf("%s: et_open problems\n", argv[0]); - exit(1); - } - et_open_config_destroy(openconfig); - - /*-------------------------------------------------------*/ - - /* Find out if we have a remote connection to the ET system */ - et_system_getlocality(id, &locality); - if (locality == ET_REMOTE) { - printf("ET is remote\n\n"); - - et_system_gethost(id, host); - et_system_getlocaladdress(id, localAddr); - printf("Connect to ET, from ip = %s to %s\n", localAddr, host); - } - else { - printf("ET is local\n\n"); - } - - /* set level of debug output (everything) */ - et_system_setdebug(id, debugLevel); - - /* define station to create */ - et_station_config_init(&sconfig); - et_station_config_setflow(sconfig, flowMode); - if (!blocking) { - et_station_config_setblock(sconfig, ET_STATION_NONBLOCKING); - if (qSize > 0) { - et_station_config_setcue(sconfig, qSize); - } - } - - if ((status = et_station_create_at(id, &my_stat, stationName, sconfig, position, pposition)) != ET_OK) { - if (status == ET_ERROR_EXISTS) { - /* my_stat contains pointer to existing station */ - printf("%s: station already exists\n", argv[0]); - } - else if (status == ET_ERROR_TOOMANY) { - printf("%s: too many stations created\n", argv[0]); - goto error; - } - else { - printf("%s: error in station creation\n", argv[0]); - goto error; - } - } - et_station_config_destroy(sconfig); - - if (et_station_attach(id, my_stat, &attach1) != ET_OK) { - printf("%s: error in station attach\n", argv[0]); - goto error; - } - - - /* read time for future statistics calculations */ -#if defined __APPLE__ - gettimeofday(&t1, NULL); - time1 = 1000L*t1.tv_sec + t1.tv_usec/1000L; /* milliseconds */ -#else - clock_gettime(CLOCK_REALTIME, &t1); - time1 = 1000L*t1.tv_sec + t1.tv_nsec/1000000L; /* milliseconds */ -#endif - - - while (1) { - - /**************/ - /* get events */ - /**************/ - - /* example of single, timeout read */ - //status = et_events_get(id, attach1, pe, ET_TIMED | ET_MODIFY, &timeout, chunk, &numRead); - - /* example of reading array of up to "chunk" events */ - status = et_events_get(id, attach1, pe, ET_SLEEP, NULL, chunk, &numRead); - if (status == ET_OK) { - ; - } - else if (status == ET_ERROR_DEAD) { - printf("%s: ET system is dead\n", argv[0]); - goto error; - } - else if (status == ET_ERROR_TIMEOUT) { - printf("%s: got timeout\n", argv[0]); - goto end; - } - else if (status == ET_ERROR_EMPTY) { - printf("%s: no events\n", argv[0]); - goto end; - } - else if (status == ET_ERROR_BUSY) { - printf("%s: station is busy\n", argv[0]); - goto end; - } - else if (status == ET_ERROR_WAKEUP) { - printf("%s: someone told me to wake up\n", argv[0]); - goto error; - } - else if ((status == ET_ERROR_WRITE) || (status == ET_ERROR_READ)) { - printf("%s: socket communication error\n", argv[0]); - goto error; - } - else { - printf("%s: get error, status = %d\n", argv[0], status); - goto error; - } - - /*******************/ - /* read/print data */ - /*******************/ - if (readData) { - size_t len; - int *data, endian, swap; - - for (j = 0; j < numRead; j++) { - et_event_getdata(pe[j], (void **) &data); - et_event_getlength(pe[j], &len); - et_event_getendian(pe[j], &endian); - et_event_needtoswap(pe[j], &swap); - - bytes += len; - totalBytes += len; - - if (verbose) { - printf("data byte order = %s\n", (endian == ET_ENDIAN_BIG ? "BIG" : "LITTLE")); - if (swap) { - printf(" data (len = %d) needs swapping, swapped int = %d\n", (int) len, ET_SWAP32(data[0])); - } - else { - printf(" data (len = %d) does NOT need swapping, int = %d\n", (int) len, data[0]); - } - - et_event_getcontrol(pe[j], con); - printf("control array = {"); - for (i = 0; i < ET_STATION_SELECT_INTS; i++) { - printf("%d ", con[i]); - } - printf("}\n"); - } - } - } - else { - size_t len; - for (j = 0; j < numRead; j++) { - et_event_getlength(pe[j], &len); - /* include ET overhead by adding commented out portions */ - bytes += len /* +52 */; - totalBytes += len /* +52 */; - } - /* - bytes += 20; - totalBytes += 20; - */ - } - - /*******************/ - /* put/dump events */ - /*******************/ - - if (!dump) { - /* putting array of events */ - status = et_events_put(id, attach1, pe, numRead); - } - else { - /* dumping array of events */ - status = et_events_dump(id, attach1, pe, numRead); - } - - if (status == ET_ERROR_DEAD) { - printf("%s: ET is dead\n", argv[0]); - goto error; - } - else if ((status == ET_ERROR_WRITE) || (status == ET_ERROR_READ)) { - printf("%s: socket communication error\n", argv[0]); - goto error; - } - else if (status != ET_OK) { - printf("%s: put error\n", argv[0]); - goto error; - } - - count += numRead; - - end: - - /* statistics */ -#if defined __APPLE__ - gettimeofday(&t2, NULL); - time2 = 1000L*t2.tv_sec + t2.tv_usec/1000L; /* milliseconds */ -#else - clock_gettime(CLOCK_REALTIME, &t2); - time2 = 1000L*t2.tv_sec + t2.tv_nsec/1000000L; /* milliseconds */ -#endif - time = time2 - time1; - if (time > 5000) { - /* reset things if necessary */ - if ( (totalCount >= (LONG_MAX - count)) || - (totalT >= (LONG_MAX - time)) ) { - bytes = totalBytes = totalT = totalCount = count = 0; - time1 = time2; - continue; - } - - rate = 1000.0 * ((double) count) / time; - totalCount += count; - totalT += time; - avgRate = 1000.0 * ((double) totalCount) / totalT; - - /* Event rates */ - printf("%s Events: %3.4g Hz, %3.4g Avg.\n", argv[0], rate, avgRate); - - /* Data rates */ - rate = ((double) bytes) / time; - avgRate = ((double) totalBytes) / totalT; - printf("%s Data: %3.4g kB/s, %3.4g Avg.\n\n", argv[0], rate, avgRate); - - bytes = count = 0; - -#if defined __APPLE__ - gettimeofday(&t1, NULL); - time1 = 1000L*t1.tv_sec + t1.tv_usec/1000L; -#else - clock_gettime(CLOCK_REALTIME, &t1); - time1 = 1000L*t1.tv_sec + t1.tv_nsec/1000000L; -#endif - } - - } /* while(1) */ - - error: - printf("%s: ERROR\n", argv[0]); - return 0; -} - - - -/************************************************************/ -/* separate thread to handle signals */ -static void *signal_thread (void *arg) { - - sigset_t signal_set; - int sig_number; - - sigemptyset(&signal_set); - sigaddset(&signal_set, SIGINT); - - /* Wait for Control-C */ - sigwait(&signal_set, &sig_number); - - printf("Got control-C, exiting\n"); - exit(1); -} diff --git a/tools/et_feeder.cpp b/tools/et_feeder.cpp deleted file mode 100644 index 9f39b3a24d720d568463657858370f521a27f55a..0000000000000000000000000000000000000000 --- a/tools/et_feeder.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "ConfigOption.h" -#include "PRadETChannel.h" -#include "et.h" -#include "evio/evioUtil.hxx" -#include "evio/evioFileChannel.hxx" -#include <csignal> -#include <thread> -#include <chrono> -#include <iostream> - -#define PROGRESS_COUNT 100 - -using namespace std::chrono; - - -volatile std::sig_atomic_t gSignalStatus; - - -void signal_handler(int signal) { - gSignalStatus = signal; -} - - -int main(int argc, char* argv[]) try -{ - // setup input arguments - ConfigOption conf_opt; - conf_opt.AddLongOpt(ConfigOption::help_message, "help"); - conf_opt.AddOpt(ConfigOption::arg_require, 'h'); - conf_opt.AddOpt(ConfigOption::arg_require, 'p'); - conf_opt.AddOpt(ConfigOption::arg_require, 'f'); - conf_opt.AddOpt(ConfigOption::arg_require, 'i'); - - conf_opt.SetDesc("usage: %0 <data_file>"); - conf_opt.SetDesc('h', "host address of the ET system, default \"localhost\"."); - conf_opt.SetDesc('p', "port to connect, default 11111."); - conf_opt.SetDesc('f', "memory mapped et file, default \"/tmp/et_feeder\"."); - conf_opt.SetDesc('i', "interval in milliseconds to write data, default \"10\""); - - if (!conf_opt.ParseArgs(argc, argv) || conf_opt.NbofArgs() != 1) { - std::cout << conf_opt.GetInstruction() << std::endl; - return -1; - } - - std::string host = "localhost"; - int port = 11111; - std::string etf = "/tmp/et_feeder"; - int interval = 10; - - for (auto &opt : conf_opt.GetOptions()) { - switch (opt.mark) { - case 'h': - host = opt.var.String(); - break; - case 'c': - port = opt.var.Int(); - break; - case 'f': - etf = opt.var.String(); - break; - case 'i': - interval = opt.var.Int(); - break; - default : - std::cout << conf_opt.GetInstruction() << std::endl; - return -1; - } - } - - // attach to ET system - auto ch = new PRadETChannel(); - ch->Open(host.c_str(), port, etf.c_str()); - ch->NewStation("Data Feeder", 1); - ch->AttachStation(); - - // evio file reader - evio::evioFileChannel *chan = new evio::evioFileChannel(conf_opt.GetArgument(0).c_str(), "r"); - chan->open(); - - // install signal handler - std::signal(SIGINT, signal_handler); - int count = 0; - while (chan->read()) { - if (gSignalStatus == SIGINT) { - std::cout << "Received control-C, exiting..." << std::endl; - ch->ForceClose(); - break; - } - system_clock::time_point start(system_clock::now()); - system_clock::time_point next(start + std::chrono::milliseconds(interval)); - - if (++count % PROGRESS_COUNT == 0) { - std::cout << "Read and feed " << count << " events to ET, rate is 1 event per " - << interval << " ms.\r" << std::flush; - } - ch->Write((void*) chan->getBuffer(), chan->getBufSize() * sizeof(uint32_t)); - - std::this_thread::sleep_until(next); - } - std::cout << "Read and feed " << count << " events to ET, rate is 1 event per " - << interval << " ms." << std::endl; - - chan->close(); - return 0; - -} catch (PRadException e) { - std::cerr << e.FailureType() << ": " << e.FailureDesc() << std::endl; - return -1; -} catch (evio::evioException e) { - std::cerr << e.toString() << std::endl; -} catch (...) { - std::cerr << "?unknown exception" << std::endl; -} - diff --git a/tools/et_producer.cpp b/tools/et_producer.cpp deleted file mode 100644 index 6d095f41d50d4e22ceddcc0d471db1dc98d92a3e..0000000000000000000000000000000000000000 --- a/tools/et_producer.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/*----------------------------------------------------------------------------* - * Copyright (c) 1998 Southeastern Universities Research Association, * - * Thomas Jefferson National Accelerator Facility * - * * - * This software was developed under a United States Government license * - * described in the NOTICE file included as part of this distribution. * - * * - * Author: Carl Timmer * - * timmer@jlab.org Jefferson Lab, MS-12H * - * Phone: (757) 269-5130 12000 Jefferson Ave. * - * Fax: (757) 269-5800 Newport News, VA 23606 * - * * - *----------------------------------------------------------------------------* - * - * Description: - * ET system sample event producer - * - *----------------------------------------------------------------------------*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <sys/types.h> -#include <unistd.h> -#include <limits.h> -#include <getopt.h> -#include <time.h> -#include <sys/time.h> -#include <math.h> - -#include "et.h" - -/* prototype */ -static void * signal_thread (void *arg); - -int main(int argc,char **argv) { - - int i, j, c, i_tmp, status, junkData, numRead, locality; - int startingVal=0, errflg=0, group=1, chunk=1, size=32, writeData=0, localEndian=1; - int delay=0, remote=0, multicast=0, broadcast=0, broadAndMulticast=0; - int sendBufSize=0, recvBufSize=0, noDelay=0, blast=0, noAllocFlag=0; - int debugLevel = ET_DEBUG_ERROR; - unsigned short port=0; - char et_name[ET_FILENAME_LENGTH], host[256], interface[16], localAddr[16]; - void *fakeData; - - int mcastAddrCount = 0, mcastAddrMax = 10; - char mcastAddr[mcastAddrMax][16]; - - et_att_id attach1; - et_sys_id id; - et_openconfig openconfig; - et_event **pe; - struct timespec timeout; -#if defined __APPLE__ - struct timeval t1, t2; -#else - struct timespec t1, t2; -#endif - sigset_t sigblock; - pthread_t tid; - - /* statistics variables */ - double rate = 0.0, avgRate = 0.0; - int64_t count = 0, totalCount = 0, totalT = 0, time, time1, time2; - - /* control int array for event header if writing junk data */ - int control[] = {17, 8, -1, -1, 0, 0}; - - /* 4 multiple character command-line options */ - static struct option long_options[] = - {{"host", 1, NULL, 1}, - {"rb", 1, NULL, 2}, - {"sb", 1, NULL, 3}, - {"nd", 0, NULL, 4}, - {"blast", 0, NULL, 5}, - {0, 0, 0, 0} - }; - - memset(host, 0, 256); - memset(interface, 0, 16); - memset(mcastAddr, 0, mcastAddrMax*16); - memset(et_name, 0, ET_FILENAME_LENGTH); - - while ((c = getopt_long_only(argc, argv, "vbmhrn:a:s:p:d:f:c:g:i:w:", long_options, 0)) != EOF) { - - if (c == -1) - break; - - switch (c) { - case 'c': - i_tmp = atoi(optarg); - if (i_tmp > 0 && i_tmp < 1001) { - chunk = i_tmp; - printf("Setting chunk to %d\n", chunk); - } else { - printf("Invalid argument to -c. Must < 1001 & > 0.\n"); - exit(-1); - } - break; - - case 's': - i_tmp = atoi(optarg); - if (i_tmp > -1) { - size = i_tmp; - } else { - printf("Invalid argument to -s. Must be a positive integer.\n"); - exit(-1); - } - break; - - case 'w': - writeData = 1; - i_tmp = atoi(optarg); - if (i_tmp != 1) { - localEndian = 0; - } - break; - - case 'd': - delay = atoi(optarg); - if (delay < 0) { - printf("Delay must be >= 0\n"); - exit(-1); - } - break; - - case 'p': - i_tmp = atoi(optarg); - if (i_tmp > 1023 && i_tmp < 65535) { - port = i_tmp; - } else { - printf("Invalid argument to -p. Must be < 65535 & > 1023.\n"); - exit(-1); - } - break; - - case 'g': - i_tmp = atoi(optarg); - if (i_tmp > 0 && i_tmp < 501) { - group = i_tmp; - } else { - printf("Invalid argument to -g. Must be 501 > g > 0.\n"); - exit(-1); - } - break; - - case 'f': - if (strlen(optarg) >= ET_FILENAME_LENGTH) { - fprintf(stderr, "ET file name is too long\n"); - exit(-1); - } - strcpy(et_name, optarg); - break; - - case 'i': - if (strlen(optarg) > 15 || strlen(optarg) < 7) { - fprintf(stderr, "interface address is bad\n"); - exit(-1); - } - strcpy(interface, optarg); - break; - - case 'a': - if (strlen(optarg) >= 16) { - fprintf(stderr, "Multicast address is too long\n"); - exit(-1); - } - if (mcastAddrCount >= mcastAddrMax) break; - strcpy(mcastAddr[mcastAddrCount++], optarg); - multicast = 1; - break; - - case 1: - if (strlen(optarg) >= 255) { - fprintf(stderr, "host name is too long\n"); - exit(-1); - } - strcpy(host, optarg); - break; - - /* case rb */ - case 2: - i_tmp = atoi(optarg); - if (i_tmp < 1) { - printf("Invalid argument to -rb. Recv buffer size must be > 0.\n"); - exit(-1); - } - recvBufSize = i_tmp; - break; - - /* case sb */ - case 3: - i_tmp = atoi(optarg); - if (i_tmp < 1) { - printf("Invalid argument to -sb. Send buffer size must be > 0.\n"); - exit(-1); - } - sendBufSize = i_tmp; - break; - - /* case nd */ - case 4: - noDelay = 1; - break; - - /* case blast */ - case 5: - blast = 1; - break; - - case 'v': - debugLevel = ET_DEBUG_INFO; - break; - - case 'r': - remote = 1; - break; - - case 'm': - multicast = 1; - break; - - case 'b': - broadcast = 1; - break; - - case ':': - case 'h': - case '?': - default: - errflg++; - } - } - - if (!multicast && !broadcast) { - /* Default to local host if direct connection */ - if (strlen(host) < 1) { - strcpy(host, ET_HOST_LOCAL); - } - } - - if (optind < argc || errflg || strlen(et_name) < 1) { - fprintf(stderr, - "\nusage: %s %s\n%s\n%s\n%s\n%s\n%s\n%s\n\n", - argv[0], "-f <ET name>", - " [-h] [-v] [-r] [-m] [-b] [-nd] [-blast]", - " [-host <ET host>] [-w <local endian? 0/1>]", - " [-s <event size>] [-c <chunk size>] [-g <group>]", - " [-d <delay>] [-p <ET port>]", - " [-i <interface address>] [-a <mcast addr>]", - " [-rb <buf size>] [-sb <buf size>]"); - - - fprintf(stderr, " -f ET system's (memory-mapped file) name\n"); - fprintf(stderr, " -host ET system's host if direct connection (default to local)\n"); - fprintf(stderr, " -h help\n"); - fprintf(stderr, " -v verbose output\n\n"); - - fprintf(stderr, " -s event size in bytes\n"); - fprintf(stderr, " -c number of events in one get/put array\n"); - fprintf(stderr, " -g group from which to get new events (1,2,...)\n"); - fprintf(stderr, " -d delay in millisec between each round of getting and putting events\n\n"); - - fprintf(stderr, " -p ET port (TCP for direct, UDP for broad/multicast)\n"); - fprintf(stderr, " -r act as remote (TCP) client even if ET system is local\n"); - fprintf(stderr, " -w write data (1 sequential int per event), 1 local endian, 0 else\n"); - fprintf(stderr, " -blast if remote, use external data buf (no mem allocation),\n"); - fprintf(stderr, " do not write data (overrides -w)\n\n"); - - fprintf(stderr, " -i outgoing network interface address (dot-decimal)\n"); - fprintf(stderr, " -a multicast address(es) (dot-decimal), may use multiple times\n"); - fprintf(stderr, " -m multicast to find ET (use default address if -a unused)\n"); - fprintf(stderr, " -b broadcast to find ET\n\n"); - - fprintf(stderr, " -rb TCP receive buffer size (bytes)\n"); - fprintf(stderr, " -sb TCP send buffer size (bytes)\n"); - fprintf(stderr, " -nd use TCP_NODELAY option\n\n"); - - fprintf(stderr, " This producer works by making a direct connection to the\n"); - fprintf(stderr, " ET system's server port and host unless at least one multicast address\n"); - fprintf(stderr, " is specified with -a, the -m option is used, or the -b option is used\n"); - fprintf(stderr, " in which case multi/broadcasting used to find the ET system.\n"); - fprintf(stderr, " If multi/broadcasting fails, look locally to find the ET system.\n"); - fprintf(stderr, " This program gets new events from the system and puts them back.\n\n"); - exit(2); - } - - /* fake data for blasting */ - fakeData = (void *) malloc(size); - if (fakeData == NULL) { - printf("%s: out of memory\n", argv[0]); - exit(1); - } - - /* delay is in milliseconds */ - if (delay > 0) { - timeout.tv_sec = delay / 1000; - timeout.tv_nsec = (delay - (delay / 1000) * 1000) * 1000000; - } - - /* allocate some memory */ - pe = (et_event **) calloc(chunk, sizeof(et_event *)); - if (pe == NULL) { - printf("%s: out of memory\n", argv[0]); - exit(1); - } - - /*************************/ - /* setup signal handling */ - /*************************/ - /* block all signals */ - sigfillset(&sigblock); - status = pthread_sigmask(SIG_BLOCK, &sigblock, NULL); - if (status != 0) { - printf("%s: pthread_sigmask failure\n", argv[0]); - exit(1); - } - - /* spawn signal handling thread */ - pthread_create(&tid, NULL, signal_thread, (void *) NULL); - - /******************/ - /* open ET system */ - /******************/ - et_open_config_init(&openconfig); - - if (broadcast && multicast) { - broadAndMulticast = 1; - } - - /* if multicasting to find ET */ - if (multicast) { - if (mcastAddrCount < 1) { - /* Use default mcast address if not given on command line */ - status = et_open_config_addmulticast(openconfig, ET_MULTICAST_ADDR); - } - else { - /* add multicast addresses to use */ - for (j = 0; j < mcastAddrCount; j++) { - if (strlen(mcastAddr[j]) > 7) { - status = et_open_config_addmulticast(openconfig, mcastAddr[j]); - if (status != ET_OK) { - printf("%s: bad multicast address argument\n", argv[0]); - exit(1); - } - printf("%s: adding multicast address %s\n", argv[0], mcastAddr[j]); - } - } - } - } - - if (broadAndMulticast) { - printf("Broad and Multicasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_BROADANDMULTICAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else if (multicast) { - printf("Multicasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_MULTICAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else if (broadcast) { - printf("Broadcasting\n"); - if (port == 0) { - port = ET_UDP_PORT; - } - et_open_config_setport(openconfig, port); - et_open_config_setcast(openconfig, ET_BROADCAST); - et_open_config_sethost(openconfig, ET_HOST_ANYWHERE); - } - else { - if (port == 0) { - port = ET_SERVER_PORT; - } - et_open_config_setserverport(openconfig, port); - et_open_config_setcast(openconfig, ET_DIRECT); - if (strlen(host) > 0) { - et_open_config_sethost(openconfig, host); - } - et_open_config_gethost(openconfig, host); - printf("Direct connection to %s\n", host); - } - /*et_open_config_sethost(openconfig, ET_HOST_REMOTE);*/ - - /* Defaults are to use operating system default buffer sizes and turn off TCP_NODELAY */ - et_open_config_settcp(openconfig, recvBufSize, sendBufSize, noDelay); - if (strlen(interface) > 6) { - et_open_config_setinterface(openconfig, interface); - } - - if (remote) { - printf("Set as remote\n"); - et_open_config_setmode(openconfig, ET_HOST_AS_REMOTE); - } - - /* If responses from different ET systems, return error. */ - et_open_config_setpolicy(openconfig, ET_POLICY_ERROR); - - /* debug level */ - et_open_config_setdebugdefault(openconfig, debugLevel); - - et_open_config_setwait(openconfig, ET_OPEN_WAIT); - if (et_open(&id, et_name, openconfig) != ET_OK) { - printf("%s: et_open problems\n", argv[0]); - exit(1); - } - et_open_config_destroy(openconfig); - - /*-------------------------------------------------------*/ - - /* Make things self-consistent by not taking time to write data if blasting. - * Blasting flag takes precedence. */ - if (blast) { - writeData = 0; - } - - /* Find out if we have a remote connection to the ET system - * so we know if we can use external data buffer for events - * for blasting - which is quite a bit faster. */ - et_system_getlocality(id, &locality); - if (locality == ET_REMOTE) { - if (blast) { - noAllocFlag = ET_NOALLOC; - } - printf("ET is remote\n\n"); - - et_system_gethost(id, host); - et_system_getlocaladdress(id, localAddr); - printf("Connect to ET, from ip = %s to %s\n", localAddr, host); - } - else { - /* local blasting is just the same as local producing */ - blast = 0; - printf("ET is local\n\n"); - } - - /* set level of debug output (everything) */ - et_system_setdebug(id, debugLevel); - - /* attach to grandcentral station */ - if (et_station_attach(id, ET_GRANDCENTRAL, &attach1) < 0) { - printf("%s: error in et_station_attach\n", argv[0]); - exit(1); - } - - /* read time for future statistics calculations */ -#if defined __APPLE__ - gettimeofday(&t1, NULL); - time1 = 1000L*t1.tv_sec + t1.tv_usec/1000L; /* milliseconds */ -#else - clock_gettime(CLOCK_REALTIME, &t1); - time1 = 1000L*t1.tv_sec + t1.tv_nsec/1000000L; /* milliseconds */ -#endif - - - while (1) { - - status = et_events_new_group(id, attach1, pe, ET_SLEEP | noAllocFlag, - NULL, size, chunk, group, &numRead); - - if (status == ET_OK) { - ; - } - else if (status == ET_ERROR_DEAD) { - printf("%s: ET system is dead\n", argv[0]); - break; - } - else if (status == ET_ERROR_TIMEOUT) { - printf("%s: got timeout\n", argv[0]); - break; - } - else if (status == ET_ERROR_EMPTY) { - printf("%s: no events\n", argv[0]); - break; - } - else if (status == ET_ERROR_BUSY) { - printf("%s: grandcentral is busy\n", argv[0]); - break; - } - else if (status == ET_ERROR_WAKEUP) { - printf("%s: someone told me to wake up\n", argv[0]); - break; - } - else if ((status == ET_ERROR_WRITE) || (status == ET_ERROR_READ)) { - printf("%s: socket communication error\n", argv[0]); - goto error; - } - else { - printf("%s: request error\n", argv[0]); - goto error; - } - - /* if blasting data (and remote), don't write anything, just use what's in buffer when allocated */ - if (blast) { - for (i=0; i < numRead; i++) { - et_event_setlength(pe[i], size); - et_event_setdatabuffer(id, pe[i], fakeData); - } - } - /* write data, set control values here */ - else if (writeData) { - char *pdata; - for (i=0; i < numRead; i++) { - junkData = i + startingVal; - if (!localEndian) { - junkData = ET_SWAP32(junkData); - et_event_setendian(pe[i], ET_ENDIAN_NOTLOCAL); - } - et_event_getdata(pe[i], (void **) &pdata); - memcpy((void *)pdata, (const void *) &junkData, sizeof(int)); - - /* Send all data even though we only wrote one int. */ - et_event_setlength(pe[i], size); - et_event_setcontrol(pe[i], control, sizeof(control)/sizeof(int)); - } - startingVal += numRead; - } - else { - for (i = 0; i < numRead; i++) { - et_event_setlength(pe[i], size); - } - } - - /* put events back into the ET system */ - status = et_events_put(id, attach1, pe, numRead); - if (status == ET_OK) { - ; - } - else if (status == ET_ERROR_DEAD) { - printf("%s: ET is dead\n", argv[0]); - break; - } - else if ((status == ET_ERROR_WRITE) || (status == ET_ERROR_READ)) { - printf("%s: socket communication error\n", argv[0]); - goto error; - } - else { - printf("%s: put error, status = %d\n", argv[0], status); - goto error; - } - - count += numRead; - - if (delay > 0) { - nanosleep(&timeout, NULL); - } - - /* statistics */ -#if defined __APPLE__ - gettimeofday(&t2, NULL); - time2 = 1000L*t2.tv_sec + t2.tv_usec/1000L; /* milliseconds */ -#else - clock_gettime(CLOCK_REALTIME, &t2); - time2 = 1000L*t2.tv_sec + t2.tv_nsec/1000000L; /* milliseconds */ -#endif - time = time2 - time1; - if (time > 5000) { - /* reset things if necessary */ - if ( (totalCount >= (LONG_MAX - count)) || - (totalT >= (LONG_MAX - time)) ) { - totalT = totalCount = count = 0; - time1 = time2; - continue; - } - rate = 1000.0 * ((double) count) / time; - totalCount += count; - totalT += time; - avgRate = 1000.0 * ((double) totalCount) / totalT; - - /* Event rates */ - printf("%s Events: %3.4g Hz, %3.4g Avg.\n", argv[0], rate, avgRate); - - /* Data rates */ - rate = ((double) count) * size / time; - avgRate = ((double) totalCount) * size / totalT; - printf("%s Data: %3.4g kB/s, %3.4g Avg.\n\n", argv[0], rate, avgRate); - - /* If including msg overhead in data rates, need to do the following - avgRate = 1000.0 * (((double) totalCount) * (size + 52) + 20)/ totalT; */ - - count = 0; - -#if defined __APPLE__ - gettimeofday(&t1, NULL); - time1 = 1000L*t1.tv_sec + t1.tv_usec/1000L; -#else - clock_gettime(CLOCK_REALTIME, &t1); - time1 = 1000L*t1.tv_sec + t1.tv_nsec/1000000L; -#endif - } - - } /* while(1) */ - - - error: - - printf("%s: ERROR\n", argv[0]); - exit(0); -} - -/************************************************************/ -/* separate thread to handle signals */ -static void * signal_thread (void *arg) { - - sigset_t signal_set; - int sig_number; - - sigemptyset(&signal_set); - sigaddset(&signal_set, SIGINT); - - /* Not necessary to clean up as ET system will do it */ - sigwait(&signal_set, &sig_number); - printf("Got control-C, exiting\n"); - exit(1); -}