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.
This commit is contained in:
Rene Gollent
2016-04-30 18:32:50 -04:00
parent 8a808785fc
commit 493cced1ef
3 changed files with 218 additions and 2 deletions
+56
View File
@@ -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
+3 -2
View File
@@ -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
@@ -0,0 +1,159 @@
/*
* Copyright 2009-2011, Axel Dörfler, [email protected].
* Copyright 2016, Rene Gollent, [email protected].
*/
#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);
}