[DEV] start to send data to the server

This commit is contained in:
Edouard DUPIN 2016-06-03 23:45:01 +02:00
parent cf72ad71fb
commit 6d985f7d2f
17 changed files with 392 additions and 266 deletions

29
database.json_picture Normal file
View File

@ -0,0 +1,29 @@
{
"default-view": { },
"right-group": [ "public" ],
"right-user": [ ],
"group-global": [ "photo", "drawing" ],
"groups": {
"photo": {
"right-herited": false,
"right-group": [ "famille" ],
"right-user": [ "camille#atria-soft.com" ],
"sub": [ "2015", "2016" ],
"files": [ 22641, 34695 ]
},
"drawing": {
"right-herited": true,
"files": [ 33913, 262464 ]
},
"2015": {
"right-herited": true,
"sub": [ ],
"files": [ 33913 ]
},
"2016": {
"right-herited": true,
"sub": [ ],
"files": [ 33913, 262464 ]
}
}
}

View File

@ -5,6 +5,8 @@
*/ */
#include <jus/AbstractFunction.h> #include <jus/AbstractFunction.h>
#include <jus/debug.h> #include <jus/debug.h>
#include <etk/os/FSNode.h>
#include <ejson/base64.h>
namespace jus { namespace jus {
template<> bool convertJsonTo<bool>(const ejson::Value& _value) { template<> bool convertJsonTo<bool>(const ejson::Value& _value) {
return _value.toBoolean().get(); return _value.toBoolean().get();
@ -62,61 +64,78 @@ namespace jus {
out.setMineType(obj["mine-type"].toString().get()); out.setMineType(obj["mine-type"].toString().get());
out.preSetDataSize(obj["size"].toNumber().getU64()); out.preSetDataSize(obj["size"].toNumber().getU64());
//out.add("type", ejson::String("file")); //out.add("type", ejson::String("file"));
// TODO : Add extended datas ...
uint64_t offset = 0;
for (auto it : obj["data"].toArray()) {
ejson::String valData = it.toString();
if (valData.get().size() != 0) {
std::vector<uint8_t> tmpData = ejson::base64::decode(valData.get());
out.setData(offset, tmpData);
offset += tmpData.size();
}
}
return out; return out;
} }
template<> ejson::Value convertToJson<bool>(const bool& _value) { // ----------------------------------------------------------------------------------------------------
template<> ejson::Value convertToJson<bool>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const bool& _value) {
return ejson::Boolean(_value); return ejson::Boolean(_value);
} }
template<> ejson::Value convertToJson<std::vector<bool>>(const std::vector<bool>& _value) { template<> ejson::Value convertToJson<std::vector<bool>>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::vector<bool>& _value) {
ejson::Array out; ejson::Array out;
for (const auto &it : _value) { for (const auto &it : _value) {
out.add(ejson::Boolean(it)); out.add(ejson::Boolean(it));
} }
return out; return out;
} }
template<> ejson::Value convertToJson<float>(const float& _value) { template<> ejson::Value convertToJson<float>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const float& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<double>(const double& _value) { template<> ejson::Value convertToJson<double>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const double& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<int64_t>(const int64_t& _value) { template<> ejson::Value convertToJson<int64_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int64_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<int32_t>(const int32_t& _value) { template<> ejson::Value convertToJson<int32_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int32_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<int16_t>(const int16_t& _value) { template<> ejson::Value convertToJson<int16_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int16_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<int8_t>(const int8_t& _value) { template<> ejson::Value convertToJson<int8_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const int8_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<uint64_t>(const uint64_t& _value) { template<> ejson::Value convertToJson<uint64_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint64_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<uint32_t>(const uint32_t& _value) { template<> ejson::Value convertToJson<uint32_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint32_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<uint16_t>(const uint16_t& _value) { template<> ejson::Value convertToJson<uint16_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint16_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<uint8_t>(const uint8_t& _value) { template<> ejson::Value convertToJson<uint8_t>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const uint8_t& _value) {
return ejson::Number(_value); return ejson::Number(_value);
} }
template<> ejson::Value convertToJson<std::string>(const std::string& _value) { template<> ejson::Value convertToJson<std::string>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::string& _value) {
return ejson::String(_value); return ejson::String(_value);
} }
template<> ejson::Value convertToJson<std::vector<std::string>>(const std::vector<std::string>& _value) { template<> ejson::Value convertToJson<char*>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, char* const & _value) {
if (_value == nullptr) {
return ejson::String();
}
return ejson::String(_value);
}
template<> ejson::Value convertToJson<std::vector<std::string>>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const std::vector<std::string>& _value) {
ejson::Array out; ejson::Array out;
for (auto &it : _value) { for (auto &it : _value) {
out.add(ejson::String(it)); out.add(ejson::String(it));
} }
return out; return out;
} }
template<> ejson::Value convertToJson<jus::FileServer>(const jus::FileServer& _value) { template<> ejson::Value convertToJson<jus::FileServer>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const jus::FileServer& _value) {
ejson::Array out; ejson::Array out;
/* /*
for (auto &it : _value) { for (auto &it : _value) {
@ -125,15 +144,63 @@ namespace jus {
*/ */
return out; return out;
} }
template<> ejson::Value convertToJson<jus::File>(const jus::File& _value) {
class SenderJusFile {
private:
jus::File m_data;
uint64_t m_size;
uint64_t m_offset;
int32_t m_paramID;
public:
SenderJusFile(jus::File _data, int32_t _paramID) :
m_data(_data),
m_size(m_data.getData().size()),
m_offset(0),
m_paramID(_paramID) {
}
~SenderJusFile() {
}
bool operator() (TcpString* _interface, const std::string& _service, uint64_t _transactionId, uint64_t _part) {
ejson::Object answer;
if (_service != "") {
answer.add("service", ejson::String(_service));
}
answer.add("id", ejson::Number(_transactionId));
answer.add("part", ejson::Number(_part));
if (m_paramID >= 0) {
answer.add("param-id", ejson::Number(m_paramID));
}
int32_t tmpSize = 1023;
if (m_size < 1023) {
tmpSize = m_size;
}
uint8_t tmpData[1023];
answer.add("data", ejson::String(ejson::base64::encode(&m_data.getData()[m_offset], tmpSize)));
m_offset += tmpSize;
m_size -= tmpSize;
JUS_INFO("data: " << answer.generateHumanString());
_interface->write(answer.generateMachineString());
if (m_size <= 0) {
return true;
}
return false;
}
};
template<> ejson::Value convertToJson<jus::File>(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const jus::File& _value) {
ejson::Object out; ejson::Object out;
out.add("type", ejson::String("file")); out.add("type", ejson::String("file"));
out.add("mine-type", ejson::String(_value.getMineType())); out.add("mine-type", ejson::String(_value.getMineType()));
out.add("size", ejson::Number(_value.getData().size())); out.add("size", ejson::Number(_value.getData().size()));
// TODO : Add extended datas ... if (_value.getData().size() != 0) {
_asyncAction.push_back(SenderJusFile(_value, _paramId));
}
return out; return out;
} }
// ----------------------------------------------------------------------------------------------------
template<> bool convertStringTo<bool>(const std::string& _value) { template<> bool convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value); return etk::string_to_bool(_value);
} }
@ -199,7 +266,7 @@ ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _f
obj.add("id", ejson::Number(_transactionId)); obj.add("id", ejson::Number(_transactionId));
return obj; return obj;
} }
void jus::createParam(ejson::Object& _obj) { void jus::createParam(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, ejson::Object& _obj) {
// Finish recursive parse ... // Finish recursive parse ...
} }

