Skip to content

Commit

Permalink
SILKIT-1488: Support unicode-characters in filenames and participant …
Browse files Browse the repository at this point in the history
…names (#752)
  • Loading branch information
VDanielEdwards authored and GitHub Enterprise committed Feb 6, 2024
1 parent b235091 commit 3782c14
Show file tree
Hide file tree
Showing 27 changed files with 347 additions and 160 deletions.
1 change: 1 addition & 0 deletions Demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ endif()
macro(make_silkit_demo executableName demoSourceFile)
add_executable(${executableName}
${demoSourceFile}
$<$<CXX_COMPILER_ID:MSVC>: "${CMAKE_CURRENT_SOURCE_DIR}/../demo.manifest" >
)
remove_definitions(-DEXPORT_SilKitAPI)

Expand Down
8 changes: 8 additions & 0 deletions Demos/demo.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>
23 changes: 23 additions & 0 deletions SilKit/IntegrationTests/ITest_Dashboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,29 @@ TEST_F(ITest_Dashboard, dashboard_no_simulation)
CheckTestResult(testResult, CreateExpectedTestResult({}, false));
}

TEST_F(ITest_Dashboard, dashboard_unicode_emoji_coordinated)
{
// the two participants use the car emoji (🚗) in their name, which is escaped for the dashboard
const auto participantName1 = "\xf0\x9f\x9a\x97 CanReader";
const auto expectedParticipantName1 = "%f0%9f%9a%97%20CanReader";
const auto participantName2 = "\xf0\x9f\x9a\x97 CanWriter";
const auto expectedParticipantName2 = "%f0%9f%9a%97%20CanWriter";
const auto canonicalName = "CanController1";
const auto networkName = "CAN1";
SetupFromParticipantLists({participantName1, participantName2}, {});
auto testResult = SilKit::Dashboard::RunDashboardTest(
ParticipantConfigurationFromStringImpl(_dashboardParticipantConfig), _registryUri, _dashboardUri,
[this, &participantName1, &participantName2, &canonicalName, &networkName]() {
RunCanDemo(participantName1, participantName2, canonicalName, networkName);
});
_simTestHarness->ResetRegistry();
CheckTestResult(testResult,
CreateExpectedTestResult(
{{{expectedParticipantName1, {{6, {"", "cancontroller", canonicalName, networkName, {}}}}},
{expectedParticipantName2, {{6, {"", "cancontroller", canonicalName, networkName, {}}}}}}},
true));
}

