[DEV] receive all data from a file in multiple messages

This commit is contained in:
Edouard DUPIN 2016-06-02 21:41:05 +02:00
parent e0861c66ac
commit cf72ad71fb
19 changed files with 517 additions and 71 deletions

View File

@ -56,6 +56,15 @@ namespace jus {
}
return out;
}
template<> jus::File convertJsonTo<jus::File>(const ejson::Value& _value) {
ejson::Object obj = _value.toObject();
jus::File out;
out.setMineType(obj["mine-type"].toString().get());
out.preSetDataSize(obj["size"].toNumber().getU64());
//out.add("type", ejson::String("file"));
// TODO : Add extended datas ...
return out;
}
template<> ejson::Value convertToJson<bool>(const bool& _value) {
return ejson::Boolean(_value);
@ -116,6 +125,14 @@ namespace jus {
*/
return out;
}
template<> ejson::Value convertToJson<jus::File>(const jus::File& _value) {
ejson::Object out;
out.add("type", ejson::String("file"));
out.add("mine-type", ejson::String(_value.getMineType()));
out.add("size", ejson::Number(_value.getData().size()));
// TODO : Add extended datas ...
return out;
}
template<> bool convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value);
@ -161,6 +178,9 @@ namespace jus {
template<> jus::FileServer convertStringTo<jus::FileServer>(const std::string& _value) {
return jus::FileServer();
}
template<> jus::File convertStringTo<jus::File>(const std::string& _value) {
return jus::File();
}
}
@ -278,6 +298,14 @@ bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejs
}
return _params.isArray();
}
if (createType<jus::File>() == _type) {
if (_params.isObject()) {
if (_params.toObject()["type"].toString().get() == "file") {
return true;
}
}
return false;
}
if (createType<std::string>() == _type) {
return _params.isString();
}

View File

