[verification] Code compiles without errors.
Change-Id: If98eaf371ffbb47a2bf39978f9529307a9e9b06f
return &entryPointsInterface1;
}
- if (!strcmp(name, XW_MESSAGING_INTERFACE_1)) {
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
static const XW_MessagingInterface_1 messagingInterface1 = {
[](XW_Extension extension, XW_HandleMessageCallback handle_message) {
},
// code provided by extension.
//
-#define XW_MESSAGING_INTERFACE_1 "XW_MessagingInterface_1"
-#define XW_MESSAGING_INTERFACE XW_MESSAGING_INTERFACE_1
+#define XW_MESSAGING_INTERFACE_2 "XW_MessagingInterface_2"
+#define XW_MESSAGING_INTERFACE XW_MESSAGING_INTERFACE_2
typedef void (*XW_HandleMessageCallback)(XW_Instance instance, const char* message);
+typedef void (*XW_HandleBinaryMessageCallback)(XW_Instance instance, const char* message,
+ size_t size);
-struct XW_MessagingInterface_1 {
+struct XW_MessagingInterface_2 {
// Register a callback to be called when the JavaScript code associated
// with the extension posts a message. Note that the callback will be called
// with the XW_Instance that posted the message as well as the message
// This function is thread-safe and can be called until the instance is
// destroyed.
void (*PostMessage)(XW_Instance instance, const char* message);
+
+ // Provides communication for binary data exchange
+ void (*RegisterBinaryMesssageCallback)(XW_Extension extension,
+ XW_HandleBinaryMessageCallback handle_message);
+ void (*PostBinaryMessage)(XW_Instance instance, const char* message, size_t size);
};
-typedef struct XW_MessagingInterface_1 XW_MessagingInterface;
+typedef struct XW_MessagingInterface_2 XW_MessagingInterface;
#ifdef __cplusplus
} // extern "C"
instance->HandleMessage(msg);
}
+void Extension::HandleBinaryMessage(XW_Instance xw_instance, const char* msg, size_t size) {
+ ScopeLogger();
+ Instance* instance = reinterpret_cast<Instance*>(g_core->GetInstanceData(xw_instance));
+ if (!instance) {
+ return;
+ }
+ // TODO maybe async version will be needed in future
+ instance->HandleSyncBinaryMessage(msg, size);
+}
+
// static
void Extension::HandleSyncMessage(XW_Instance xw_instance, const char* msg) {
ScopeLogger();
g_core->RegisterInstanceCallbacks(extension, created_instance, Extension::OnInstanceDestroyed);
g_messaging->Register(extension, Extension::HandleMessage);
g_sync_messaging->Register(extension, Extension::HandleSyncMessage);
+
+ g_messaging->RegisterBinaryMesssageCallback(extension, Extension::HandleBinaryMessage);
return XW_OK;
}
LoggerE("Trying to post message to non-existing instance: [%p], ignoring", that);
}
+void Instance::PostMessage(Instance* that, const char* msg, size_t size) {
+ ScopeLogger();
+ if (nullptr != that) {
+ std::lock_guard<std::mutex> lock{instances_mutex_};
+ if (all_instances_.end() != all_instances_.find(that)) {
+ that->PostMessage(msg, size);
+ return;
+ }
+ }
+ LoggerE("Trying to post message to non-existing instance: [%p], ignoring", that);
+}
+
void Instance::PostMessage(Instance* that, const picojson::value& json) {
Instance::PostMessage(that, json.serialize().c_str());
}
g_messaging->PostMessage(xw_instance_, msg);
}
+void Instance::PostMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ if (!xw_instance_) {
+ LoggerE(
+ "Ignoring PostMessage() in the constructor or after the "
+ "instance was destroyed.");
+ return;
+ }
+ g_messaging->PostBinaryMessage(xw_instance_, msg, size);
+}
+
void Instance::SendSyncReply(const char* reply) {
ScopeLogger();
if (!xw_instance_) {
handler_map_.insert(std::make_pair("#SYNC#" + name, func));
}
+void ParsedInstance::RegisterBinaryHandler(const BinaryNativeHandler& func) {
+ ScopeLogger();
+ binary_handler_vec_.push_back(func);
+}
+
+void ParsedInstance::RegisterBinarySyncHandler(const BinaryNativeHandler& func) {
+ ScopeLogger();
+ // TODO - maybe async version will be needed in future
+ binary_handler_vec_.push_back(func);
+}
+
void ParsedInstance::ReportSuccess(picojson::object& out) {
ScopeLogger();
tools::ReportSuccess(out);
HandleMessage(msg, false);
}
+void ParsedInstance::HandleBinaryMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ HandleBinaryMessage(msg, size, false);
+}
+
void ParsedInstance::HandleSyncMessage(const char* msg) {
ScopeLogger();
HandleMessage(msg, true);
}
+void ParsedInstance::HandleSyncBinaryMessage(const char* msg, size_t size) {
+ ScopeLogger();
+ HandleBinaryMessage(msg, size, true);
+}
+
void ParsedInstance::HandleMessage(const char* msg, bool is_sync) {
ScopeLogger();
try {
}
}
+void ParsedInstance::HandleBinaryMessage(const char* msg, size_t size, bool is_sync) {
+ ScopeLogger();
+ try {
+ // first byte is a method ID
+ auto func = binary_handler_vec_.at(msg[0]);
+
+ picojson::value result = picojson::value(picojson::object());
+ func(msg + 1, size - 1, result.get<picojson::object>());
+
+ if (is_sync) SendSyncReply(result.serialize().c_str());
+ } catch (const std::out_of_range& e) {
+ return HandleException(UnknownException("Unknown command"));
+ } catch (const PlatformException& e) {
+ return HandleException(e);
+ } catch (const PlatformException* e) {
+ return HandleException(*e);
+ } catch (const std::exception& e) {
+ return HandleException(e);
+ } catch (...) {
+ return HandleException(UnknownException("Unknown exception"));
+ }
+}
+
void ParsedInstance::HandleException(const PlatformException& ex) {
ScopeLogger();
LoggerE("Exception: %s", ex.message().c_str());
#include <mutex>
#include <string>
#include <unordered_set>
+#include <vector>
#include "common/XW_Extension.h"
#include "common/XW_Extension_EntryPoints.h"
static void OnInstanceCreated(XW_Instance xw_instance, Instance* instance); // modified
static void OnInstanceDestroyed(XW_Instance xw_instance);
static void HandleMessage(XW_Instance xw_instance, const char* msg);
- static void HandleSyncMessage(XW_Instance xw_instance, const char* msg);
+ static void HandleSyncMessage(XW_Instance xw_instance, const char* msg);
+ static void HandleBinaryMessage(XW_Instance instance, const char* message, const size_t size);
XW_Extension xw_extension_;
class Detail;
static void DoAndPostMessage(Instance* that, const std::function<void()>& work,
const picojson::value& json);
static void PostMessage(Instance* that, const char* msg);
+ static void PostMessage(Instance* that, const char* msg, size_t size);
static void PostMessage(Instance* that, const picojson::value& json);
void PostMessage(const char* msg);
+ void PostMessage(const char* msg, size_t size);
void SendSyncReply(const char* reply);
virtual void Initialize() {
virtual void HandleSyncMessage(const char* msg) {
}
+ virtual void HandleBinaryMessage(const char* msg, size_t size) = 0;
+ virtual void HandleSyncBinaryMessage(const char* msg, size_t size) = 0;
+
XW_Instance xw_instance() const {
return xw_instance_;
}
};
typedef std::function<void(const picojson::value&, picojson::object&)> NativeHandler;
+typedef std::function<void(const char*, size_t size, picojson::object&)> BinaryNativeHandler;
class ParsedInstance : public Instance {
public:
void RegisterHandler(const std::string& name, const NativeHandler& func);
void RegisterSyncHandler(const std::string& name, const NativeHandler& func);
+ void RegisterBinaryHandler(const BinaryNativeHandler& func);
+ void RegisterBinarySyncHandler(const BinaryNativeHandler& func);
+
static void ReportSuccess(picojson::object& out);
static void ReportSuccess(const picojson::value& result, picojson::object& out);
static void ReportError(picojson::object& out);
void HandleMessage(const char* msg);
void HandleSyncMessage(const char* msg);
+ void HandleBinaryMessage(const char* msg, size_t size);
+ void HandleSyncBinaryMessage(const char* msg, size_t size);
+
void HandleMessage(const char* msg, bool is_sync);
+ void HandleBinaryMessage(const char* msg, size_t size, bool is_sync);
void HandleException(const PlatformException& ex);
void HandleException(const std::exception& e);
void HandleError(const PlatformResult& error);
std::map<std::string, NativeHandler> handler_map_;
+ std::vector<BinaryNativeHandler> binary_handler_vec_;
};
} // namespace common
return &entryPointsInterface1;
}
- if (!strcmp(name, XW_MESSAGING_INTERFACE_1)) {
- static const XW_MessagingInterface_1 messagingInterface1 = {
+ if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
+ static const XW_MessagingInterface_2 messagingInterface1 = {
[](XW_Extension extension, XW_HandleMessageCallback handle_message) {},
- [](XW_Instance instance, const char* message) {}};
+ [](XW_Instance instance, const char* message) {},
+ [](XW_Extension extension,
+ XW_HandleBinaryMessageCallback handle_message) {},
+ [](XW_Instance instance, const char* message, size_t size) {}};
return &messagingInterface1;
}
return JSON_.parse(response);
};
+NativeManager.prototype.callSyncBinaryWithJSONAnswer = function(uint8array_data) {
+ // method id should be coded as first byte, refer to:
+ // extension.cc - ParsedInstance:: HandleBinaryMessage
+
+ var response = this.extension.internal.sendSyncMessage(uint8array_data);
+ if (response === undefined) {
+ /* C++ extension didn't set sync response using Instance::SendSyncReply */
+ throw new WebAPIException(WebAPIException.ABORT_ERR, 'Internal error');
+ }
+ return JSON_.parse(response);
+};
+
NativeManager.prototype.sendRuntimeMessage = function(msg, body) {
return this.extension.sendRuntimeMessage(msg, body || '');
};