TEST_F(ITest_Dashboard, dashboard_can_coordinated)
{
const auto participantName1 = "CanReader";
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/SilKit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ DETAIL_SILKIT_DETAIL_VN_NAMESPACE_BEGIN
* Become a participant based on the the given configuration options.
*
* \param participantConfig Configuration of the participant
* \param participantName Name of the participant
* \param participantName Name of the participant (UTF-8)
* \return Instance of the communication adapter
*
* \throw SilKit::ConfigurationError if the config has errors
Expand All @@ -52,7 +52,7 @@ DETAIL_SILKIT_CPP_API auto CreateParticipant(
* Become a participant based on the the given configuration options.
*
* \param participantConfig Configuration of the participant
* \param participantName Name of the participant
* \param participantName Name of the participant (UTF-8)
* \param registryUri The URI of the registry
* \return Instance of the communication adapter
*
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/capi/Can.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ typedef void (SilKitFPTR *SilKit_CanErrorStateChangeHandler_t)(void* context, Si
/*! \brief Create a CAN controller at this SIL Kit simulation participant.
* \param outCanController Pointer that refers to the resulting CAN controller (out parameter).
* \param participant The simulation participant at which the CAN controller should be created.
* \param name The name of the new CAN controller.
* \param network The network of the CAN controller to operate in.
* \param name The name of the new CAN controller (UTF-8).
* \param network The network of the CAN controller to operate in (UTF-8).
*
* The lifetime of the resulting CAN controller is directly bound to the lifetime of the simulation participant.
* There is no further cleanup necessary except for destroying the simulation participant at the end of the
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/capi/DataPubSub.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ typedef void (SilKitFPTR *SilKit_DataMessageHandler_t)(void* context, SilKit_Dat
/*! \brief Create a DataPublisher on the provided simulation participant with the provided properties.
* \param outPublisher Pointer to which the resulting DataPublisher reference will be written.
* \param participant The simulation participant for which the DataPublisher should be created.
* \param controllerName The name of this controller.
* \param controllerName The name of this controller (UTF-8).
* \param dataSpec The specification of topic, media type and labels.
* \param history A number indicating the number of historic values that should be replayed for a new DataSubscriber.
* Restricted to {0|1}.
Expand All @@ -84,7 +84,7 @@ typedef SilKit_ReturnCode(SilKitFPTR* SilKit_DataPublisher_Create_t)(SilKit_Data
/*! \brief Create a DataSubscriber on the provided simulation participant with the provided properties.
* \param outSubscriber Pointer to which the resulting DataSubscriber reference will be written.
* \param participant The simulation participant for which the DataSubscriber should be created.
* \param controllerName The name of this controller.
* \param controllerName The name of this controller (UTF-8).
* \param dataSpec The specification of topic, media type and labels.
* \param dataHandlerContext A user provided context that is reobtained on data reception in the dataHandler.
* \param dataHandler The handler that is called on data reception. Can be overwritten by \ref SilKit_DataSubscriber_SetDataMessageHandler.
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/capi/Ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ typedef void (SilKitFPTR *SilKit_EthernetBitrateChangeHandler_t)(void* context,
*
* \param outController A pointer to a pointer in which the Ethernet controller will be stored (out parameter).
* \param participant The simulation participant for which the Ethernet controller should be created.
* \param name The utf8 encoded name of the new Ethernet controller.
* \param network The network of the Ethernet controller to operate in.
* \param name The name of the new Ethernet controller (UTF-8).
* \param network The network of the Ethernet controller to operate in (UTF-8).
* \result A return code identifying the success/failure of the call.
* ! \note The object returned must not be deallocated using free()!
*
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/capi/Lin.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,8 @@ typedef void (SilKitFPTR* SilKit_Experimental_LinFrameHeaderHandler_t)(
*
* \param outLinController Pointer into which the resulting LIN controller will be written (out parameter).
* \param participant The simulation participant at which the LIN controller should be created.
* \param name The name of the new LIN controller.
* \param network The network of the LIN controller to operate in.
* \param name The name of the new LIN controller (UTF-8).
* \param network The network of the LIN controller to operate in (UTF-8).
*
* \return \ref SilKit_ReturnCode
*/
Expand Down
2 changes: 1 addition & 1 deletion SilKit/include/silkit/capi/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef struct SilKit_Logger SilKit_Logger;
*
* \param logger The logger to use.
* \param level The log level for the message.
* \param message The message which shall be logged.
* \param message The message which shall be logged (UTF-8).
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_Logger_Log(SilKit_Logger* logger, SilKit_LoggingLevel level,
const char* message);
Expand Down
18 changes: 12 additions & 6 deletions SilKit/include/silkit/capi/Orchestration.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ typedef int8_t SilKit_OperationMode;
typedef struct
{
SilKit_StructHeader structHeader;
const char* participantName; /*!< Name of the participant. */
const char* participantName; /*!< Name of the participant (UTF-8). */
SilKit_ParticipantState participantState; /*!< The new state of the participant. */
const char* enterReason; /*!< The reason for the participant to enter the new state. */
const char* enterReason; /*!< The reason for the participant to enter the new state (UTF-8). */
SilKit_NanosecondsWallclockTime enterTime; /*!< The enter time of the participant. */
SilKit_NanosecondsWallclockTime refreshTime; /*!< The refresh time. */
} SilKit_ParticipantStatus;
Expand Down Expand Up @@ -365,7 +365,7 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_LifecycleService_WaitForLifecycleT
* report the error message in the SIL Kit system.
*
* \param lifecycleService The lifecycle service of the simulation.
* \param reason A string describing the error.
* \param reason A string describing the error (UTF-8).
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_LifecycleService_ReportError(SilKit_LifecycleService* lifecycleService,
const char* reason);
Expand All @@ -382,6 +382,9 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_LifecycleService_ReportError_t)(Si
* health monitoring related timeout occurs.
*
* Precondition: State() == \ref SilKit_ParticipantState_Running
*
* \param lifecycleService The lifecycle service of the simulation.
* \param reason A string describing the reason why the simulation was paused (UTF-8).
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_LifecycleService_Pause(SilKit_LifecycleService* lifecycleService,
const char* reason);
Expand Down Expand Up @@ -412,6 +415,9 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_LifecycleService_Continue_t)(SilKi
* cannot participate in the system simulation anymore.
*
* Precondition: State() == \ref SilKit_ParticipantState_Running
*
* \param lifecycleService The lifecycle service of the simulation.
* \param reason A string describing why the simulation was stopped (UTF-8).
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_LifecycleService_Stop(SilKit_LifecycleService* lifecycleService, const char* reason);

Expand Down Expand Up @@ -548,7 +554,7 @@ SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_SystemMonitor_Create(SilKit_System
typedef SilKit_ReturnCode(SilKitFPTR* SilKit_SystemMonitor_Create_t)(SilKit_SystemMonitor** outSystemMonitor,
SilKit_Participant* participant);

/*! \brief Get the current participant state of the participant given by participantName
/*! \brief Get the current participant state of the participant given by participantName (UTF-8)
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_SystemMonitor_GetParticipantStatus(SilKit_ParticipantStatus* outParticipantState,
SilKit_SystemMonitor* systemMonitor,
Expand Down Expand Up @@ -635,7 +641,7 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_SystemMonitor_RemoveParticipantSta
typedef struct SilKit_ParticipantConnectionInformation
{
SilKit_StructHeader structHeader;
/*! \brief Name of the remote participant. */
/*! \brief Name of the remote participant (UTF-8). */
const char* participantName;
} SilKit_ParticipantConnectionInformation;

Expand Down Expand Up @@ -680,7 +686,7 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_SystemMonitor_SetParticipantDiscon
/*! \brief Check if a participant identified by the participantName is present.
*
* @param systemMonitor The system monitor obtained via \ref SilKit_SystemMonitor_Create.
* @param participantName The name of the participant for which presence is queried.
* @param participantName The name of the participant for which presence is queried (UTF-8).
* @param out \ref SilKit_True is written to the pointee if the participant is present, otherwise \ref SilKit_False.
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_SystemMonitor_IsParticipantConnected(SilKit_SystemMonitor* systemMonitor,
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/capi/Rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ typedef void (SilKitFPTR *SilKit_RpcCallResultHandler_t)(void* context, SilKit_R
/*! \brief Create a RPC server on a simulation participant with the provided properties.
* \param outServer Pointer to which the resulting RPC server reference will be written.
* \param participant The simulation participant for which the RPC server should be created.
* \param controllerName The name of this controller.
* \param controllerName The name of this controller (UTF-8).
* \param rpcSpec A struct containing all matching related information
* \param callHandlerContext A user provided context pointer that is passed to the callHandler on call.
* \param callHandler A callback function that is triggered on invocation of the server functionality.
Expand Down Expand Up @@ -148,7 +148,7 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_RpcServer_SetCallHandler_t)(SilKit
/*! \brief Create a RPC client on a simulation participant with the provided properties.
* \param outClient Pointer to which the resulting RPC client reference will be written.
* \param participant The simulation participant for which the RPC client should be created.
* \param controllerName The name of this controller.
* \param controllerName The name of this controller (UTF-8).
* \param rpcSpec The specification of function name, media type and labels.
* \param resultHandlerContext A user provided context that is reobtained on call result in the resultHandler.
* \param resultHandler A callback that is called when a call result is received.
Expand Down
20 changes: 18 additions & 2 deletions SilKit/include/silkit/capi/SilKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ SILKIT_BEGIN_DECLS

/*! \brief Get the corresponding static error string for a given return code.
*
* \param outString The pointer through which the resulting human readable error string will be returned.
* \param outString The pointer through which the resulting human readable error string, encoded in UTF-8, will be returned.
* \param returnCode The return code for which the string should be obtained.
*
* \ref SilKit_GetLastErrorString()
Expand All @@ -67,7 +67,7 @@ typedef const char*(SilKitFPTR *SilKit_GetLastErrorString_t)();
* To destroy the participant configuration, call \ref SilKit_ParticipantConfiguration_Destroy.
*
* \param outParticipantConfiguration The pointer through which the participant configuration will be returned (out parameter).
* \param participantConfigurationString The configuration as a string (e.g., read from a configuration file or a string constant).
* \param participantConfigurationString The configuration as a UTF-8 encoded string (e.g., read from a configuration file or a string constant).
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_ParticipantConfiguration_FromString(
SilKit_ParticipantConfiguration** outParticipantConfiguration,
Expand All @@ -78,6 +78,22 @@ typedef SilKit_ReturnCode (SilKitFPTR *SilKit_ParticipantConfiguration_FromStrin
const char* participantConfigurationString);


/*! \brief Create an opaque participant configuration from the contents of the UTF-8 encoded text file.
*
* To destroy the participant configuration, call \ref SilKit_ParticipantConfiguration_Destroy.
*
* \param outParticipantConfiguration The pointer through which the participant configuration will be returned (out parameter).
* \param participantConfigurationPath The path to the configuration file as a UTF-8 encoded string.
*/
SilKitAPI SilKit_ReturnCode SilKitCALL SilKit_ParticipantConfiguration_FromFile(
SilKit_ParticipantConfiguration** outParticipantConfiguration,
const char* participantConfigurationPath);

typedef SilKit_ReturnCode (SilKitFPTR *SilKit_ParticipantConfiguration_FromFile_t)(
SilKit_ParticipantConfiguration** outParticipantConfiguration,
const char* participantConfigurationPath);


/*! \brief Destroy a participant configuration.
*
* \param participantConfiguration The participant configuration to be destroyed.
Expand Down
4 changes: 2 additions & 2 deletions SilKit/include/silkit/config/IParticipantConfiguration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace Config {
* Create a configuration data object from settings described by a
* YAML or JSON formatted string.
*
* \param text A string that adheres to our JSON schema.
* \param text A string that adheres to our JSON schema (UTF-8).
* \return The configuration data
*
* \throw SilKit::ConfigurationError The input string violates the
Expand All @@ -63,7 +63,7 @@ DETAIL_SILKIT_CPP_API auto ParticipantConfigurationFromString(const std::string&
* Create a configuration data object from settings described by a
* YAML or JSON file.
*
* \param filename Path to the YAML or JSON file.
* \param filename Path to the YAML or JSON file (UTF-8).
* \return The configuration data
*
* \throw SilKit::ConfigurationError The file could not be read, or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,15 @@ auto ParticipantConfigurationFromString(const std::string& text)
return std::make_shared<Impl::Config::ParticipantConfiguration>(participantConfiguration);
}

auto ParticipantConfigurationFromFile(const std::string& filename)
auto ParticipantConfigurationFromFile(const std::string& path)
-> std::shared_ptr<SilKit::Config::IParticipantConfiguration>
{
std::ifstream fs(filename);

if (!fs.is_open())
throw SilKit::ConfigurationError("the file could not be opened");
SilKit_ParticipantConfiguration* participantConfiguration{nullptr};

std::stringstream buffer;
buffer << fs.rdbuf();
const auto returnCode = SilKit_ParticipantConfiguration_FromFile(&participantConfiguration, path.c_str());
Impl::ThrowOnError(returnCode);

return ParticipantConfigurationFromString(buffer.str());
return std::make_shared<Impl::Config::ParticipantConfiguration>(participantConfiguration);
}

} // namespace Config
Expand Down
2 changes: 1 addition & 1 deletion SilKit/include/silkit/services/logging/ILogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ILogger
/*! \brief Log a message with a specified level
*
* \param level The log level for the message
* \param msg The message which shall be logged.
* \param msg The message which shall be logged (UTF-8).
*/
virtual void Log(Level level, const std::string& msg) = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class ISystemMonitor

/*! \brief Get the current \ref ParticipantStatus of specific participant
*
* \param participantName The name of the participant for which the status is queried.
* \param participantName The name of the participant for which the status is queried (UTF-8).
* \throw SilKit::SilKitError If the participant name does not
* identify a participant that participates in synchronization.
*/
Expand All @@ -112,7 +112,7 @@ class ISystemMonitor

/*! \brief Check if a participant identified by the participantName is present.
*
* @param participantName The name of the participant for which presence is queried.
* @param participantName The name of the participant for which presence is queried (UTF-8).
* @return true if the participant is present
*/
virtual auto IsParticipantConnected(const std::string& participantName) const -> bool = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ enum class ParticipantState : SilKit_ParticipantState
//! \brief Details about a participant state change.
struct ParticipantStatus
{
std::string participantName; //!< Name of the participant.
std::string participantName; //!< Name of the participant (UTF-8).
ParticipantState state{ParticipantState::Invalid}; //!< The new state of the participant.
std::string enterReason; //!< The reason for the participant to enter the new state.
std::string enterReason; //!< The reason for the participant to enter the new state (UTF-8).
std::chrono::system_clock::time_point enterTime; //!< The enter time of the participant.
std::chrono::system_clock::time_point refreshTime; //!< The refresh time.
};
Expand Down
Loading

0 comments on commit 3782c14

Please sign in to comment.