return new (std::nothrow) Client(fd);
}
-int Client::Send(const std::vector<uint8_t>& data) {
- size_t size = data.size();
- auto* p = reinterpret_cast<void*>(&size);
- int ret = Socket::Send(p, sizeof(size));
- if (ret != 0) {
- _E("Send() is failed. error(%d)", ret);
- return ret;
- }
-
- auto* dp = reinterpret_cast<const void*>(&data[0]);
- ret = Socket::Send(dp, data.size());
+int Client::Send(const void* data, size_t data_size) {
+ int ret = Socket::Send(data, data_size);
if (ret != 0)
_E("Send() is failed. error(%d)", ret);
- if (getenv("PORT_DEBUG"))
- Util::Hexdump("Send", data);
+ if (getenv("PORT_DEBUG")) {
+ auto* p = reinterpret_cast<const uint8_t*>(data);
+ Util::Hexdump("Send", std::vector<uint8_t>(p, p + data_size));
+ }
+
return ret;
}
-int Client::Recv(std::vector<uint8_t>& data) {
- size_t size = 0;
- auto* p = reinterpret_cast<void*>(&size);
- int ret = Socket::Read(p, sizeof(size));
- if (ret != 0) {
+int Client::Recv(void* data, size_t data_size) {
+ int ret = Socket::Read(data, data_size);
+ if (ret != 0)
_E("Read() is failed. error(%d)", ret);
- return ret;
- }
- std::vector<uint8_t> buf(size);
- p = reinterpret_cast<void*>(&buf[0]);
- ret = Socket::Read(p, size);
- if (ret != 0) {
- _E("Read() is failed. error(%d)", ret);
- return ret;
+ if (getenv("PORT_DEBUG")) {
+ auto* p = reinterpret_cast<uint8_t*>(data);
+ Util::Hexdump("Recv", std::vector<uint8_t>(p, p + data_size));
}
- std::copy(buf.begin(), buf.end(), std::back_inserter(data));
- if (getenv("PORT_DEBUG"))
- Util::Hexdump("Recv", data);
return ret;
}
static Client* Create(const std::string& name, int timeout = 0);
- int Send(const std::vector<uint8_t>& data);
- int Recv(std::vector<uint8_t>& data);
+ int Send(const void* data, size_t data_size);
+ int Recv(void* data, size_t data_size);
pid_t GetPid() const;
return -EIO;
}
- Request req(std::string(name_), false, request->GetRaw());
+ Request req(std::string(name_), false, request->ToRaw());
tizen_base::Parcel req_parcel;
req_parcel.WriteParcelable(req);
- int ret = client->Send(req_parcel.GetRaw());
- if (ret != 0) {
- _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ size_t data_size = 0;
+ uint8_t* data = nullptr;
+ int ret = SendAndReceive(client.get(), req_parcel.GetData(),
+ req_parcel.GetDataSize(), &data, &data_size);
+ if (ret != 0)
return ret;
- }
-
- std::vector<uint8_t> data;
- ret = client->Recv(data);
- if (ret != 0) {
- _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
- return ret;
- }
Response res;
- auto* p = reinterpret_cast<void*>(&data[0]);
- tizen_base::Parcel res_parcel(p, data.size());
+ tizen_base::Parcel res_parcel(data, data_size, false);
res_parcel.ReadParcelable(&res);
return res.GetResult();
}
return -EIO;
}
- Request req(std::string(name_), true, request->GetRaw());
+ Request req(std::string(name_), true, request->ToRaw());
tizen_base::Parcel req_parcel;
req_parcel.WriteParcelable(req);
- int ret = client->Send(req_parcel.GetRaw());
- if (ret != 0) {
- _E("Send() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
+ size_t data_size = 0;
+ uint8_t* data = nullptr;
+ int ret = SendAndReceive(client.get(), req_parcel.GetData(),
+ req_parcel.GetDataSize(), &data, &data_size);
+ if (ret != 0)
return ret;
- }
-
- std::vector<uint8_t> data;
- ret = client->Recv(data);
- if (ret != 0) {
- _E("Recv() is failed. endpoint(%s), error(%d)", endpoint.c_str(), ret);
- return ret;
- }
Response res;
- auto* p = reinterpret_cast<void*>(&data[0]);
- tizen_base::Parcel res_parcel(p, data.size());
+ tizen_base::Parcel res_parcel(data, data_size, false);
res_parcel.ReadParcelable(&res);
auto& res_data = res.GetData();
if (res_data.size() > 0) {
return res.GetResult();
}
+int Port::Impl::SendAndReceive(Client* client, const uint8_t* send_data,
+ size_t send_data_size, uint8_t** recv_data, size_t* recv_data_size) {
+ int ret = client->Send(&send_data_size, sizeof(send_data_size));
+ if (ret != 0) {
+ _E("Send() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ ret = client->Send(send_data, send_data_size);
+ if (ret != 0) {
+ _E("Send() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ size_t data_size = 0;
+ ret = client->Recv(&data_size, sizeof(data_size));
+ if (ret != 0) {
+ _E("Recv() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ uint8_t* data = static_cast<uint8_t*>(malloc(data_size));
+ if (data == nullptr) {
+ _E("Out of memory");
+ return ret;
+ }
+
+ ret = client->Recv(data, data_size);
+ if (ret != 0) {
+ _E("Recv() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ *recv_data = data;
+ *recv_data_size = data_size;
+ return ret;
+}
+
void Port::Impl::OnSyncRequestReceived(const std::string& sender, pid_t pid,
const std::vector<uint8_t>& request, std::vector<uint8_t>& response) {
auto sender_info = std::make_shared<SenderInfo>(sender, pid);
auto res = std::shared_ptr<tizen_base::Parcel>(
new (std::nothrow) tizen_base::Parcel());
listener_->OnSyncRequest(sender_info, req, res);
- std::copy(res->GetRaw().begin(), res->GetRaw().end(),
- std::back_inserter(response));
+ response.insert(response.end(), res->GetData(),
+ res->GetData() + res->GetDataSize());
}
void Port::Impl::OnRequestReceived(const std::string& sender, pid_t pid,
friend class Port;
explicit Impl(Port* parent, std::string name, Port::IEvent* listener);
+ int SendAndReceive(Client* client, const uint8_t* send_data,
+ size_t send_data_size, uint8_t** recv_data, size_t* recv_data_size);
void OnSyncRequestReceived(const std::string& sender, pid_t pid,
const std::vector<uint8_t>& request,
std::vector<uint8_t>& response) override;
return checker_->Check(fd);
}
+int Server::ReceiveData(Client* client, uint8_t** data, size_t* data_size) {
+ size_t size = 0;
+ int ret = client->Recv(&size, sizeof(size));
+ if (ret != 0) {
+ _E("Recv() is failed. error(%d)", ret);
+ return ret;
+ }
+
+ uint8_t* buf = static_cast<uint8_t*>(malloc(size));
+ if (buf == nullptr) {
+ _E("malloc() is failed");
+ return -ENOMEM;
+ }
+
+ ret = client->Recv(buf, size);
+ if (ret != 0) {
+ _E("Recv() is failed. error(%d)", ret);
+ std::free(buf);
+ return ret;
+ }
+
+ *data = buf;
+ *data_size = size;
+ return ret;
+}
+
gboolean Server::GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data) {
if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
_E("Error condition(%d)", static_cast<int>(cond));
int ret = handle->CheckPrivilege(client->GetFd());
if (ret != 0) {
_E("Request is denied");
- std::vector<uint8_t> buf;
- client->Recv(buf);
+ size_t data_size = 0;
+ uint8_t* data = nullptr;
+ if (handle->ReceiveData(client.get(), &data, &data_size) != 0)
+ return G_SOURCE_CONTINUE;
+
+ std::free(data);
std::vector<uint8_t> dummy;
Response res(ret, dummy);
tizen_base::Parcel res_parcel;
res_parcel.WriteParcelable(res);
- client->Send(res_parcel.GetRaw());
+ data_size = res_parcel.GetDataSize();
+ client->Send(&data_size, sizeof(data_size));
+ client->Send(res_parcel.GetData(), data_size);
return G_SOURCE_CONTINUE;
}
auto* listener = handle->listener_;
if (listener) {
- std::vector<uint8_t> buf;
- client->Recv(buf);
- auto* p = reinterpret_cast<void*>(&buf[0]);
- tizen_base::Parcel parcel(p, buf.size());
+ size_t data_size = 0;
+ uint8_t* data = nullptr;
+ if (handle->ReceiveData(client.get(), &data, &data_size) != 0)
+ return G_SOURCE_REMOVE;
+
+ tizen_base::Parcel parcel(data, data_size, false);
Request req;
parcel.ReadParcelable(&req);
_W("Sender(%s), sync(%s)",
Response res(0, res_data);
tizen_base::Parcel res_parcel;
res_parcel.WriteParcelable(res);
- client->Send(res_parcel.GetRaw());
+ data_size = res_parcel.GetDataSize();
+ client->Send(&data_size, sizeof(data_size));
+ client->Send(res_parcel.GetData(), data_size);
} else {
std::vector<uint8_t> dummy;
Response res(0, dummy);
tizen_base::Parcel res_parcel;
res_parcel.WriteParcelable(res);
- client->Send(res_parcel.GetRaw());
+ data_size = res_parcel.GetDataSize();
+ client->Send(&data_size, sizeof(data_size));
+ client->Send(res_parcel.GetData(), data_size);
listener->OnRequestReceived(req.GetSender(), client->GetPid(),
req.GetData());
}
static Server* Create(const std::string& name, IEvent* listener);
private:
+ int ReceiveData(Client* client, uint8_t** data, size_t* data_size);
static gboolean GIOFunc(GIOChannel* source, GIOCondition cond, gpointer data);
Client* Accept();
int CheckPrivilege(int fd);
parcel_h res_parcel = nullptr;
parcel_create(&res_parcel);
- auto& res_data = res->GetRaw();
- auto* res_p = reinterpret_cast<const void*>(&res_data[0]);
- parcel_burst_write(res_parcel, res_p, res_data.size());
+ parcel_burst_write(res_parcel, res->GetData(), res->GetDataSize());
*response = res_parcel;
return COMPONENT_PORT_ERROR_NONE;
}