diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4e7bb5d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,101 @@ +cmake_minimum_required(VERSION 3.18) +project(fncs) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +if(WIN32) + set(CMAKE_CXX_FLAGS "/EHsc /O2 -D_WINDOWS -D_WIN32 -DLIBFNCS_EXPORTS") + set(HAVE_WINDOWS_H ON) + find_library(LIBZMQ_LIBRARY NAMES libzmq-v142-mt-4_3_4) +endif() +if(UNIX) + set(CMAKE_CXX_FLAGS "-w -O2 -std=c++14 -fPIC") + set(HAVE_UNISTD_H ON) + find_library(LIBZMQ_LIBRARY NAMES zmq) +endif() + if(APPLE) + set(CMAKE_CXX_FLAGS "-w -O2 -std=c++14") + set(HAVE_UNISTD_H ON) + find_library(LIBZMQ_LIBRARY NAMES zmq) +endif() + +find_library(CZMQ_LIBRARY czmq) +find_path(CZMQ_INCLUDE_DIR czmq.h) +message("cmzq.h found at " ${CZMQ_INCLUDE_DIR}) +message("cmzq library found at " ${CZMQ_LIBRARY}) +message("libmzq library found at " ${LIBZMQ_LIBRARY}) +include_directories(${CZMQ_INCLUDE_DIR}) + +configure_file(config.h.in.cmake config.h) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(contrib) +include_directories(contrib/yaml-cpp/include) + +add_library(jsoncpp STATIC + contrib/json-cpp/jsoncpp.cpp) + +add_library(yamlcpp STATIC + contrib/yaml-cpp/src/aliasmanager.cpp + contrib/yaml-cpp/src/binary.cpp + contrib/yaml-cpp/src/contrib/graphbuilderadapter.cpp + contrib/yaml-cpp/src/contrib/graphbuilder.cpp + contrib/yaml-cpp/src/conversion.cpp + contrib/yaml-cpp/src/directives.cpp + contrib/yaml-cpp/src/emitfromevents.cpp + contrib/yaml-cpp/src/emitter.cpp + contrib/yaml-cpp/src/emitterstate.cpp + contrib/yaml-cpp/src/emitterutils.cpp + contrib/yaml-cpp/src/exp.cpp + contrib/yaml-cpp/src/iterator.cpp + contrib/yaml-cpp/src/nodebuilder.cpp + contrib/yaml-cpp/src/node.cpp + contrib/yaml-cpp/src/nodeownership.cpp + contrib/yaml-cpp/src/null.cpp + contrib/yaml-cpp/src/ostream.cpp + contrib/yaml-cpp/src/parser.cpp + contrib/yaml-cpp/src/regex.cpp + contrib/yaml-cpp/src/scanner.cpp + contrib/yaml-cpp/src/scanscalar.cpp + contrib/yaml-cpp/src/scantag.cpp + contrib/yaml-cpp/src/scantoken.cpp + contrib/yaml-cpp/src/simplekey.cpp + contrib/yaml-cpp/src/singledocparser.cpp + contrib/yaml-cpp/src/stream.cpp + contrib/yaml-cpp/src/tag.cpp) + +add_library(fncs SHARED + src/echo.cpp + src/fncs.cpp + src/fncs_capi.cpp + src/fncs_fapi.cpp) +target_link_libraries(fncs PRIVATE + jsoncpp + yamlcpp + ${CZMQ_LIBRARY} + ${LIBZMQ_LIBRARY}) + +add_executable(fncs_broker src/broker.cpp) +target_link_libraries(fncs_broker PRIVATE + fncs + ${CZMQ_LIBRARY} + ${LIBZMQ_LIBRARY}) + +add_executable(fncs_player src/player.cpp) +target_link_libraries(fncs_player PRIVATE fncs) + +add_executable(fncs_tracer src/tracer.cpp) +target_link_libraries(fncs_tracer PRIVATE fncs) + +install(TARGETS fncs + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) +install(FILES src/fncs.h src/fncs.hpp DESTINATION include) + +install(TARGETS fncs_broker DESTINATION bin) +install(TARGETS fncs_player DESTINATION bin) +install(TARGETS fncs_tracer DESTINATION bin) + diff --git a/config.h.in.cmake b/config.h.in.cmake new file mode 100644 index 0000000..85fbe15 --- /dev/null +++ b/config.h.in.cmake @@ -0,0 +1,178 @@ +/* Define if you have the header file, 0 if you don't */ +#cmakedefine HAVE_CSTDINT + +/* set to 1 if we have the indicated package */ +#cmakedefine HAVE_CZMQ + +/* Define if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define if you have the `gettimeofday' function, 0 if you don't */ +#cmakedefine HAVE_GETTIMEOFDAY + +/* Define if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* Define if you have the `iphlpapi' library (-liphlpapi). */ +#cmakedefine HAVE_LIBIPHLPAPI + +/* Define if you have the `rpcrt4' library (-lrpcrt4). */ +#cmakedefine HAVE_LIBRPCRT4 + +/* Define if you have the `ws2_32' library (-lws2_32). */ +#cmakedefine HAVE_LIBWS2_32 + +/* Define if you have the header file. */ +#cmakedefine HAVE_MEMORY_H + +/* Define if you have the header file, 0 if you don't */ +#cmakedefine HAVE_STDINT_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define if you have the header file, 0 if you don't */ +#cmakedefine HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define if you have the header file. */ +#cmakedefine HAVE_WINDOWS_H + +/* set to 1 if we have the indicated package */ +#cmakedefine HAVE_ZMQ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#cmakedefine LT_OBJDIR + +/* Name of package */ +#cmakedefine PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#cmakedefine PACKAGE_URL + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION + +/* The size of `char', as computed by sizeof. */ +#cmakedefine SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#cmakedefine SIZEOF_INT + +/* The size of `int16_t', as computed by sizeof. */ +#cmakedefine SIZEOF_INT16_T + +/* The size of `int32_t', as computed by sizeof. */ +#cmakedefine SIZEOF_INT32_T + +/* The size of `int64_t', as computed by sizeof. */ +#cmakedefine SIZEOF_INT64_T + +/* The size of `int8_t', as computed by sizeof. */ +#cmakedefine SIZEOF_INT8_T + +/* The size of `long', as computed by sizeof. */ +#cmakedefine SIZEOF_LONG + +/* The size of `long long', as computed by sizeof. */ +#cmakedefine SIZEOF_LONG_LONG + +/* The size of `short', as computed by sizeof. */ +#cmakedefine SIZEOF_SHORT + +/* The size of `uint16_t', as computed by sizeof. */ +#cmakedefine SIZEOF_UINT16_T + +/* The size of `uint32_t', as computed by sizeof. */ +#cmakedefine SIZEOF_UINT32_T + +/* The size of `uint64_t', as computed by sizeof. */ +#cmakedefine SIZEOF_UINT64_T + +/* The size of `uint8_t', as computed by sizeof. */ +#cmakedefine SIZEOF_UINT8_T + +/* The size of `unsigned char', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_CHAR + +/* The size of `unsigned int', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_INT + +/* The size of `unsigned long', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_LONG + +/* The size of `unsigned long long', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_LONG_LONG + +/* The size of `unsigned short', as computed by sizeof. */ +#cmakedefine SIZEOF_UNSIGNED_SHORT + +/* The size of `void*', as computed by sizeof. */ +#cmakedefine SIZEOF_VOIDP + +/* Define if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS + +/* Version number of package */ +#cmakedefine VERSION + +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine int16_t + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine int64_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#cmakedefine int8_t + +/* if nullptr is not defined, attempt a substitute */ +#cmakedefine nullptr + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#cmakedefine uint8_t diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 25ed509..d5b5e3a 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -8,8 +8,8 @@ INCLUDE(UseJava) # find fncs INCLUDE(FindPackageHandleStandardArgs) -FIND_PATH(FNCS_INCLUDE_DIR fncs.hpp) -FIND_LIBRARY(FNCS_LIBRARY fncs) +FIND_PATH(FNCS_INCLUDE_DIR fncs.hpp PATHS $ENV{FNCS_INCLUDE_DIR}) +FIND_LIBRARY(FNCS_LIBRARY fncs PATHS $ENV{FNCS_LIBRARY}) FIND_PACKAGE_HANDLE_STANDARD_ARGS(FNCS DEFAULT_MSG FNCS_INCLUDE_DIR @@ -24,11 +24,18 @@ ELSE() ENDIF() # generate JNIfncs.h stub +#ADD_CUSTOM_COMMAND( +# OUTPUT fncs_JNIfncs.h +# COMMAND ${Java_JAVAH_EXECUTABLE} -verbose +# -classpath fncs.jar +# -jni fncs.JNIfncs +# MAIN_DEPENDENCY fncs.jar +#) ADD_CUSTOM_COMMAND( OUTPUT fncs_JNIfncs.h - COMMAND ${Java_JAVAH_EXECUTABLE} -verbose - -classpath fncs.jar - -jni fncs.JNIfncs + COMMAND ${Java_JAVAC_EXECUTABLE} -h ../fncs -verbose + -classpath fncs + ../fncs/JNIfncs.java MAIN_DEPENDENCY fncs.jar ) diff --git a/java/Makefile b/java/Makefile index 4e9e468..73e1bf7 100644 --- a/java/Makefile +++ b/java/Makefile @@ -40,6 +40,7 @@ clean: rm -f *.so install: + $(info $$INSTALL_PATH is [${INSTALL_PATH}]) mkdir -p $(INSTALL_PATH) cp fncs.jar $(INSTALL_PATH) cp libJNIfncs.so $(INSTALL_PATH) diff --git a/src/fncs.cpp b/src/fncs.cpp index f7d1734..ec94b2d 100644 --- a/src/fncs.cpp +++ b/src/fncs.cpp @@ -30,7 +30,9 @@ #include #endif #include +#ifdef HAVE_UNISTD_H #include +#endif /* 3rd party headers */ #include "czmq.h" @@ -1077,6 +1079,32 @@ void fncs::publish(const string &key, const string &value) } } +void fncs::cpublish(const string &key, const char *value) +{ + LDEBUG4 << "fncs::cpublish(c_str,c_str)"; + + if (!is_initialized_) { + LWARNING << "fncs is not initialized"; + return; + } + + if (keys.count(key)) { + string new_key = simulation_name + '/' + key; + if (aggregate_pub) { + pub_cache[new_key] = value; + LDEBUG4 << "cached PUBLISH '" << new_key << "'='" << value << "'"; + } + else { + zstr_sendm(client, fncs::PUBLISH); + zstr_sendm(client, new_key.c_str()); + zstr_send(client, value); + } + } + else { + LDEBUG4 << "dropped " << key; + } +} + void fncs::publish_anon(const string &key, const string &value) { diff --git a/src/fncs.h b/src/fncs.h index 6bd7c4a..132fdaa 100644 --- a/src/fncs.h +++ b/src/fncs.h @@ -70,43 +70,49 @@ extern "C" { FNCS_EXPORT size_t fncs_get_events_size(); /** Get the keys for all values that were updated during the last - * time_request. */ + * time_request. Must _fncs_free return value. */ FNCS_EXPORT const char** fncs_get_events(); /** Get one key for the given event index that as updated during the - * last time_request. */ + * last time_request. Must _fncs_free return value. */ FNCS_EXPORT const char* fncs_get_event_at(size_t index); /** Get the agent events for all values that were updated during the last - * time_request. */ + * time_request. Must _fncs_free return value. */ FNCS_EXPORT const char* fncs_agentGetEvents(); /** Get a value from the cache with the given key. - * Will hard fault if key is not found. */ + * Will hard fault if key is not found. Must _fncs_free + * return value. */ FNCS_EXPORT const char* fncs_get_value(const char *key); /** Get the number of values from the cache with the given key. */ FNCS_EXPORT size_t fncs_get_values_size(const char *key); /** Get an array of values from the cache with the given key. - * Will return an array of size 1 if only a single value exists. */ + * Will return an array of size 1 if only a single value + * exists. Must _fncs_free the return value. */ FNCS_EXPORT const char** fncs_get_values(const char *key); - /** Get a single value from the array of values for the given key. */ + /** Get a single value from the array of values for the given + * key. Must _fncs_free the return value. */ FNCS_EXPORT const char* fncs_get_value_at(const char *key, size_t index); /** Get the number of subscribed keys. */ FNCS_EXPORT size_t fncs_get_keys_size(); /** Get the subscribed keys. - * Will return NULL if fncs_get_keys_size() returns 0. */ + * Will return NULL if fncs_get_keys_size() returns 0. Must + * _fncs_free the return value. */ FNCS_EXPORT const char** fncs_get_keys(); /** Get the subscribed key at the given index. - * Will return NULL if fncs_get_keys_size() returns 0. */ + * Will return NULL if fncs_get_keys_size() returns 0. Must + * _fncs_free the return value. */ FNCS_EXPORT const char* fncs_get_key_at(size_t index); - /** Return the name of the simulator. */ + /** Return the name of the simulator. Must _fncs_free the + * return value. */ FNCS_EXPORT const char * fncs_get_name(); /** Return a unique numeric ID for the simulator. */ @@ -121,6 +127,18 @@ extern "C" { /** Convenience wrapper around libc free. */ FNCS_EXPORT void _fncs_free(void * ptr); + /** Faster version: call count first, and then + * fncs_next_event that many times. Don't _fncs_free retval + * and don't retain the references. */ + FNCS_EXPORT size_t fncs_count_events(); + FNCS_EXPORT const char *fncs_next_event(); + + /** Faster version: call count first, and then fncs_next_value + * that many times on the same key. Don't _fncs_free retval + * and don't retain the references. */ + FNCS_EXPORT size_t fncs_count_values(const char *key); + FNCS_EXPORT const char *fncs_next_value(); + #ifdef __cplusplus } #endif diff --git a/src/fncs.hpp b/src/fncs.hpp index 709bc14..093c7ed 100644 --- a/src/fncs.hpp +++ b/src/fncs.hpp @@ -58,6 +58,7 @@ namespace fncs { /** Publish value using the given key. */ FNCS_EXPORT void publish(const string &key, const string &value); + FNCS_EXPORT void cpublish(const string &key, const char *value); /** Publish value anonymously using the given key. */ FNCS_EXPORT void publish_anon(const string &key, const string &value); diff --git a/src/fncs_capi.cpp b/src/fncs_capi.cpp index 2c65530..97de17f 100644 --- a/src/fncs_capi.cpp +++ b/src/fncs_capi.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include "fncs.hpp" +#include "fncs.h" using namespace std; @@ -40,7 +40,7 @@ fncs_time fncs_time_request(fncs_time next) void fncs_publish(const char *key, const char *value) { - fncs::publish(key, value); + fncs::cpublish(key, value); } void fncs_publish_anon(const char *key, const char *value) @@ -139,6 +139,37 @@ const char** fncs_get_values(const char *key) return convert(fncs::get_values(key)); } +vector vecEvents; +vector vecValues; +int idxEvent = 0; +int idxValue = 0; + +size_t fncs_count_events() +{ + vecEvents.clear(); + vecEvents = fncs::get_events(); + idxEvent = 0; + return vecEvents.size(); +} + +const char *fncs_next_event() +{ + return vecEvents[idxEvent++].c_str(); +} + +size_t fncs_count_values(const char *key) +{ + vecValues.clear(); + vecValues = fncs::get_values(key); + idxValue = 0; + return vecValues.size(); +} + +const char *fncs_next_value() +{ + return vecValues[idxValue++].c_str(); +} + const char* fncs_get_value_at(const char *key, size_t index) { return convert(fncs::get_values(key)[index]);