mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-28 16:14:09 +02:00
De-coupled JSON parsing from the Netstring class.
This commit is contained in:
parent
7b03f52e99
commit
cdcac0d903
@ -57,6 +57,8 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <algorithm>
|
|
||||||
#include "i2-base.h"
|
#include "i2-base.h"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
@ -68,7 +68,7 @@ void EndpointManager::AddConnection(string node, string service)
|
|||||||
|
|
||||||
void EndpointManager::RegisterServer(JsonRpcServer::Ptr server)
|
void EndpointManager::RegisterServer(JsonRpcServer::Ptr server)
|
||||||
{
|
{
|
||||||
m_Servers.push_front(server);
|
m_Servers.push_back(server);
|
||||||
server->OnNewClient += bind_weak(&EndpointManager::NewClientHandler, shared_from_this());
|
server->OnNewClient += bind_weak(&EndpointManager::NewClientHandler, shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,9 @@ int EndpointManager::NewClientHandler(const NewClientEventArgs& ncea)
|
|||||||
|
|
||||||
void EndpointManager::UnregisterServer(JsonRpcServer::Ptr server)
|
void EndpointManager::UnregisterServer(JsonRpcServer::Ptr server)
|
||||||
{
|
{
|
||||||
m_Servers.remove(server);
|
m_Servers.erase(
|
||||||
|
remove(m_Servers.begin(), m_Servers.end(), server),
|
||||||
|
m_Servers.end());
|
||||||
// TODO: unbind event
|
// TODO: unbind event
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
|
|||||||
throw InvalidArgumentException("Identity must be empty.");
|
throw InvalidArgumentException("Identity must be empty.");
|
||||||
|
|
||||||
endpoint->SetEndpointManager(static_pointer_cast<EndpointManager>(shared_from_this()));
|
endpoint->SetEndpointManager(static_pointer_cast<EndpointManager>(shared_from_this()));
|
||||||
m_Endpoints.push_front(endpoint);
|
m_Endpoints.push_back(endpoint);
|
||||||
|
|
||||||
NewEndpointEventArgs neea;
|
NewEndpointEventArgs neea;
|
||||||
neea.Source = shared_from_this();
|
neea.Source = shared_from_this();
|
||||||
@ -106,7 +108,9 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
|
|||||||
|
|
||||||
void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint)
|
void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint)
|
||||||
{
|
{
|
||||||
m_Endpoints.remove(endpoint);
|
m_Endpoints.erase(
|
||||||
|
remove(m_Endpoints.begin(), m_Endpoints.end(), endpoint),
|
||||||
|
m_Endpoints.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr recipient, const JsonRpcRequest& request, bool fromLocal)
|
void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr recipient, const JsonRpcRequest& request, bool fromLocal)
|
||||||
@ -123,7 +127,7 @@ void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr rec
|
|||||||
throw InvalidArgumentException("Missing 'method' parameter.");
|
throw InvalidArgumentException("Missing 'method' parameter.");
|
||||||
|
|
||||||
if (recipient->IsMethodSink(method)) {
|
if (recipient->IsMethodSink(method)) {
|
||||||
Application::Log(sender->GetAddress() + " -> " + recipient->GetAddress() + ": " + method);
|
//Application::Log(sender->GetAddress() + " -> " + recipient->GetAddress() + ": " + method);
|
||||||
recipient->ProcessRequest(sender, request);
|
recipient->ProcessRequest(sender, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +149,7 @@ void EndpointManager::SendMulticastRequest(Endpoint::Ptr sender, const JsonRpcRe
|
|||||||
if (!request.GetMethod(&method))
|
if (!request.GetMethod(&method))
|
||||||
throw InvalidArgumentException("Message is missing the 'method' property.");
|
throw InvalidArgumentException("Message is missing the 'method' property.");
|
||||||
|
|
||||||
for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
|
for (vector<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
|
||||||
{
|
{
|
||||||
SendUnicastRequest(sender, *i, request, fromLocal);
|
SendUnicastRequest(sender, *i, request, fromLocal);
|
||||||
}
|
}
|
||||||
@ -156,7 +160,7 @@ void EndpointManager::ForEachEndpoint(function<int (const NewEndpointEventArgs&)
|
|||||||
NewEndpointEventArgs neea;
|
NewEndpointEventArgs neea;
|
||||||
neea.Source = shared_from_this();
|
neea.Source = shared_from_this();
|
||||||
|
|
||||||
list<Endpoint::Ptr>::iterator prev, i;
|
vector<Endpoint::Ptr>::iterator prev, i;
|
||||||
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
|
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
|
||||||
prev = i;
|
prev = i;
|
||||||
i++;
|
i++;
|
||||||
@ -168,7 +172,7 @@ void EndpointManager::ForEachEndpoint(function<int (const NewEndpointEventArgs&)
|
|||||||
|
|
||||||
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const
|
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const
|
||||||
{
|
{
|
||||||
list<Endpoint::Ptr>::const_iterator i;
|
vector<Endpoint::Ptr>::const_iterator i;
|
||||||
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) {
|
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) {
|
||||||
if ((*i)->GetIdentity() == identity)
|
if ((*i)->GetIdentity() == identity)
|
||||||
return *i;
|
return *i;
|
||||||
|
@ -33,8 +33,8 @@ class I2_ICINGA_API EndpointManager : public Object
|
|||||||
string m_Identity;
|
string m_Identity;
|
||||||
shared_ptr<SSL_CTX> m_SSLContext;
|
shared_ptr<SSL_CTX> m_SSLContext;
|
||||||
|
|
||||||
list<JsonRpcServer::Ptr> m_Servers;
|
vector<JsonRpcServer::Ptr> m_Servers;
|
||||||
list<Endpoint::Ptr> m_Endpoints;
|
vector<Endpoint::Ptr> m_Endpoints;
|
||||||
|
|
||||||
void RegisterServer(JsonRpcServer::Ptr server);
|
void RegisterServer(JsonRpcServer::Ptr server);
|
||||||
void UnregisterServer(JsonRpcServer::Ptr server);
|
void UnregisterServer(JsonRpcServer::Ptr server);
|
||||||
|
@ -33,18 +33,21 @@ void JsonRpcClient::Start(void)
|
|||||||
|
|
||||||
void JsonRpcClient::SendMessage(const Message& message)
|
void JsonRpcClient::SendMessage(const Message& message)
|
||||||
{
|
{
|
||||||
Netstring::WriteMessageToFIFO(GetSendQueue(), message);
|
Netstring::WriteStringToFIFO(GetSendQueue(), message.ToJsonString());
|
||||||
}
|
}
|
||||||
|
|
||||||
int JsonRpcClient::DataAvailableHandler(const EventArgs&)
|
int JsonRpcClient::DataAvailableHandler(const EventArgs&)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
try {
|
try {
|
||||||
|
string jsonString;
|
||||||
Message message;
|
Message message;
|
||||||
|
|
||||||
if (!Netstring::ReadMessageFromFIFO(GetRecvQueue(), &message))
|
if (!Netstring::ReadStringFromFIFO(GetRecvQueue(), &jsonString))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
message = Message(jsonString);
|
||||||
|
|
||||||
NewMessageEventArgs nea;
|
NewMessageEventArgs nea;
|
||||||
nea.Source = shared_from_this();
|
nea.Source = shared_from_this();
|
||||||
nea.Message = message;
|
nea.Message = message;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "i2-jsonrpc.h"
|
#include "i2-jsonrpc.h"
|
||||||
|
#include <cJSON.h>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
@ -26,6 +27,18 @@ Message::Message(void)
|
|||||||
m_Dictionary = make_shared<Dictionary>();
|
m_Dictionary = make_shared<Dictionary>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::Message(string jsonString)
|
||||||
|
{
|
||||||
|
json_t *json = cJSON_Parse(jsonString.c_str());
|
||||||
|
|
||||||
|
if (!json)
|
||||||
|
throw InvalidArgumentException("Invalid JSON string");
|
||||||
|
|
||||||
|
m_Dictionary = GetDictionaryFromJson(json);
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
}
|
||||||
|
|
||||||
Message::Message(const Dictionary::Ptr& dictionary)
|
Message::Message(const Dictionary::Ptr& dictionary)
|
||||||
{
|
{
|
||||||
m_Dictionary = dictionary;
|
m_Dictionary = dictionary;
|
||||||
@ -36,6 +49,80 @@ Message::Message(const Message& message)
|
|||||||
m_Dictionary = message.GetDictionary();
|
m_Dictionary = message.GetDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr Message::GetDictionaryFromJson(json_t *json)
|
||||||
|
{
|
||||||
|
Dictionary::Ptr dictionary = make_shared<Dictionary>();
|
||||||
|
|
||||||
|
for (cJSON *i = json->child; i != NULL; i = i->next) {
|
||||||
|
switch (i->type) {
|
||||||
|
case cJSON_Number:
|
||||||
|
dictionary->SetProperty(i->string, i->valueint);
|
||||||
|
break;
|
||||||
|
case cJSON_String:
|
||||||
|
dictionary->SetProperty(i->string, i->valuestring);
|
||||||
|
break;
|
||||||
|
case cJSON_Object:
|
||||||
|
dictionary->SetProperty(i->string, GetDictionaryFromJson(i));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_t *Message::GetJsonFromDictionary(const Dictionary::Ptr& dictionary)
|
||||||
|
{
|
||||||
|
cJSON *json;
|
||||||
|
string valueString;
|
||||||
|
Dictionary::Ptr valueDictionary;
|
||||||
|
|
||||||
|
json = cJSON_CreateObject();
|
||||||
|
|
||||||
|
for (DictionaryIterator i = dictionary->Begin(); i != dictionary->End(); i++) {
|
||||||
|
switch (i->second.GetType()) {
|
||||||
|
case VariantInteger:
|
||||||
|
cJSON_AddNumberToObject(json, i->first.c_str(), i->second.GetInteger());
|
||||||
|
break;
|
||||||
|
case VariantString:
|
||||||
|
valueString = i->second.GetString();
|
||||||
|
cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
|
||||||
|
break;
|
||||||
|
case VariantObject:
|
||||||
|
valueDictionary = dynamic_pointer_cast<Dictionary>(i->second.GetObject());
|
||||||
|
|
||||||
|
if (valueDictionary)
|
||||||
|
cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(valueDictionary));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Message::ToJsonString(void) const
|
||||||
|
{
|
||||||
|
json_t *json = GetJsonFromDictionary(m_Dictionary);
|
||||||
|
char *jsonString;
|
||||||
|
string result;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
jsonString = cJSON_Print(json);
|
||||||
|
#else /* _DEBUG */
|
||||||
|
jsonString = cJSON_PrintUnformatted(json);
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
result = jsonString;
|
||||||
|
|
||||||
|
free(jsonString);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary::Ptr Message::GetDictionary(void) const
|
Dictionary::Ptr Message::GetDictionary(void) const
|
||||||
{
|
{
|
||||||
return m_Dictionary;
|
return m_Dictionary;
|
||||||
|
@ -20,19 +20,29 @@
|
|||||||
#ifndef MESSAGE_H
|
#ifndef MESSAGE_H
|
||||||
#define MESSAGE_H
|
#define MESSAGE_H
|
||||||
|
|
||||||
|
struct cJSON;
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef ::cJSON json_t;
|
||||||
|
|
||||||
class I2_JSONRPC_API Message
|
class I2_JSONRPC_API Message
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Dictionary::Ptr m_Dictionary;
|
Dictionary::Ptr m_Dictionary;
|
||||||
|
|
||||||
|
static Dictionary::Ptr GetDictionaryFromJson(json_t *json);
|
||||||
|
static json_t *GetJsonFromDictionary(const Dictionary::Ptr& dictionary);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Message(void);
|
Message(void);
|
||||||
|
Message(string json);
|
||||||
Message(const Dictionary::Ptr& dictionary);
|
Message(const Dictionary::Ptr& dictionary);
|
||||||
Message(const Message& message);
|
Message(const Message& message);
|
||||||
|
|
||||||
|
string ToJsonString(void) const;
|
||||||
|
|
||||||
Dictionary::Ptr GetDictionary(void) const;
|
Dictionary::Ptr GetDictionary(void) const;
|
||||||
|
|
||||||
bool GetPropertyString(string key, string *value) const;
|
bool GetPropertyString(string key, string *value) const;
|
||||||
|
@ -17,67 +17,12 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include "i2-jsonrpc.h"
|
#include "i2-jsonrpc.h"
|
||||||
#include <cJSON.h>
|
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
Dictionary::Ptr Netstring::GetDictionaryFromJson(json_t *json)
|
|
||||||
{
|
|
||||||
Dictionary::Ptr dictionary = make_shared<Dictionary>();
|
|
||||||
|
|
||||||
for (cJSON *i = json->child; i != NULL; i = i->next) {
|
|
||||||
switch (i->type) {
|
|
||||||
case cJSON_Number:
|
|
||||||
dictionary->SetProperty(i->string, i->valueint);
|
|
||||||
break;
|
|
||||||
case cJSON_String:
|
|
||||||
dictionary->SetProperty(i->string, i->valuestring);
|
|
||||||
break;
|
|
||||||
case cJSON_Object:
|
|
||||||
dictionary->SetProperty(i->string, GetDictionaryFromJson(i));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
json_t *Netstring::GetJsonFromDictionary(const Dictionary::Ptr& dictionary)
|
|
||||||
{
|
|
||||||
cJSON *json;
|
|
||||||
string valueString;
|
|
||||||
Dictionary::Ptr valueDictionary;
|
|
||||||
|
|
||||||
json = cJSON_CreateObject();
|
|
||||||
|
|
||||||
for (DictionaryIterator i = dictionary->Begin(); i != dictionary->End(); i++) {
|
|
||||||
switch (i->second.GetType()) {
|
|
||||||
case VariantInteger:
|
|
||||||
cJSON_AddNumberToObject(json, i->first.c_str(), i->second.GetInteger());
|
|
||||||
break;
|
|
||||||
case VariantString:
|
|
||||||
valueString = i->second.GetString();
|
|
||||||
cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
|
|
||||||
break;
|
|
||||||
case VariantObject:
|
|
||||||
valueDictionary = dynamic_pointer_cast<Dictionary>(i->second.GetObject());
|
|
||||||
|
|
||||||
if (valueDictionary)
|
|
||||||
cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(valueDictionary));
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
|
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
|
||||||
bool Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message)
|
bool Netstring::ReadStringFromFIFO(FIFO::Ptr fifo, string *str)
|
||||||
{
|
{
|
||||||
size_t buffer_length = fifo->GetSize();
|
size_t buffer_length = fifo->GetSize();
|
||||||
char *buffer = (char *)fifo->GetReadBuffer();
|
char *buffer = (char *)fifo->GetReadBuffer();
|
||||||
@ -113,45 +58,22 @@ bool Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message)
|
|||||||
if (buffer[i + len] != ',')
|
if (buffer[i + len] != ',')
|
||||||
throw InvalidArgumentException("Invalid Netstring (missing ,)");
|
throw InvalidArgumentException("Invalid Netstring (missing ,)");
|
||||||
|
|
||||||
/* nuke the comma delimiter */
|
*str = string(&buffer[i], &buffer[i + len]);
|
||||||
buffer[i + len] = '\0';
|
|
||||||
cJSON *object = cJSON_Parse(&buffer[i]);
|
|
||||||
|
|
||||||
if (object == NULL) {
|
|
||||||
/* restore the comma */
|
|
||||||
buffer[i + len] = ',';
|
|
||||||
throw InvalidArgumentException("Invalid JSON string");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove the data from the fifo */
|
/* remove the data from the fifo */
|
||||||
fifo->Read(NULL, i + len + 1);
|
fifo->Read(NULL, i + len + 1);
|
||||||
|
|
||||||
*message = Message(GetDictionaryFromJson(object));
|
|
||||||
cJSON_Delete(object);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Netstring::WriteMessageToFIFO(FIFO::Ptr fifo, const Message& message)
|
void Netstring::WriteStringToFIFO(FIFO::Ptr fifo, const string& str)
|
||||||
{
|
{
|
||||||
char *json;
|
unsigned long len = str.size();
|
||||||
cJSON *object = GetJsonFromDictionary(message.GetDictionary());
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
json = cJSON_Print(object);
|
|
||||||
#else /* _DEBUG */
|
|
||||||
json = cJSON_PrintUnformatted(object);
|
|
||||||
#endif /* _DEBUG */
|
|
||||||
|
|
||||||
cJSON_Delete(object);
|
|
||||||
|
|
||||||
len = strlen(json);
|
|
||||||
char strLength[50];
|
char strLength[50];
|
||||||
sprintf(strLength, "%lu:", (unsigned long)len);
|
sprintf(strLength, "%lu:", (unsigned long)len);
|
||||||
|
|
||||||
fifo->Write(strLength, strlen(strLength));
|
fifo->Write(strLength, strlen(strLength));
|
||||||
fifo->Write(json, len);
|
fifo->Write(str.c_str(), len);
|
||||||
free(json);
|
|
||||||
|
|
||||||
fifo->Write(",", 1);
|
fifo->Write(",", 1);
|
||||||
}
|
}
|
||||||
|
@ -20,28 +20,17 @@
|
|||||||
#ifndef NETSTRING_H
|
#ifndef NETSTRING_H
|
||||||
#define NETSTRING_H
|
#define NETSTRING_H
|
||||||
|
|
||||||
struct cJSON;
|
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef ::cJSON json_t;
|
|
||||||
|
|
||||||
class I2_JSONRPC_API Netstring : public Object
|
class I2_JSONRPC_API Netstring : public Object
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
size_t m_Length;
|
|
||||||
void *m_Data;
|
|
||||||
|
|
||||||
static Dictionary::Ptr GetDictionaryFromJson(json_t *json);
|
|
||||||
static json_t *GetJsonFromDictionary(const Dictionary::Ptr& dictionary);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<Netstring> Ptr;
|
typedef shared_ptr<Netstring> Ptr;
|
||||||
typedef weak_ptr<Netstring> WeakPtr;
|
typedef weak_ptr<Netstring> WeakPtr;
|
||||||
|
|
||||||
static bool ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message);
|
static bool ReadStringFromFIFO(FIFO::Ptr fifo, string *message);
|
||||||
static void WriteMessageToFIFO(FIFO::Ptr fifo, const Message& message);
|
static void WriteStringToFIFO(FIFO::Ptr fifo, const string& message);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user