assert(Object::ActiveObjects == 0);
return result;
-}
\ No newline at end of file
+}
string GetMessage(void) const;
};
-}
-
#define DEFINE_EXCEPTION_CLASS(klass) \
class klass : public Exception \
{ \
} \
};
+DEFINE_EXCEPTION_CLASS(NotImplementedException);
+DEFINE_EXCEPTION_CLASS(InvalidArgumentException);
+
+}
+
#endif /* EXCEPTION_H */
int ConfigRpcComponent::RemoteObjectRemovedHandler(NewMessageEventArgs::Ptr ea)
{
- JsonRpcMessage::Ptr message = ea->Message;
+ JsonRpcRequest::Ptr message = ea->Message->Cast<JsonRpcRequest>();
+ Message::Ptr params = message->GetParams();
string name, type;
if (!message->GetParamString("name", &name))
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsonrpc", "jsonrpc\jsonrpc.vcxproj", "{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}"
ProjectSection(ProjectDependencies) = postProject
{66BED474-C33F-48F9-90BA-BBCFEDC006B8} = {66BED474-C33F-48F9-90BA-BBCFEDC006B8}
+ {4F00EE82-B829-4872-B8F0-C1A8D86C94B4} = {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}
{9C92DA90-FD53-43A9-A244-90F2E8AF9677} = {9C92DA90-FD53-43A9-A244-90F2E8AF9677}
EndProjectSection
EndProject
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msgc", "msgc\msgc.vcxproj", "{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
{697C6D7E-3109-484C-A7AF-384D28711610}.Debug|Win32.Build.0 = Debug|Win32
{697C6D7E-3109-484C-A7AF-384D28711610}.Release|Win32.ActiveCfg = Release|Win32
{697C6D7E-3109-484C-A7AF-384D28711610}.Release|Win32.Build.0 = Release|Win32
+ {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Debug|Win32.Build.0 = Debug|Win32
+ {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Release|Win32.ActiveCfg = Release|Win32
+ {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
using namespace icinga;
-Endpoint::Endpoint(void)
+void Endpoint::RegisterMethodSink(string method)
{
- m_Connected = false;
+ m_MethodSinks.insert(method);
}
-void Endpoint::SetConnected(bool connected)
+void Endpoint::UnregisterMethodSink(string method)
{
- m_Connected = connected;
+ m_MethodSinks.erase(method);
}
-bool Endpoint::GetConnected(void)
+bool Endpoint::IsMethodSink(string method)
{
- return m_Connected;
+ return (m_MethodSinks.find(method) != m_MethodSinks.end());
+}
+
+void Endpoint::RegisterMethodSource(string method)
+{
+ m_MethodSources.insert(method);
+}
+
+void Endpoint::UnregisterMethodSource(string method)
+{
+ m_MethodSources.erase(method);
+}
+
+bool Endpoint::IsMethodSource(string method)
+{
+ return (m_MethodSources.find(method) != m_MethodSinks.end());
}
class I2_ICINGA_API Endpoint : public Object
{
private:
- bool m_Connected;
+ set<string> m_MethodSinks;
+ set<string> m_MethodSources;
public:
typedef shared_ptr<Endpoint> Ptr;
typedef weak_ptr<Endpoint> WeakPtr;
- Endpoint(void);
+ void RegisterMethodSink(string method);
+ void UnregisterMethodSink(string method);
+ bool IsMethodSink(string method);
- virtual void SetConnected(bool connected);
- virtual bool GetConnected(void);
+ void RegisterMethodSource(string method);
+ void UnregisterMethodSource(string method);
+ bool IsMethodSource(string method);
- virtual void SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message) = 0;
+ virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message) = 0;
+ virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message) = 0;
};
}
m_Endpoints.remove(endpoint);
}
-void EndpointManager::SendMessage(Endpoint::Ptr source, Endpoint::Ptr destination, JsonRpcMessage::Ptr message)
+void EndpointManager::SendAnycastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
{
- if (destination) {
- destination->SendMessage(source, message);
- } else {
- for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
- {
- Endpoint::Ptr endpoint = *i;
+ throw NotImplementedException();
+}
+
+void EndpointManager::SendMulticastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
+{
+#ifdef _DEBUG
+ string id;
+ if (request->GetID(&id))
+ throw InvalidArgumentException("Multicast requests must not have an ID.");
+#endif /* _DEBUG */
+
+ string method;
+ if (!request->GetMethod(&method))
+ throw InvalidArgumentException();
+
+ for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
+ {
+ Endpoint::Ptr endpoint = *i;
- if (endpoint == source)
- continue;
+ if (endpoint == sender)
+ continue;
- endpoint->SendMessage(source, message);
- }
+ if (endpoint->IsMethodSink(method))
+ endpoint->SendRequest(sender, request);
}
}
void RegisterEndpoint(Endpoint::Ptr endpoint);
void UnregisterEndpoint(Endpoint::Ptr endpoint);
- void SendMessage(Endpoint::Ptr source, Endpoint::Ptr destination, JsonRpcMessage::Ptr message);
+ void SendAnycastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request);
+ void SendMulticastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request);
};
}
#include <i2-base.h>
#include <i2-jsonrpc.h>
+#include <set>
#ifdef I2_ICINGA_BUILD
# define I2_ICINGA_API I2_EXPORT
#include "i2-icinga.h"
using namespace icinga;
+
+JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void)
+{
+ return m_Client;
+}
+
+void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client)
+{
+ m_Client = client;
+}
+
+bool JsonRpcEndpoint::IsConnected(void) const
+{
+ return (m_Client.get() != NULL);
+}
+
+void JsonRpcEndpoint::SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message)
+{
+ if (IsConnected())
+ m_Client->SendMessage(message);
+}
+
+void JsonRpcEndpoint::SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message)
+{
+ if (IsConnected())
+ m_Client->SendMessage(message);
+}
class I2_ICINGA_API JsonRpcEndpoint : public Endpoint
{
+private:
+ JsonRpcClient::Ptr m_Client;
+
+ bool IsConnected(void) const;
+
public:
+ JsonRpcEndpoint(void);
+
+ JsonRpcClient::Ptr GetClient(void);
+ void SetClient(JsonRpcClient::Ptr client);
+
+ virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message);
+ virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message);
};
}
-#endif /* JSONRPCENDPOINT_H */
\ No newline at end of file
+#endif /* JSONRPCENDPOINT_H */
using namespace icinga;
-VirtualEndpoint::VirtualEndpoint()
-{
- SetConnected(true);
-}
-
-void VirtualEndpoint::RegisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback)
+void VirtualEndpoint::RegisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback)
{
m_MethodHandlers[method] += callback;
+
+ RegisterMethodSink(method);
}
-void VirtualEndpoint::UnregisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback)
+void VirtualEndpoint::UnregisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback)
{
// TODO: implement
- //m_Methods[method] -= callback;
-}
+ //m_MethodHandlers[method] -= callback;
+ //UnregisterMethodSink(method);
-void VirtualEndpoint::RegisterMethodSource(string method)
-{
- m_MethodSources.push_front(method);
+ throw NotImplementedException();
}
-void VirtualEndpoint::UnregisterMethodSource(string method)
+void VirtualEndpoint::SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
{
- m_MethodSources.remove(method);
+ string method;
+ if (!request->GetMethod(&method))
+ return;
+
+ map<string, Event<NewRequestEventArgs::Ptr> >::iterator i = m_MethodHandlers.find(method);
+
+ if (i == m_MethodHandlers.end())
+ throw InvalidArgumentException();
+
+ NewRequestEventArgs::Ptr nrea = make_shared<NewRequestEventArgs>();
+ nrea->Source = shared_from_this();
+ nrea->Sender = sender;
+ nrea->Request = request;
+ i->second(nrea);
}
-void VirtualEndpoint::SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message)
+void VirtualEndpoint::SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr response)
{
- map<string, Event<NewMessageEventArgs::Ptr> >::iterator i;
- i = m_MethodHandlers.find(message->GetMethod());
-
- if (i == m_MethodHandlers.end()) {
- JsonRpcMessage::Ptr response = make_shared<JsonRpcMessage>();
- response->SetVersion("2.0");
- response->SetError("Unknown method.");
- response->SetID(message->GetID());
- source->SendMessage(static_pointer_cast<Endpoint>(shared_from_this()), response);
- }
-
- NewMessageEventArgs::Ptr nmea = make_shared<NewMessageEventArgs>();
- nmea->Source = shared_from_this();
- nmea->Message = message;
- i->second(nmea);
+ // TODO: figure out which request this response belongs to and notify the caller
+ throw NotImplementedException();
}
namespace icinga
{
+struct I2_JSONRPC_API NewRequestEventArgs : public EventArgs
+{
+ typedef shared_ptr<NewRequestEventArgs> Ptr;
+ typedef weak_ptr<NewRequestEventArgs> WeakPtr;
+
+ Endpoint::Ptr Sender;
+ JsonRpcRequest::Ptr Request;
+};
+
class I2_ICINGA_API VirtualEndpoint : public Endpoint
{
private:
- map< string, Event<NewMessageEventArgs::Ptr> > m_MethodHandlers;
- list<string> m_MethodSources;
+ map< string, Event<NewRequestEventArgs::Ptr> > m_MethodHandlers;
public:
typedef shared_ptr<VirtualEndpoint> Ptr;
typedef weak_ptr<VirtualEndpoint> WeakPtr;
- VirtualEndpoint();
-
- virtual void RegisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback);
- virtual void UnregisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback);
+ void RegisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback);
+ void UnregisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback);
virtual void RegisterMethodSource(string method);
virtual void UnregisterMethodSource(string method);
- virtual void SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message);
+ virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message);
+ virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message);
};
}
# define I2_JSONRPC_API I2_IMPORT
#endif /* I2_JSONRPC_BUILD */
+#include "message.h"
#include "netstring.h"
-#include "jsonrpcmessage.h"
+#include "jsonrpcrequest.h"
+#include "jsonrpcresponse.h"
#include "jsonrpcclient.h"
#include "jsonrpcserver.h"
<ItemGroup>
<ClInclude Include="i2-jsonrpc.h" />
<ClInclude Include="jsonrpcclient.h" />
- <ClInclude Include="jsonrpcmessage.h" />
+ <ClInclude Include="jsonrpcrequest.h" />
+ <ClInclude Include="jsonrpcresponse.h" />
<ClInclude Include="jsonrpcserver.h" />
+ <ClInclude Include="message.h" />
<ClInclude Include="netstring.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="jsonrpcclient.cpp" />
- <ClCompile Include="jsonrpcmessage.cpp" />
+ <ClCompile Include="jsonrpcrequest.cpp" />
+ <ClCompile Include="jsonrpcresponse.cpp" />
<ClCompile Include="jsonrpcserver.cpp" />
+ <ClCompile Include="message.cpp" />
<ClCompile Include="netstring.cpp" />
</ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="jsonrpcrequest.message">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Identity)</Message>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Identity)</Message>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp %(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp %(Filename).h</Outputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </AdditionalInputs>
+ </CustomBuild>
+ <CustomBuild Include="jsonrpcresponse.message">
+ <FileType>Document</FileType>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp %(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp %(Filename).h</Outputs>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Identity)</Message>
+ <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Identity)</Message>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </AdditionalInputs>
+ <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </AdditionalInputs>
+ </CustomBuild>
+ </ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
OnDataAvailable += bind_weak(&JsonRpcClient::DataAvailableHandler, shared_from_this());
}
-void JsonRpcClient::SendMessage(JsonRpcMessage::Ptr message)
+void JsonRpcClient::SendMessage(Message::Ptr message)
{
- Netstring::WriteJSONToFIFO(GetSendQueue(), message->GetJSON());
+ Netstring::WriteMessageToFIFO(GetSendQueue(), message);
}
int JsonRpcClient::DataAvailableHandler(EventArgs::Ptr ea)
{
- cJSON *json;
+ Message::Ptr message;
while (true) {
try {
- json = Netstring::ReadJSONFromFIFO(GetRecvQueue());
+ message = Netstring::ReadMessageFromFIFO(GetRecvQueue());
} catch (const exception&) {
Close();
return 1;
}
- if (json == NULL)
+ if (message.get() == NULL)
break;
- JsonRpcMessage::Ptr msg = make_shared<JsonRpcMessage>();
- msg->SetJSON(json);
NewMessageEventArgs::Ptr nea = make_shared<NewMessageEventArgs>();
nea->Source = shared_from_this();
- nea->Message = msg;
+ nea->Message = message;
OnNewMessage(nea);
}
typedef shared_ptr<NewMessageEventArgs> Ptr;
typedef weak_ptr<NewMessageEventArgs> WeakPtr;
- JsonRpcMessage::Ptr Message;
+ Message::Ptr Message;
};
class I2_JSONRPC_API JsonRpcClient : public TCPClient
typedef shared_ptr<JsonRpcClient> Ptr;
typedef weak_ptr<JsonRpcClient> WeakPtr;
- void SendMessage(JsonRpcMessage::Ptr message);
+ void SendMessage(Message::Ptr message);
virtual void Start(void);
+++ /dev/null
-#include "i2-jsonrpc.h"
-
-using namespace icinga;
-
-JsonRpcMessage::JsonRpcMessage(void)
-{
- m_JSON = NULL;
-}
-
-JsonRpcMessage::~JsonRpcMessage(void)
-{
- cJSON_Delete(m_JSON);
-}
-
-void JsonRpcMessage::SetJSON(cJSON *object)
-{
- cJSON_Delete(m_JSON);
- m_JSON = object;
-}
-
-cJSON *JsonRpcMessage::GetJSON(void)
-{
- return m_JSON;
-}
-
-void JsonRpcMessage::InitJson(void)
-{
- if (m_JSON == NULL)
- m_JSON = cJSON_CreateObject();
-}
-
-void JsonRpcMessage::SetFieldObject(const char *field, cJSON *object)
-{
- if (m_JSON == NULL && object == NULL)
- return;
-
- InitJson();
-
- cJSON_DeleteItemFromObject(m_JSON, field);
-
- if (object != NULL)
- cJSON_AddItemToObject(m_JSON, field, object);
-}
-
-cJSON *JsonRpcMessage::GetFieldObject(const char *field)
-{
- if (m_JSON == NULL)
- return NULL;
-
- return cJSON_GetObjectItem(m_JSON, field);
-}
-
-void JsonRpcMessage::SetFieldString(const char *field, const string& value)
-{
- cJSON *object = cJSON_CreateString(value.c_str());
- SetFieldObject(field, object);
-}
-
-string JsonRpcMessage::GetFieldString(const char *field)
-{
- cJSON *object = GetFieldObject(field);
-
- if (object == NULL || object->type != cJSON_String)
- return string();
-
- return string(object->valuestring);
-}
-
-void JsonRpcMessage::SetVersion(const string& version)
-{
- SetFieldString("version", version);
-}
-
-string JsonRpcMessage::GetVersion(void)
-{
- return GetFieldString("jsonrpc");
-}
-
-void JsonRpcMessage::SetID(const string& id)
-{
- SetFieldString("id", id);
-}
-
-string JsonRpcMessage::GetID(void)
-{
- return GetFieldString("id");
-}
-
-void JsonRpcMessage::SetMethod(const string& method)
-{
- SetFieldString("method", method);
-}
-
-string JsonRpcMessage::GetMethod(void)
-{
- return GetFieldString("method");
-}
-
-void JsonRpcMessage::ClearParams(void)
-{
- SetFieldObject("params", NULL);
-}
-
-cJSON *JsonRpcMessage::GetParams(void)
-{
- cJSON *object = GetFieldObject("params");
-
- if (object == NULL) {
- object = cJSON_CreateObject();
- cJSON_AddItemToObject(m_JSON, "params", object);
- }
-
- return object;
-}
-
-void JsonRpcMessage::SetParam(const string& name, const string& value)
-{
-}
-
-cJSON *JsonRpcMessage::GetParam(const string& name)
-{
- cJSON *params = GetFieldObject("params");
-
- if (params == NULL)
- return NULL;
-
- return cJSON_GetObjectItem(params, name.c_str());
-}
-
-bool JsonRpcMessage::GetParamString(const string name, string *value)
-{
- cJSON *param = GetParam(name);
-
- if (param == NULL || param->type != cJSON_String)
- return false;
-
- *value = param->valuestring;
-
- return true;
-}
-
-void JsonRpcMessage::ClearResult(void)
-{
- SetFieldObject("result", NULL);
-}
-
-cJSON *JsonRpcMessage::GetResult(void)
-{
- cJSON *object = GetFieldObject("result");
-
- if (object == NULL) {
- object = cJSON_CreateObject();
- cJSON_AddItemToObject(m_JSON, "result", object);
- }
-
- return object;
-}
-
-void JsonRpcMessage::SetError(const string& error)
-{
- SetFieldString("error", error);
-}
-
-string JsonRpcMessage::GetError(void)
-{
- return GetFieldString("error");
-}
+++ /dev/null
-#ifndef JSONRPCMESSAGE_H
-#define JSONRPCMESSAGE_H
-
-namespace icinga
-{
-
-class I2_JSONRPC_API JsonRpcMessage : public Object
-{
-private:
- cJSON *m_JSON;
-
- void InitJson(void);
-
- void SetFieldString(const char *field, const string& value);
- string GetFieldString(const char *field);
-
- void ClearField(const char *field);
- void SetFieldObject(const char *field, cJSON *object);
- cJSON *GetFieldObject(const char *field);
-
-public:
- typedef shared_ptr<JsonRpcMessage> Ptr;
- typedef weak_ptr<JsonRpcMessage> WeakPtr;
-
- JsonRpcMessage(void);
- ~JsonRpcMessage(void);
-
- void SetJSON(cJSON *object);
- cJSON *GetJSON(void);
-
- void SetVersion(const string& version);
- string GetVersion(void);
-
- void SetID(const string& id);
- string GetID(void);
-
- void SetMethod(const string& method);
- string GetMethod(void);
-
- void ClearParams(void);
- cJSON *GetParams(void);
-
- void SetParam(const string& name, const string& value);
- cJSON *GetParam(const string& name);
- bool GetParamString(const string name, string *value);
-
- void ClearResult();
- cJSON *GetResult(void);
-
- void SetError(const string& error);
- string GetError(void);
-};
-
-}
-
-#endif /* JSONRPCMESSAGE_H */
--- /dev/null
+JsonRpcRequest : Message
+ JsonRpc : string
+ Method : string
+ Params : Message
+ ID : string
--- /dev/null
+JsonRpcResponse : Message
+ JsonRpc : string
+ Result : string
+ Error : string
+ ID : string
using namespace icinga;
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
-cJSON *Netstring::ReadJSONFromFIFO(FIFO::Ptr fifo)
+Message::Ptr Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo)
{
size_t buffer_length = fifo->GetSize();
char *buffer = (char *)fifo->GetReadBuffer();
/* remove the data from the fifo */
fifo->Read(NULL, i + len + 1);
- return object;
+ return make_shared<Message>(object);
}
-void Netstring::WriteJSONToFIFO(FIFO::Ptr fifo, cJSON *object)
+void Netstring::WriteMessageToFIFO(FIFO::Ptr fifo, Message::Ptr message)
{
char *json;
+ shared_ptr<cJSON> object = message->GetJson();
size_t len;
#ifdef _DEBUG
- json = cJSON_Print(object);
+ json = cJSON_Print(object.get());
#else /* _DEBUG */
- json = cJSON_PrintUnformatted(object);
+ json = cJSON_PrintUnformatted(object.get());
#endif /* _DEBUG */
len = strlen(json);
typedef shared_ptr<Netstring> Ptr;
typedef weak_ptr<Netstring> WeakPtr;
- static cJSON *ReadJSONFromFIFO(FIFO::Ptr fifo);
- static void WriteJSONToFIFO(FIFO::Ptr fifo, cJSON *object);
+ static Message::Ptr ReadMessageFromFIFO(FIFO::Ptr fifo);
+ static void WriteMessageToFIFO(FIFO::Ptr fifo, Message::Ptr message);
};
}
--- /dev/null
+#include <cstdlib>
+#include <cctype>
+#include <iostream>
+#include <algorithm>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+void trim(string& str, const char *whitespace = "\r\n\t ")
+{
+ string::size_type pos;
+
+ pos = str.find_first_not_of(whitespace);
+ if (pos != string::npos)
+ str.erase(0, pos);
+
+ pos = str.find_last_not_of(whitespace);
+ if (pos != string::npos)
+ str.erase(pos + 1);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ cerr << "Syntax: " << argv[0] << " <file.message>" << endl;
+ return EXIT_FAILURE;
+ }
+
+ char *pos;
+ pos = strrchr(argv[1], '.');
+
+ if (pos == NULL || strcmp(pos, ".message") != 0) {
+ cerr << "Input filename must have the '.message' extension." << endl;
+ return EXIT_FAILURE;
+ }
+
+ char *headername, *implname;
+ headername = strdup(argv[1]);
+ strcpy(&(headername[pos - argv[1]]), ".h");
+
+ implname = strdup(argv[1]);
+ strcpy(&(implname[pos - argv[1]]), ".cpp");
+
+ fstream inputfp, headerfp, implfp;
+
+ inputfp.open(argv[1], fstream::in);
+ headerfp.open(headername, fstream::out | fstream::trunc);
+ implfp.open(implname, fstream::out | fstream::trunc);
+
+ string line;
+ string klass, klassupper, base;
+ bool hasclass = false;
+
+ while (true) {
+ getline(inputfp, line);
+
+ if (inputfp.fail())
+ break;
+
+ if (!hasclass) {
+ string::size_type index = line.find(':');
+
+ if (index == string::npos) {
+ cerr << "Must specify class and base name." << endl;
+ return EXIT_FAILURE;
+ }
+
+ klass = line.substr(0, index);
+ trim(klass);
+
+ klassupper = klass;
+ transform(klassupper.begin(), klassupper.end(), klassupper.begin(), toupper);
+
+ base = line.substr(index + 1);
+ trim(base);
+
+ cout << "Class: '" << klass << "' (inherits from: '" << base << "')" << endl;
+
+ headerfp << "#ifndef " << klassupper << "_H" << endl
+ << "#define " << klassupper << "_H" << endl
+ << endl
+ << "namespace icinga" << endl
+ << "{" << endl
+ << endl
+ << "class " << klass << " : public " << base << endl
+ << "{" << endl
+ << endl
+ << "public:" << endl
+ << "\ttypedef shared_ptr<" << klass << "> Ptr;" << endl
+ << "\ttypedef weak_ptr<" << klass << "> WeakPtr;" << endl
+ << endl
+ << "\t" << klass << "(void) : " << base << "() { }" << endl
+ << "\t" << klass << "(const Message::Ptr& message) : " << base << "(message) { }" << endl
+ << endl;
+
+ implfp << "#include \"i2-jsonrpc.h\"" << endl
+ << "#include \"" << headername << "\"" << endl
+ << endl
+ << "using namespace icinga;" << endl
+ << endl;
+
+ hasclass = true;
+ } else {
+ string::size_type index = line.find(':');
+
+ if (index == string::npos) {
+ cerr << "Must specify type and property name." << endl;
+ return EXIT_FAILURE;
+ }
+
+ string prop = line.substr(0, index);
+ trim(prop);
+
+ string type = line.substr(index + 1);
+ trim(type);
+
+ string typeaccessor = type;
+ typeaccessor[0] = toupper(typeaccessor[0]);
+
+ string rawtype = type;
+
+ /* assume it's a reference type if we don't know the type */
+ if (type != "int" && type != "string") {
+ type = type + "::Ptr";
+ typeaccessor = "Message";
+ }
+
+ cout << "Property: '" << prop << "' (Type: '" << type << "')" << endl;
+
+ headerfp << endl
+ << "\tbool Get" << prop << "(" << type << " *value);" << endl
+ << "\tvoid Set" << prop << "(const " << type << "& value);" << endl;
+
+ implfp << "bool " << klass << "::Get" << prop << "(" << type << " *value)" << endl
+ << "{" << endl;
+
+ if (typeaccessor == "Message") {
+ implfp << "\tMessage::Ptr message;" << endl
+ << endl
+ << "\tif (!GetProperty" << typeaccessor << "(\"" << prop << "\", &message))" << endl
+ << "\treturn false;" << endl
+ << endl
+ << "\t*value = message->Cast<" + rawtype + ">();" << endl
+ << "return true;" << endl
+ << endl;
+ } else {
+ implfp << "\treturn GetProperty" << typeaccessor << "(\"" << prop << "\", value);" << endl;
+ }
+
+ implfp << "}" << endl
+ << endl;
+
+ implfp << "void " << klass << "::Set" << prop << "(const " << type << "& value)" << endl
+ << "{" << endl
+ << "\tSetProperty" << typeaccessor << "(\"" << prop << "\", value);" << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+
+ headerfp << endl
+ << "};" << endl
+ << endl
+ << "}" << endl
+ << endl
+ << "#endif /* " << klassupper << "_H */" << endl;
+
+ inputfp.close();
+ headerfp.close();
+ implfp.close();
+
+ free(headername);
+ free(implname);
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>msgc</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="msgc.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file