@ -96,6 +96,8 @@ namespace jus {
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) {
@ -220,6 +222,15 @@ namespace jus {
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>
ejson::Object createCall(uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) {

View File

@ -10,6 +10,11 @@
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/AbstractFunction.h>
#include <jus/mineType.h>
#include <etk/os/FSNode.h>
#include <ejson/base64.h>
namespace jus {
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
void executeClassCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
@ -38,8 +43,71 @@ namespace jus {
JUS_INFO("Answer: " << answer.generateHumanString());
_interfaceClient->write(answer.generateMachineString());
}
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
class SendFile {
private:
jus::FileServer m_data;
uint64_t m_transactionId;
uint64_t m_clientId;
uint32_t m_partId;
etk::FSNode m_node;
uint64_t m_size;
public:
SendFile(jus::FileServer _data,
uint64_t _transactionId,
uint64_t _clientId) :
m_data(_data),
m_transactionId(_transactionId),
m_clientId(_clientId),
m_partId(0),
m_node(_data.getFileName()),
m_size(0) {
}
~SendFile() {
//m_node.fileClose();
}
bool operator() (TcpString* _interface) {
ejson::Object answer;
answer.add("id", ejson::Number(m_transactionId));
answer.add("client-id", ejson::Number(m_clientId));
answer.add("part", ejson::Number(m_partId));
if (m_partId == 0) {
m_node.fileOpenRead();
ejson::Object file;
file.add("type", ejson::String("file"));
std::string extention = std::string(m_data.getFileName().begin()+m_data.getFileName().size() -3, m_data.getFileName().end());
JUS_WARNING("send file: '" << m_data.getFileName() << "' with extention: '" << extention << "'");
file.add("mine-type", ejson::String(jus::getMineType(extention)));
m_size = m_node.fileSize();
file.add("size", ejson::Number(m_size));
answer.add("return", file);
JUS_INFO("Answer: " << answer.generateHumanString());
_interface->write(answer.generateMachineString());
m_partId++;
return false;
}
int32_t tmpSize = 1024;
if (m_size < 1024) {
tmpSize = m_size;
}
uint8_t tmpData[1024];
m_node.fileRead(tmpData, 1, tmpSize);
answer.add("data", ejson::String(ejson::base64::encode(tmpData, tmpSize)));
m_size -= tmpSize;
if (m_size <= 0) {
answer.add("finish", ejson::Boolean(true));
m_node.fileClose();
}
JUS_INFO("Answer: " << answer.generateHumanString());
_interface->write(answer.generateMachineString());
m_partId++;
if (m_size <= 0) {
return true;
}
return false;
}
};
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
void executeClassCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
uint64_t _transactionId,
uint64_t _clientId,
@ -59,7 +127,7 @@ namespace jus {
jus::FileServer tmpElem;
return;
#endif
JUS_ERROR("Must be implemented in a worker ...");
_interfaceClient->addAsync(SendFile(tmpElem, _transactionId, _clientId));
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>

View File

@ -21,10 +21,10 @@ namespace jus {
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
ejson::Value ret = convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
ejson::Value ret = jus::convertToJson(_func((jus::convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
ejson::Value ret = convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
ejson::Value ret = jus::convertToJson(_func(jus::convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
ejson::Value ret = ejson::Null();
@ -48,10 +48,10 @@ namespace jus {
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
_func((jus::convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
_func(jus::convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
@ -64,7 +64,6 @@ namespace jus {
_interface->write(answer.generateMachineString());
return true;
});
}
}
template <class JUS_RETURN, class... JUS_TYPES>
@ -73,10 +72,10 @@ namespace jus {
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return etk::to_string(_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
return etk::to_string(_func((jus::convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return etk::to_string(_func(convertStringTo<JUS_TYPES>(_params[idParam--])...));
return etk::to_string(_func(jus::convertStringTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
@ -89,10 +88,10 @@ namespace jus {
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
_func((jus::convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertStringTo<JUS_TYPES>(_params[idParam--])...);
_func(jus::convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif

View File

@ -25,24 +25,24 @@ void jus::Client::onClientData(std::string _value) {
JUS_DEBUG("Get answer : " << _value);
ejson::Object obj(_value);
jus::FutureBase future;
{
uint64_t tid = obj["id"].toNumber().get();
if (tid == 0) {
if (obj["error"].toString().get() == "PROTOCOL-ERROR") {
JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) {
if (it.isValid() == false) {
continue;
}
it.setAnswer(obj);
uint64_t tid = obj["id"].toNumber().get();
if (tid == 0) {
if (obj["error"].toString().get() == "PROTOCOL-ERROR") {
JUS_ERROR("Get a Protocol error ...");
std::unique_lock<std::mutex> lock(m_mutex);
for (auto &it : m_pendingCall) {
if (it.isValid() == false) {
continue;
}
m_pendingCall.clear();
} else {
JUS_ERROR("call with no ID ==> error ...");
it.setAnswer(obj);
}
return;
m_pendingCall.clear();
} else {
JUS_ERROR("call with no ID ==> error ...");
}
return;
}
{
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
@ -55,16 +55,31 @@ void jus::Client::onClientData(std::string _value) {
continue;
}
future = *it;
it = m_pendingCall.erase(it);
break;
}
}
if (future.isValid() == false) {
JUS_TODO("manage this event better ...");
m_newData.push_back(std::move(_value));
//m_newData.push_back(std::move(_value));
return;
}
future.setAnswer(obj);
bool ret = future.setAnswer(obj);
if (ret == true) {
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
if (it->isValid() == false) {
it = m_pendingCall.erase(it);
continue;
}
if (it->getTransactionId() != tid) {
++it;
continue;
}
it = m_pendingCall.erase(it);
break;
}
}
}
jus::ServiceRemote jus::Client::getService(const std::string& _name) {

View File

@ -17,14 +17,24 @@ jus::File::File(const std::string& _filename) {
}
jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data) {
jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data):
m_mineType(_mineType),
m_data(_data) {
}
void jus::File::setData(uint64_t _offset, const std::vector<uint8_t>& _data) {
// TODO : Check size/offset before set
memcpy(&m_data[_offset], &_data[0], _data.size());
}
jus::FileServer::FileServer() {
}
jus::FileServer::FileServer(const std::string& _filename) {
m_name = _filename;
jus::FileServer::FileServer(const std::string& _filename) :
m_name(_filename) {
}

View File

@ -15,12 +15,19 @@ namespace jus {
File();
File(const std::string& _filename);
File(const std::string& _mineType, std::vector<uint8_t> _data);
const std::string& getMineType() {
const std::string& getMineType() const {
return m_mineType;
}
const std::vector<uint8_t>& getData() {
void setMineType(const std::string& _type) {
m_mineType = _type;
}
void preSetDataSize(uint64_t _size) {
m_data.resize(_size, 0);
}
const std::vector<uint8_t>& getData() const {
return m_data;
}
void setData(uint64_t _offset, const std::vector<uint8_t>& _data);
};
class FileServer {
private:
@ -28,6 +35,9 @@ namespace jus {
public:
FileServer();
FileServer(const std::string& _filename);
const std::string& getFileName() {
return m_name;
}
};
}

View File

@ -7,6 +7,7 @@
#include <jus/debug.h>
#include <unistd.h>
#include <jus/File.h>
#include <ejson/base64.h>
namespace jus {
template<>
@ -495,25 +496,32 @@ namespace jus {
if (m_data == nullptr) {
return out;
}
// TODO :...
/*
ejson::Value val = m_data->m_returnData["return"];
if (val.exist() == false) {
JUS_WARNING("No Return value ...");
return out;
}
if (val.isArray() == false) {
JUS_WARNING("Wrong return Type get '" << val.getType() << " instead of 'Array'");
if (val.isObject() == false) {
JUS_WARNING("Wrong return Type get '" << val.getType() << " instead of 'Object'");
return out;
}
for (auto it : val.toArray()) {
if (it.isBoolean() == false) {
JUS_WARNING("Wrong return Type (part of array) get '" << it.getType() << " instead of 'Boolean'");
continue;
}
out.push_back(it.toBoolean().get());
ejson::Object retVal = val.toObject();
if (retVal["type"].toString().get() != "file") {
JUS_WARNING("Wrong return object-type get '" << retVal["type"].toString().get() << " instead of 'file'");
return out;
}
out.setMineType(retVal["mine-type"].toString().get());
out.preSetDataSize(retVal["size"].toNumber().getU64());
// no data might be stored in the first packet ...
uint64_t offset = 0;
// TODO: check part ID
for (auto &it : m_data->m_returnDataPart) {
ejson::String valData = it.toString();
std::vector<uint8_t> tmpData = ejson::base64::decode(valData.get());
out.setData(offset, tmpData);
offset += tmpData.size();
}
*/
return out;
}
}

View File

@ -182,3 +182,69 @@ jus::FutureBase& jus::FutureBase::waitUntil(std::chrono::steady_clock::time_poin
return *this;
}
jus::FutureCall::FutureCall(uint64_t _clientId, uint64_t _transactionId, const ejson::Object& _callValue) :
m_transactionId(_transactionId),
m_clientId(_clientId),
m_isFinished(false) {
m_data = _callValue;
if (m_data.valueExist("part") == true) {
if (m_data.valueExist("finish") == true) {
if (m_data["finish"].toBoolean().get() == true) {
m_isFinished = true;
}
}
} else {
m_isFinished = true;
}
}
void jus::FutureCall::appendData(const ejson::Object& _callValue) {
uint64_t paramID = _callValue["param-id"].toNumber().getU64();
// get the previous element parameters
ejson::Array params = m_data["param"].toArray();
if (params.exist() == false) {
JUS_ERROR("try to add element on an inexistand parameter ...==> bad case");
m_isFinished = true;
return;
}
// Get the specific parameter
ejson::Object param = params[paramID].toObject();
if (param.exist() == false) {
JUS_ERROR("the parameter is not an object ==> bad case");
m_isFinished = true;
return;
}
// check if section data
if (param.valueExist("data") == false) {
param.add("data", ejson::Array());
}
// add data in the array
param["data"].toArray().add(_callValue["data"]);
if (_callValue.valueExist("finish") == true) {
if (_callValue["finish"].toBoolean().get() == true) {
m_isFinished = true;
}
}
}
uint64_t jus::FutureCall::getTransactionId() {
return m_transactionId;
}
uint64_t jus::FutureCall::getClientId() {
return m_clientId;
}
bool jus::FutureCall::isFinished() {
return m_isFinished;
}
ejson::Object jus::FutureCall::getRaw() {
return m_data;
}
std::chrono::nanoseconds jus::FutureCall::getTransmitionTime() {
return m_answerTime - m_receiveTime;
}

View File

@ -31,5 +31,22 @@ namespace jus {
ejson::Object getRaw();
std::chrono::nanoseconds getTransmitionTime();
};
class FutureCall {
private:
uint64_t m_transactionId;
uint64_t m_clientId;
bool m_isFinished;
ejson::Object m_data;
std::chrono::steady_clock::time_point m_receiveTime;
std::chrono::steady_clock::time_point m_answerTime;
public:
FutureCall(uint64_t _clientId, uint64_t _transactionId, const ejson::Object& _callValue);
void appendData(const ejson::Object& _callValue);
uint64_t getTransactionId();
uint64_t getClientId();
bool isFinished();
std::chrono::nanoseconds getTransmitionTime();
ejson::Object getRaw();
};
}

View File

@ -360,7 +360,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64());
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
tmpp["id"].toNumber().set(data["id"].toNumber().getU64());
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
JUS_DEBUG("transmit=" << tmpp.generateMachineString());
m_interfaceClient.write(tmpp.generateMachineString());
if (tmpp.valueExist("part") == true) {
// multiple send element ...

View File

@ -35,19 +35,29 @@ std::vector<std::string> jus::Service::getExtention() {
void jus::Service::onClientData(std::string _value) {
JUS_INFO("Request: " << _value);
ejson::Object request(_value);
uint64_t tmpID = request["id"].toNumber().getU64();
//request.remove("id");
JUS_INFO("Request: " << _value);
callJson(tmpID, request);
/*
// check if an answer is needed
if (answer.isNull() == false) {
answer.toObject().add("id", tmpID);
JUS_INFO("Answer: " << answer.generateHumanString());
m_interfaceClient->write(answer.generateMachineString());
uint64_t clientId = request["client-id"].toNumber().getU64();
auto it = m_callMultiData.begin();
while (it != m_callMultiData.end()) {
if ( it->getTransactionId() == tmpID
&& it->getClientId() == clientId) {
it->appendData(request);
if (it->isFinished() == true) {
callJson(tmpID, it->getRaw());
it = m_callMultiData.erase(it);
}
return;
}
++it;
}
jus::FutureCall futCall(clientId, tmpID, request);
if (futCall.isFinished() == true) {
callJson(tmpID, futCall.getRaw());
} else {
m_callMultiData.push_back(futCall);
}
*/
}
void jus::Service::onPropertyChangeIp() {

View File

@ -12,6 +12,7 @@
#include <jus/AbstractFunctionTypeClass.h>
#include <jus/debug.h>
#include <jus/RemoteProcessCall.h>
#include <jus/Future.h>
namespace jus {
class ClientProperty {
@ -61,6 +62,7 @@ namespace jus {
ememory::SharedPtr<jus::TcpString> m_interfaceClient;
uint32_t m_id;
std::vector<std::string> m_newData;
std::vector<jus::FutureCall> m_callMultiData;
public:
Service();
virtual ~Service();

View File

@ -149,13 +149,20 @@ std::string jus::TcpString::read() {
m_threadRunning = false;
//m_connection.unlink();
} else {
int64_t offset = 0;
out.resize(size);
len = m_connection.read(&out[0], size);
if (len == 0) {
JUS_WARNING("Read No data");
} else if (len != size) {
// TODO do it again ...
JUS_ERROR("Protocol error occured .2.");
while (offset != size) {
len = m_connection.read(&out[offset], size-offset);
offset += len;
if (len == 0) {
JUS_WARNING("Read No data");
//break;
}
/*
else if (size != offset) {
JUS_ERROR("Protocol error occured .2. ==> concat (offset=" << offset << " size=" << size);
}
*/
}
}
}
@ -176,7 +183,7 @@ void jus::TcpString::threadAsyncCallback() {
std::unique_lock<std::mutex> lock(m_threadAsyncMutex);
auto it = m_threadAsyncList.begin();
while (it != m_threadAsyncList.end()) {
bool ret = m_threadAsyncList(this);
bool ret = (*it)(this);
if (ret == true) {
// Remove it ...
it = m_threadAsyncList.erase(it);
@ -184,13 +191,6 @@ void jus::TcpString::threadAsyncCallback() {
++it;
}
}
JUS_VERBOSE("Receive data: '" << data << "'");
if (data.size() != 0) {
m_lastReceive = std::chrono::steady_clock::now();
if (m_obsercerElement != nullptr) {
m_obsercerElement(std::move(data));
}
}
}
m_threadRunning = false;
JUS_DEBUG("End of thread");

134
jus/mineType.cpp Normal file
View File

@ -0,0 +1,134 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <jus/mineType.h>
#include <jus/debug.h>
static std::vector<std::pair<std::string, std::string>> mineList = {
/* Video files */
{ "asf", "video/x-ms-asf"},
{ "avc", "video/avi"},
{ "avi", "video/avi"},
{ "dv", "video/x-dv"},
{ "divx", "video/avi"},
{ "wmv", "video/x-ms-wmv"},
{ "mjpg", "video/x-motion-jpeg"},
{ "mjpeg", "video/x-motion-jpeg"},
{ "mpeg", "video/mpeg"},
{ "mpg", "video/mpeg"},
{ "mpe", "video/mpeg"},
{ "mp2p", "video/mp2p"},
{ "vob", "video/mp2p"},
{ "mp2t", "video/mp2t"},
{ "m1v", "video/mpeg"},
{ "m2v", "video/mpeg2"},
{ "mpg2", "video/mpeg2"},
{ "mpeg2", "video/mpeg2"},
{ "m4v", "video/mp4"},
{ "m4p", "video/mp4"},
{ "mp4ps", "video/x-nerodigital-ps"},
{ "ts", "video/mpeg2"},
{ "ogm", "video/mpeg"},
{ "mkv", "video/x-matroska"},
{ "rmvb", "video/mpeg"},
{ "mov", "video/quicktime"},
{ "hdmov", "video/quicktime"},
{ "qt", "video/quicktime"},
{ "bin", "video/mpeg2"},
{ "iso", "video/mpeg2"},
/* Audio files */
{ "3gp", "audio/3gpp"},
{ "aac", "audio/x-aac"},
{ "ac3", "audio/x-ac3"},
{ "aif", "audio/aiff"},
{ "aiff", "audio/aiff"},
{ "at3p", "audio/x-atrac3"},
{ "au", "audio/basic"},
{ "snd", "audio/basic"},
{ "dts", "audio/x-dts"},
{ "rmi", "audio/midi"},
{ "mid", "audio/midi"},
{ "mp1", "audio/mp1"},
{ "mp2", "audio/mp2"},
{ "mp3", "audio/mpeg"},
{ "mp4", "audio/mp4"},
{ "m4a", "audio/mp4"},
{ "mka", "audio/x-matroska"},
{ "ogg", "audio/x-ogg"},
{ "wav", "audio/wav"},
{ "pcm", "audio/l16"},
{ "lpcm", "audio/l16"},
{ "l16", "audio/l16"},
{ "wma", "audio/x-ms-wma"},
{ "mka", "audio/x-matroska"},
{ "ra", "audio/x-pn-realaudio"},
{ "rm", "audio/x-pn-realaudio"},
{ "ram", "audio/x-pn-realaudio"},
{ "flac", "audio/x-flac"},
/* Images files */
{ "bmp", "image/bmp"},
{ "ico", "image/x-icon"},
{ "gif", "image/gif"},
{ "jpg", "image/jpeg"},
{ "jpeg", "image/jpeg"},
{ "jpe", "image/jpeg"},
{ "pcd", "image/x-ms-bmp"},
{ "png", "image/png"},
{ "pnm", "image/x-portable-anymap"},
{ "ppm", "image/x-portable-pixmap"},
{ "qti", "image/x-quicktime"},
{ "qtf", "image/x-quicktime"},
{ "qtif", "image/x-quicktime"},
{ "tif", "image/tiff"},
{ "tiff", "image/tiff"},
/* Playlist files */
{ "pls", "audio/x-scpls"},
{ "m3u", "audio/mpegurl"},
{ "asx", "video/x-ms-asf"},
/* Subtitle Text files */
{ "srt", "text/srt"}, /* SubRip */
{ "ssa", "text/ssa"}, /* SubStation Alpha */
{ "stl", "text/srt"}, /* Spruce */
{ "psb", "text/psb"}, /* PowerDivX */
{ "pjs", "text/pjs"}, /* Phoenix Japanim */
{ "sub", "text/sub"}, /* MicroDVD */
{ "idx", "text/idx"}, /* VOBsub */
{ "dks", "text/dks"}, /* DKS */
{ "scr", "text/scr"}, /* MACsub */
{ "tts", "text/tts"}, /* TurboTitler */
{ "vsf", "text/vsf"}, /* ViPlay */
{ "zeg", "text/zeg"}, /* ZeroG */
{ "mpl", "text/mpl"}, /* MPL */
/* Miscellaneous text files */
{ "bup", "text/bup"}, /* DVD backup */
{ "ifo", "text/ifo"}, /* DVD information */
};
std::string jus::getMineType(const std::string& _extention) {
for (auto &it : mineList) {
if (it.first == _extention) {
return it.second;
}
}
JUS_ERROR(" try to cenvert mine type: " << _extention);
return "";
}
std::string jus::getExtention(const std::string& _mineType) {
for (auto &it : mineList) {
if (it.second == _mineType) {
return it.first;
}
}
JUS_ERROR(" try to cenvert extention: " << _mineType);
return "";
}

12
jus/mineType.h Normal file
View File

@ -0,0 +1,12 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <etk/types.h>
namespace jus {
std::string getMineType(const std::string& _extention);
std::string getExtention(const std::string& _mineType);
};

View File

@ -47,6 +47,7 @@ def create(target, module_name):
'jus/Service.cpp',
'jus/ServiceRemote.cpp',
'jus/TcpString.cpp',
'jus/mineType.cpp',
])
my_module.add_header_file([
'jus/AbstractFunction.h',
@ -66,6 +67,7 @@ def create(target, module_name):
'jus/Service.h',
'jus/ServiceRemote.h',
'jus/TcpString.h',
'jus/mineType.h',
])
if target.config["compilator"] == "clang":
my_module.add_export_flag('c++', "-Wno-unsequenced")

View File

@ -7,7 +7,9 @@
#include <appl/debug.h>
#include <jus/Client.h>
#include <jus/ServiceRemote.h>
#include <jus/mineType.h>
#include <etk/etk.h>
#include <etk/os/FSNode.h>
#include <unistd.h>
#include <etk/stdTools.h>
@ -164,12 +166,22 @@ int main(int _argc, const char *_argv[]) {
jus::File tmpFile = retListImage.get();
APPL_INFO(" mine-type: " << tmpFile.getMineType());
APPL_INFO(" size: " << tmpFile.getData().size());
APPL_INFO(" receive in =" << int64_t(retListImage.getTransmitionTime().count()/1000)/1000.0 << " ms");
std::string tmpFileName = std::string("./out/") + it + "_" + it2 + "_" + it3 + "." + jus::getExtention(tmpFile.getMineType());
APPL_INFO(" store in: " << tmpFileName);
etk::FSNode node(tmpFileName);
node.fileOpenWrite();
node.fileWrite(&tmpFile.getData()[0], 1, tmpFile.getData().size());
node.fileClose();
}
} else {
APPL_INFO(" - " << it2);
}
}
}
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::FutureBase retSendImage = remoteServicePicture.call("addFile", tmp).wait();
}
int32_t iii=0;
while (iii < 3) {

View File

@ -198,8 +198,46 @@ namespace appl {
// Return a File Data (might be a picture .tiff/.png/.jpg)
jus::FileServer getAlbumPicture(const std::string& _pictureName) {
std::unique_lock<std::mutex> lock(m_mutex);
// TODO : Check right ...
uint64_t id = etk::string_to_uint64_t(_pictureName);
APPL_WARNING("try to get file : " << _pictureName << " with id=" << id);
{
auto it = m_listFile.find(id);
if (it != m_listFile.end()) {
return jus::FileServer(m_basePath + it->second);
}
}
for (auto &it : m_listFile) {
APPL_WARNING("compare: " << it.first << " with " << id << " " << it.second);
if (it.first == id) {
return jus::FileServer(m_basePath + it.second);
}
}
APPL_ERROR(" ==> Not find ...");
return jus::FileServer();
}
std::string addFile(const jus::File& _dataFile) {
std::unique_lock<std::mutex> lock(m_mutex);
// TODO : Check right ...
/*
uint64_t id = etk::string_to_uint64_t(_pictureName);
APPL_WARNING("try to get file : " << _pictureName << " with id=" << id);
{
auto it = m_listFile.find(id);
if (it != m_listFile.end()) {
return jus::FileServer(m_basePath + it->second);
}
}
for (auto &it : m_listFile) {
APPL_WARNING("compare: " << it.first << " with " << id << " " << it.second);
if (it.first == id) {
return jus::FileServer(m_basePath + it.second);
}
}
*/
APPL_ERROR(" ==> Receive FILE " << _dataFile.getMineType());
return "54654654654654";//jus::FileServer();
}
/*
// Return a global UTC time
jus::Time getAlbumPictureTime(const std::string& _pictureName) {
@ -277,6 +315,9 @@ namespace appl {
jus::FileServer getAlbumPicture(std::string _pictureName) {
return m_user->getAlbumPicture(_pictureName);
}
std::string addFile(jus::File _dataFile) {
return m_user->addFile(_dataFile);
}
/*
// Return a global UTC time
jus::Time getAlbumPictureTime(std::string _pictureName) {
@ -332,6 +373,7 @@ int main(int _argc, const char *_argv[]) {
serviceInterface.advertise("getAlbumCount", &appl::PictureService::getAlbumCount);
serviceInterface.advertise("getAlbumListPicture", &appl::PictureService::getAlbumListPicture);
serviceInterface.advertise("getAlbumPicture", &appl::PictureService::getAlbumPicture);
serviceInterface.advertise("addFile", &appl::PictureService::addFile);
/*
serviceInterface.advertise("getAlbumPicture", &appl::PictureService::getAlbumPicture);
serviceInterface.advertise("getAlbumPictureTime", &appl::PictureService::getAlbumPictureTime);