View File

@ -60,6 +60,9 @@ namespace jus {
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0; virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
}; };
// define basic async call element ...
using ActionAsyncClient = std::function<bool(TcpString* _interface, const std::string& _service, uint64_t _transactionId, uint64_t _part)>;
template<class JUS_TYPE> template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value); JUS_TYPE convertStringTo(const std::string& _value);
@ -67,181 +70,51 @@ namespace jus {
JUS_TYPE convertJsonTo(const ejson::Value& _value); JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE> template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value); ejson::Value convertToJson(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const JUS_TYPE& _value);
//ejson::Value convertToJson(std::vector<ActionAsyncClient>& _asyncAction, int32_t _paramId, const char* _value);
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service=""); ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service="");
void createParam(ejson::Object& _obj); void createParam(std::vector<ActionAsyncClient>& _asyncAction,
int32_t _paramId,
ejson::Object& _obj);
template<class... _ARGS> template<class JUS_TYPE, class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args); void createParam(std::vector<ActionAsyncClient>& _asyncAction,
template<class... _ARGS> int32_t _paramId,
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args); ejson::Object& _obj,
template<class... _ARGS> const JUS_TYPE& _param,
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args); _ARGS&&... _args) {
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const jus::File& _param, _ARGS&&... _args);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) { if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array()); _obj.add("param", ejson::Array());
} }
ejson::Array array = _obj["param"].toArray(); ejson::Array array = _obj["param"].toArray();
if (_param == nullptr) { array.add(convertToJson<JUS_TYPE>(_asyncAction, _paramId, _param));
array.add(ejson::String()); _paramId++;
} else { createParam(_asyncAction, _paramId, _obj, std::forward<_ARGS>(_args)...);
array.add(ejson::String(_param));
}
createParam(_obj, std::forward<_ARGS>(_args)...);
} }
// convert const char in std::string ...
template<class... _ARGS> template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args) { void createParam(std::vector<ActionAsyncClient>& _asyncAction,
if (_obj.valueExist("param") == false) { int32_t _paramId,
_obj.add("param", ejson::Array()); ejson::Object& _obj,
} const char* _param,
ejson::Array array = _obj["param"].toArray(); _ARGS&&... _args) {
array.add(ejson::String(_param)); createParam(_asyncAction, _paramId, _obj, std::string(_param), std::forward<_ARGS>(_args)...);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Boolean(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::String(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (const auto& it : _param) {
array2.add(ejson::Boolean(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const jus::File& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(convertToJson<jus::File>(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
} }
template<class... _ARGS> template<class... _ARGS>
ejson::Object createCall(uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) { ejson::Object createCall(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName); ejson::Object callElem = createBaseCall(_transactionId, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(_asyncAction, 0, callElem, std::forward<_ARGS>(_args)...);
return callElem; return callElem;
} }
template<class... _ARGS> template<class... _ARGS>
ejson::Object createCallService(uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) { ejson::Object createCallService(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceName); ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(_asyncAction, 0, callElem, std::forward<_ARGS>(_args)...);
return callElem; return callElem;
} }
ejson::Object createCallJson(uint64_t _transactionId, const std::string& _functionName, ejson::Array _params); ejson::Object createCallJson(uint64_t _transactionId, const std::string& _functionName, ejson::Array _params);

View File

@ -23,19 +23,23 @@ namespace jus {
JUS_CLASS_TYPE* _pointer, JUS_CLASS_TYPE* _pointer,
JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
const ejson::Array& _params) { const ejson::Array& _params) {
std::vector<ActionAsyncClient> asyncAction;
#if defined(__clang__) #if defined(__clang__)
// clang generate a basic warning: // clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced] // warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0; int32_t idParam = 0;
ejson::Value ret = convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...)); ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) #elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1; int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
ejson::Value ret = convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...)); ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else #else
#error Must be implemented ... #error Must be implemented ...
ejson::Value ret = ejson::Null(); ejson::Value ret = ejson::Null();
return; return;
#endif #endif
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
ejson::Object answer; ejson::Object answer;
answer.add("id", ejson::Number(_transactionId)); answer.add("id", ejson::Number(_transactionId));
answer.add("client-id", ejson::Number(_clientId)); answer.add("client-id", ejson::Number(_clientId));

View File

@ -164,7 +164,53 @@ uint64_t jus::Client::getId() {
return m_id++; return m_id++;
} }
jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) { class SendAsync {
private:
std::vector<jus::ActionAsyncClient> m_async;
uint64_t m_transactionId;
std::string m_service;
uint32_t m_partId;
public:
SendAsync(uint64_t _transactionId, const std::string& _service, const std::vector<jus::ActionAsyncClient>& _async) :
m_async(_async),
m_transactionId(_transactionId),
m_service(_service),
m_partId(1) {
}
bool operator() (jus::TcpString* _interface){
auto it = m_async.begin();
while (it != m_async.end()) {
bool ret = (*it)(_interface, m_service, m_transactionId, m_partId);
if (ret == true) {
// Remove it ...
it = m_async.erase(it);
} else {
++it;
}
m_partId++;
}
if (m_async.size() == 0) {
ejson::Object obj;
if (m_service != "") {
obj.add("service", ejson::String(m_service));
}
obj.add("id", ejson::Number(m_transactionId));
obj.add("part", ejson::Number(m_partId));
obj.add("finish", ejson::Boolean(true));
JUS_DEBUG("Send JSON '" << obj.generateHumanString() << "'");
_interface->write(obj.generateMachineString());
return true;
}
return false;
}
};
jus::FutureBase jus::Client::callJson(uint64_t _transactionId,
ejson::Object _obj,
const std::vector<ActionAsyncClient>& _async,
jus::FutureData::ObserverFinish _callback,
const std::string& _service) {
JUS_VERBOSE("Send JSON [START] "); JUS_VERBOSE("Send JSON [START] ");
if (m_interfaceClient.isActive() == false) { if (m_interfaceClient.isActive() == false) {
ejson::Object obj; ejson::Object obj;
@ -177,8 +223,15 @@ jus::FutureBase jus::Client::callJson(uint64_t _transactionId, const ejson::Obje
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture); m_pendingCall.push_back(tmpFuture);
} }
if (_async.size() != 0) {
_obj.add("part", ejson::Number(0));
}
JUS_DEBUG("Send JSON '" << _obj.generateHumanString() << "'"); JUS_DEBUG("Send JSON '" << _obj.generateHumanString() << "'");
m_interfaceClient.write(_obj.generateMachineString()); m_interfaceClient.write(_obj.generateMachineString());
if (_async.size() != 0) {
m_interfaceClient.addAsync(SendAsync(_transactionId, _service, _async));
}
JUS_VERBOSE("Send JSON [STOP]"); JUS_VERBOSE("Send JSON [STOP]");
return tmpFuture; return tmpFuture;
} }

