hrev50274 adds 1 changeset to branch 'master'
old head: 8a808785fc472776f7b22704c6b0dedc7881f652
new head: 493cced1ef23111138481697c5de9ca21a10124a
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=493cced1ef23+%5E8a808785fc47
----------------------------------------------------------------------------
493cced1ef23: libbnetapi: Add socket messenger class.
- Introduces new network API class BSocketMessenger, allowing one to send
and receive BMessages across a network socket in a BMessenger-like
fashion. Still very much WIP, hence currently not exposed via public
headers.
Based partly on previous work by Axel.
[ Rene Gollent <rene@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev50274
Commit: 493cced1ef23111138481697c5de9ca21a10124a
URL: http://cgit.haiku-os.org/haiku/commit/?id=493cced1ef23
Author: Rene Gollent <rene@xxxxxxxxxxx>
Date: Sat Apr 30 22:29:55 2016 UTC
----------------------------------------------------------------------------
3 files changed, 218 insertions(+), 2 deletions(-)
headers/private/net/SocketMessenger.h | 56 ++++++++
src/kits/network/libnetapi/Jamfile | 5 +-
src/kits/network/libnetapi/SocketMessenger.cpp | 159 +++++++++++++++++++++
----------------------------------------------------------------------------
diff --git a/headers/private/net/SocketMessenger.h
b/headers/private/net/SocketMessenger.h
new file mode 100644
index 0000000..488c7e7
--- /dev/null
+++ b/headers/private/net/SocketMessenger.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2011-2016, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef SOCKET_MESSENGER_H
+#define SOCKET_MESSENGER_H
+
+#include <Socket.h>
+
+class BMessage;
+class BMessenger;
+
+
+class BSocketMessenger {
+public:
+
BSocketMessenger();
+
BSocketMessenger(
+ const
BNetworkAddress& address,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+ // adopt an
existing already connected socket.
+
BSocketMessenger(const BSocket& socket);
+ virtual ~BSocketMessenger();
+
+ void Unset();
+ status_t SetTo(const
BNetworkAddress& address,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+ status_t SetTo(const
BSocketMessenger& target,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+
+ status_t InitCheck() const {
return fInitStatus; }
+
+ const BNetworkAddress& Address() const { return
fSocket.Peer(); }
+
+ virtual status_t SendMessage(const BMessage&
message);
+ virtual status_t SendMessage(const BMessage&
message,
+
BMessage& _reply,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+ virtual status_t SendMessage(const BMessage&
message,
+
BMessenger& replyTarget,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+
+ // wait for
unsolicited message on socket
+ virtual status_t ReceiveMessage(BMessage&
_message,
+
bigtime_t timeout = B_INFINITE_TIMEOUT);
+
+private:
+ status_t _SendMessage(const
BMessage& message);
+ status_t _ReadMessage(BMessage&
_message,
+
bigtime_t timeout);
+
+private:
+ BSocket fSocket;
+ status_t fInitStatus;
+};
+
+#endif // SOCKET_MESSENGER_H
diff --git a/src/kits/network/libnetapi/Jamfile
b/src/kits/network/libnetapi/Jamfile
index aef8869..85f508b 100644
--- a/src/kits/network/libnetapi/Jamfile
+++ b/src/kits/network/libnetapi/Jamfile
@@ -64,9 +64,10 @@ for architectureObject in [ MultiArchSubDirSetup ] {
AbstractSocket.cpp
DatagramSocket.cpp
- Socket.cpp
- SecureSocket.cpp
ProxySecureSocket.cpp
+ SecureSocket.cpp
+ Socket.cpp
+ SocketMessenger.cpp
# TODO: another add-on for file:// (a much simpler one)
FileRequest.cpp
diff --git a/src/kits/network/libnetapi/SocketMessenger.cpp
b/src/kits/network/libnetapi/SocketMessenger.cpp
new file mode 100644
index 0000000..2b6556d
--- /dev/null
+++ b/src/kits/network/libnetapi/SocketMessenger.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2009-2011, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2016, Rene Gollent, rene@xxxxxxxxxxx.
+ */
+
+
+#include <SocketMessenger.h>
+
+#include <Message.h>
+#include <Messenger.h>
+
+#include <AutoDeleter.h>
+
+
+BSocketMessenger::BSocketMessenger()
+ :
+ fSocket(),
+ fInitStatus(B_NO_INIT)
+{
+}
+
+
+BSocketMessenger::BSocketMessenger(const BNetworkAddress& address,
+ bigtime_t timeout)
+{
+ SetTo(address, timeout);
+}
+
+
+BSocketMessenger::BSocketMessenger(const BSocket& socket)
+ :
+ fSocket(socket)
+{
+ fInitStatus = socket.InitCheck();
+}
+
+
+BSocketMessenger::~BSocketMessenger()
+{
+ Unset();
+}
+
+
+void
+BSocketMessenger::Unset()
+{
+ fSocket.Disconnect();
+ fInitStatus = B_NO_INIT;
+}
+
+
+status_t
+BSocketMessenger::SetTo(const BNetworkAddress& address, bigtime_t timeout)
+{
+ return fInitStatus = fSocket.Connect(address, timeout);
+}
+
+
+status_t
+BSocketMessenger::SetTo(const BSocketMessenger& target, bigtime_t timeout)
+{
+ return SetTo(target.Address(), timeout);
+}
+
+
+status_t
+BSocketMessenger::SendMessage(const BMessage& message)
+{
+ return _SendMessage(message);
+}
+
+
+status_t
+BSocketMessenger::SendMessage(const BMessage& message, BMessage& _reply,
+ bigtime_t timeout)
+{
+ status_t error = _SendMessage(message);
+ if (error != B_OK)
+ return error;
+
+ return _ReadMessage(_reply, timeout);
+}
+
+
+status_t
+BSocketMessenger::SendMessage(const BMessage& message,
+ BMessenger& replyTarget, bigtime_t timeout)
+{
+ BMessage reply;
+ status_t error = SendMessage(message, reply, timeout);
+ if (error != B_OK)
+ return error;
+
+ return replyTarget.SendMessage(&reply);
+}
+
+
+status_t
+BSocketMessenger::ReceiveMessage(BMessage& _message, bigtime_t timeout)
+{
+ return _ReadMessage(_message, timeout);
+}
+
+
+status_t
+BSocketMessenger::_SendMessage(const BMessage& message)
+{
+ ssize_t flatSize = message.FlattenedSize();
+ flatSize += sizeof(ssize_t);
+
+ char* buffer = new(std::nothrow) char[flatSize];
+ if (buffer == NULL)
+ return B_NO_MEMORY;
+
+ ArrayDeleter<char> bufferDeleter(buffer);
+ *(ssize_t*)buffer = flatSize;
+ char* messageBuffer = buffer + sizeof(ssize_t);
+ status_t error = message.Flatten(messageBuffer, flatSize);
+ if (error != B_OK)
+ return error;
+
+ ssize_t size = fSocket.Write(buffer, flatSize);
+ if (size < 0)
+ return size;
+
+ return B_OK;
+}
+
+
+status_t
+BSocketMessenger::_ReadMessage(BMessage& _message, bigtime_t timeout)
+{
+ status_t error = fSocket.WaitForReadable(timeout);
+ if (error != B_OK)
+ return error;
+
+ ssize_t size = 0;
+ ssize_t readSize = fSocket.Read(&size, sizeof(ssize_t));
+ if (readSize < 0)
+ return readSize;
+ else if (readSize != sizeof(ssize_t))
+ return B_BAD_VALUE;
+
+ if (size <= 0)
+ return B_MISMATCHED_VALUES;
+
+ char* buffer = new(std::nothrow) char[size];
+ if (buffer == NULL)
+ return B_NO_MEMORY;
+
+ ArrayDeleter<char> bufferDeleter(buffer);
+ readSize = fSocket.Read(buffer, size);
+ if (readSize < 0)
+ return readSize;
+ else if (readSize != size)
+ return B_MISMATCHED_VALUES;
+
+ return _message.Unflatten(buffer);
+}