View File

@ -43,20 +43,26 @@ namespace jus {
private: private:
void onClientData(std::string _value); void onClientData(std::string _value);
std::string asyncRead(); std::string asyncRead();
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr); jus::FutureBase callJson(uint64_t _transactionId,
ejson::Object _obj,
const std::vector<ActionAsyncClient>& _async,
jus::FutureData::ObserverFinish _callback=nullptr,
const std::string& _service="");
public: public:
uint64_t getId(); uint64_t getId();
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) { jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncAction;
return callJson(id, callElem); ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncAction);
} }
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) { jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncAction;
return callJson(id, callElem, _callback); ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncAction, _callback);
} }
private: private:
void onPropertyChangeIp(); void onPropertyChangeIp();

View File

@ -4,8 +4,11 @@
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */
#include <jus/File.h> #include <jus/File.h>
#include <jus/debug.h>
#include <etk/types.h> #include <etk/types.h>
#include <etk/stdTools.h> #include <etk/stdTools.h>
#include <jus/mineType.h>
#include <etk/os/FSNode.h>
@ -14,7 +17,14 @@ jus::File::File() {
} }
jus::File::File(const std::string& _filename) { jus::File::File(const std::string& _filename) {
m_data = etk::FSNodeReadAllDataType<uint8_t>(_filename);
std::string extention = std::string(_filename.begin()+_filename.size() -3, _filename.end());
JUS_WARNING("send file: '" << _filename << "' with extention: '" << extention << "'");
m_mineType = jus::getMineType(extention);
}
void jus::File::storeIn(const std::string& _filename) const {
etk::FSNodeWriteAllDataType(_filename, m_data);
} }
jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data): jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data):

View File

@ -15,6 +15,7 @@ namespace jus {
File(); File();
File(const std::string& _filename); File(const std::string& _filename);
File(const std::string& _mineType, std::vector<uint8_t> _data); File(const std::string& _mineType, std::vector<uint8_t> _data);
void storeIn(const std::string& _filename) const;
const std::string& getMineType() const { const std::string& getMineType() const {
return m_mineType; return m_mineType;
} }

View File

@ -219,9 +219,10 @@ void jus::FutureCall::appendData(const ejson::Object& _callValue) {
if (param.valueExist("data") == false) { if (param.valueExist("data") == false) {
param.add("data", ejson::Array()); param.add("data", ejson::Array());
} }
// add data in the array // add data in the array (only if we have local data ...
if (_callValue.valueExist("data") == true) {
param["data"].toArray().add(_callValue["data"]); param["data"].toArray().add(_callValue["data"]);
}
if (_callValue.valueExist("finish") == true) { if (_callValue.valueExist("finish") == true) {
if (_callValue["finish"].toBoolean().get() == true) { if (_callValue["finish"].toBoolean().get() == true) {
m_isFinished = true; m_isFinished = true;

View File

@ -83,7 +83,7 @@ void jus::GateWayClient::returnBool(int32_t _transactionId, bool _value) {
void jus::GateWayClient::onClientData(std::string _value) { void jus::GateWayClient::onClientData(std::string _value) {
JUS_DEBUG("On data: " << _value); JUS_DEBUG("On data: " << _value);
ejson::Object data(_value); ejson::Object data(_value);
int32_t transactionId = data["id"].toNumber().get(); uint64_t transactionId = data["id"].toNumber().getU64();
if (transactionId == 0) { if (transactionId == 0) {
JUS_ERROR("Protocol error ==>missing id"); JUS_ERROR("Protocol error ==>missing id");
protocolError("missing parameter: 'id'"); protocolError("missing parameter: 'id'");
@ -274,7 +274,12 @@ void jus::GateWayClient::onClientData(std::string _value) {
linkService.add("event", ejson::String("new")); linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName)); linkService.add("user", ejson::String(m_userConnectionName));
linkService.add("client", ejson::String(m_clientName)); linkService.add("client", ejson::String(m_clientName));
linkService.add("groups", convertToJson(m_clientgroups)); // TODO ==> remove events ...
std::vector<ActionAsyncClient> asyncAction;
linkService.add("groups", convertToJson(asyncAction, 0, m_clientgroups));
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
srv->SendData(m_uid, linkService); srv->SendData(m_uid, linkService);
m_listConnectedService.push_back(srv); m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true)); answer.add("return", ejson::Boolean(true));
@ -351,7 +356,43 @@ void jus::GateWayClient::onClientData(std::string _value) {
JUS_DEBUG("answer: " << answer.generateHumanString()); JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString()); m_interfaceClient.write(answer.generateMachineString());
} else { } else {
bool finish = false;
if (data.valueExist("finish") == true) {
finish = data["finish"].toBoolean().get();
}
int64_t partTmp = -1;
if (data.valueExist("part") == true) {
uint64_t part = data["part"].toNumber().getU64();
partTmp = part;
if (part != 0) {
// subMessage ... ==> try to forward message:
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &itCall : m_pendingCall) {
JUS_INFO(" compare : " << itCall.first << " =?= " << transactionId);
if (itCall.first == transactionId) {
// Find element ==> transit it ...
if (*it == nullptr) {
// TODO ...
} else {
ejson::Object obj;
obj.add("id", ejson::Number(itCall.second.getTransactionId()));
obj.add("param-id", data["param-id"]);
obj.add("part", ejson::Number(part));
obj.add("data", data["data"]);
if (finish == true) {
obj.add("finish", ejson::Boolean(true));
}
(*it)->SendData(m_uid, obj);
}
return;
}
}
JUS_ERROR("Can not transfer part of a message ...");
return;
}
}
callActionForward(m_uid, callActionForward(m_uid,
transactionId,
*it, *it,
data["call"].toString().get(), data["call"].toString().get(),
data["param"].toArray(), data["param"].toArray(),
@ -359,7 +400,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
ejson::Object tmpp = _ret.getRaw(); ejson::Object tmpp = _ret.getRaw();
JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64()); JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64());
JUS_VERBOSE(" msg=" << tmpp.generateMachineString()); JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
tmpp["id"].toNumber().set(data["id"].toNumber().getU64()); tmpp["id"].toNumber().set(transactionId);
JUS_DEBUG("transmit=" << tmpp.generateMachineString()); JUS_DEBUG("transmit=" << tmpp.generateMachineString());
m_interfaceClient.write(tmpp.generateMachineString()); m_interfaceClient.write(tmpp.generateMachineString());
if (tmpp.valueExist("part") == true) { if (tmpp.valueExist("part") == true) {
@ -370,16 +411,31 @@ void jus::GateWayClient::onClientData(std::string _value) {
return false; return false;
} }
return true; return true;
}); },
partTmp,
finish);
} }
} }
} }
} }
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback) { jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId,
uint64_t _clientTransactionId,
ememory::SharedPtr<jus::GateWayService> _srv,
const std::string& _functionName,
ejson::Array _params,
jus::FutureData::ObserverFinish _callback,
int64_t _part,
bool _finish) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCallJson(id, _functionName, _params); ejson::Object callElem = jus::createCallJson(id, _functionName, _params);
jus::FutureBase ret = callJson(_callerId, _srv, id, callElem, _callback); if (_part != -1) {
callElem.add("part", ejson::Number(uint64_t(_part)));
}
if (_finish == true) {
callElem.add("finish", ejson::Boolean(true));
}
jus::FutureBase ret = callJson(_callerId, _srv, _clientTransactionId, id, callElem, _callback);
ret.setSynchronous(); ret.setSynchronous();
return ret; return ret;
} }
@ -388,7 +444,7 @@ uint64_t jus::GateWayClient::getId() {
return m_transactionLocalId++; return m_transactionLocalId++;
} }
jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) { jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _clientTransactionId, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) {
JUS_VERBOSE("Send JSON [START] "); JUS_VERBOSE("Send JSON [START] ");
if (_srv == nullptr) { if (_srv == nullptr) {
ejson::Object obj; ejson::Object obj;
@ -399,7 +455,7 @@ jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::Shared
jus::FutureBase tmpFuture(_transactionId, _callback); jus::FutureBase tmpFuture(_transactionId, _callback);
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture); m_pendingCall.push_back(std::make_pair(_clientTransactionId, tmpFuture));
} }
_srv->SendData(_callerId, _obj); _srv->SendData(_callerId, _obj);
JUS_VERBOSE("Send JSON [STOP]"); JUS_VERBOSE("Send JSON [STOP]");
@ -416,10 +472,10 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
JUS_ERROR("Get a Protocol error ..."); JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) { for (auto &it : m_pendingCall) {
if (it.isValid() == false) { if (it.second.isValid() == false) {
continue; continue;
} }
it.setAnswer(_data); it.second.setAnswer(_data);
} }
m_pendingCall.clear(); m_pendingCall.clear();
} else { } else {
@ -431,16 +487,16 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin(); auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) { while (it != m_pendingCall.end()) {
if (it->isValid() == false) { if (it->second.isValid() == false) {
it = m_pendingCall.erase(it); it = m_pendingCall.erase(it);
continue; continue;
} }
if (it->getTransactionId() != tid) { if (it->second.getTransactionId() != tid) {
++it; ++it;
continue; continue;
} }
// TODO : Do it better ... // TODO : Do it better ...
future = *it; future = it->second;
break; break;
} }
} }
@ -453,11 +509,11 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin(); auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) { while (it != m_pendingCall.end()) {
if (it->isValid() == false) { if (it->second.isValid() == false) {
it = m_pendingCall.erase(it); it = m_pendingCall.erase(it);
continue; continue;
} }
if (it->getTransactionId() != tid) { if (it->second.getTransactionId() != tid) {
++it; ++it;
continue; continue;
} }

View File

@ -57,24 +57,39 @@ namespace jus {
private: private:
std::mutex m_mutex; std::mutex m_mutex;
std::vector<jus::FutureBase> m_pendingCall; std::vector<std::pair<uint64_t, jus::FutureBase>> m_pendingCall;
int32_t m_transactionLocalId; int32_t m_transactionLocalId;
jus::FutureBase callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr); jus::FutureBase callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _clientTransactionId, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
uint64_t getId(); uint64_t getId();
public: public:
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase call(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args) { jus::FutureBase call(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncAction;
return callJson(_callerId, _srv, id, callElem); ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
}
return callJson(_callerId, _srv, 0, id, callElem);
} }
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase callAction(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) { jus::FutureBase callAction(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncAction;
return callJson(_callerId, _srv, id, callElem, _callback); ejson::Object callElem = jus::createCall(asyncAction, id, _functionName, std::forward<_ARGS>(_args)...);
if (asyncAction.size() != 0) {
JUS_ERROR("Missing send async messages");
} }
jus::FutureBase callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback); return callJson(_callerId, _srv, 0, id, callElem, _callback);
}
jus::FutureBase callActionForward(uint64_t _callerId,
uint64_t _clientTransactionId,
ememory::SharedPtr<jus::GateWayService> _srv,
const std::string& _functionName,
ejson::Array _params,
jus::FutureData::ObserverFinish _callback,
int64_t _part,
bool _finish);
}; };
} }

View File

@ -43,8 +43,10 @@ void jus::Service::onClientData(std::string _value) {
while (it != m_callMultiData.end()) { while (it != m_callMultiData.end()) {
if ( it->getTransactionId() == tmpID if ( it->getTransactionId() == tmpID
&& it->getClientId() == clientId) { && it->getClientId() == clientId) {
JUS_WARNING("Append data ... " << tmpID);
it->appendData(request); it->appendData(request);
if (it->isFinished() == true) { if (it->isFinished() == true) {
JUS_WARNING("CALL Function ...");
callJson(tmpID, it->getRaw()); callJson(tmpID, it->getRaw());
it = m_callMultiData.erase(it); it = m_callMultiData.erase(it);
} }

View File

@ -28,7 +28,10 @@ uint64_t jus::ServiceRemote::getId() {
return m_clientInterface->getId(); return m_clientInterface->getId();
} }
jus::FutureBase jus::ServiceRemote::callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback) { jus::FutureBase jus::ServiceRemote::callJson(uint64_t _transactionId,
return m_clientInterface->callJson(_transactionId, _obj, _callback); const ejson::Object& _obj,
const std::vector<ActionAsyncClient>& _async,
jus::FutureData::ObserverFinish _callback) {
return m_clientInterface->callJson(_transactionId, _obj, _async, _callback, m_name);
} }

View File

@ -25,20 +25,22 @@ namespace jus {
~ServiceRemote(); ~ServiceRemote();
bool exist(); bool exist();
private: private:
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr); jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, const std::vector<ActionAsyncClient>& _async, jus::FutureData::ObserverFinish _callback=nullptr);
uint64_t getId(); uint64_t getId();
public: public:
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) { jus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncActionToDo;
return callJson(id, callElem); ejson::Object callElem = jus::createCallService(asyncActionToDo, id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncActionToDo);
} }
template<class... _ARGS> template<class... _ARGS>
jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) { jus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args, jus::FutureData::ObserverFinish _callback) {
uint64_t id = getId(); uint64_t id = getId();
ejson::Object callElem = jus::createCallService(id, m_name, _functionName, std::forward<_ARGS>(_args)...); std::vector<ActionAsyncClient> asyncActionToDo;
return callJson(id, callElem, _callback); ejson::Object callElem = jus::createCallService(asyncActionToDo, id, m_name, _functionName, std::forward<_ARGS>(_args)...);
return callJson(id, callElem, asyncActionToDo, _callback);
} }
}; };
} }

View File

@ -86,6 +86,7 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO("serviceTest1.mul = " << retCall); APPL_INFO("serviceTest1.mul = " << retCall);
} }
*/ */
if (false) {
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service system-user"); APPL_INFO(" -- Get service system-user");
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
@ -134,13 +135,14 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO(" IO*=" << int64_t((stop-start).count()/1000)/1000.0 << " ms"); APPL_INFO(" IO*=" << int64_t((stop-start).count()/1000)/1000.0 << " ms");
} }
} }
}
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service picture"); APPL_INFO(" -- Get service picture");
APPL_INFO(" ----------------------------------"); APPL_INFO(" ----------------------------------");
jus::ServiceRemote remoteServicePicture = client1.getService("picture"); jus::ServiceRemote remoteServicePicture = client1.getService("picture");
if (remoteServicePicture.exist() == true) { if (remoteServicePicture.exist() == true) {
/*
jus::Future<std::vector<std::string>> retCall = remoteServicePicture.call("getAlbums").wait(); jus::Future<std::vector<std::string>> retCall = remoteServicePicture.call("getAlbums").wait();
APPL_INFO(" album list: "); APPL_INFO(" album list: ");
for (auto &it : retCall.get()) { for (auto &it : retCall.get()) {
@ -179,7 +181,8 @@ int main(int _argc, const char *_argv[]) {
} }
} }
} }
jus::File tmp("image/jpg", {0,5,2,6,7,5,8,4,5,2,1,5,65,5,2,6,85,4,6,6,54,65,88,64,14,6,4,64,51,3,16,4}); */
jus::File tmp("./photo_2016_33913.bmp");//"image/jpg", {0,5,2,6,7,5,8,4,5,2,1,5,65,5,2,6,85,4,6,6,54,65,88,64,14,6,4,64,51,3,16,4});
jus::FutureBase retSendImage = remoteServicePicture.call("addFile", tmp).wait(); jus::FutureBase retSendImage = remoteServicePicture.call("addFile", tmp).wait();
} }

View File

@ -235,7 +235,8 @@ namespace appl {
} }
} }
*/ */
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType()); APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType() << " size=" << _dataFile.getData().size());
_dataFile.storeIn("plopppp.bmp");
return "54654654654654";//jus::FileServer(); return "54654654654654";//jus::FileServer();
} }
/* /*