BMessage: implemented KMessage reply.
* When you receive a message from a KMessage, and reply to it, it will automatically reply as KMessage, too. * This allows to communicate with BLoopers from within the kernel or libroot.so.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2009, Haiku Inc. All rights reserved.
|
* Copyright 2005-2015, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#ifndef _MESSAGE_PRIVATE_H_
|
#ifndef _MESSAGE_PRIVATE_H_
|
||||||
#define _MESSAGE_PRIVATE_H_
|
#define _MESSAGE_PRIVATE_H_
|
||||||
|
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <MessengerPrivate.h>
|
#include <MessengerPrivate.h>
|
||||||
@@ -30,7 +31,8 @@ enum {
|
|||||||
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
|
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
|
||||||
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
|
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
|
||||||
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
|
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
|
||||||
MESSAGE_FLAG_PASS_BY_AREA = 0x0080
|
MESSAGE_FLAG_PASS_BY_AREA = 0x0080,
|
||||||
|
MESSAGE_FLAG_REPLY_AS_KMESSAGE = 0x0100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
static status_t Unflatten(uint32 format, BMessage* into,
|
static status_t Unflatten(uint32 format, BMessage* into,
|
||||||
BDataIO* stream);
|
BDataIO* stream);
|
||||||
|
|
||||||
|
static status_t ConvertToKMessage(const BMessage* from,
|
||||||
|
KMessage& to);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static status_t _ConvertFromKMessage(const KMessage* from,
|
static status_t _ConvertFromKMessage(const KMessage* from,
|
||||||
BMessage* to);
|
BMessage* to);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2010, Haiku Inc. All rights reserved.
|
* Copyright 2005-2015, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#ifndef _MESSAGE_PRIVATE_H_
|
#ifndef _MESSAGE_PRIVATE_H_
|
||||||
#define _MESSAGE_PRIVATE_H_
|
#define _MESSAGE_PRIVATE_H_
|
||||||
|
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Messenger.h>
|
#include <Messenger.h>
|
||||||
#include <MessengerPrivate.h>
|
#include <MessengerPrivate.h>
|
||||||
@@ -30,7 +31,8 @@ enum {
|
|||||||
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
|
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
|
||||||
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
|
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
|
||||||
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
|
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
|
||||||
MESSAGE_FLAG_PASS_BY_AREA = 0x0080
|
MESSAGE_FLAG_PASS_BY_AREA = 0x0080,
|
||||||
|
MESSAGE_FLAG_REPLY_AS_KMESSAGE = 0x0100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -913,6 +913,8 @@ BMessage::SendReply(BMessage* reply, BMessenger replyTo, bigtime_t timeout)
|
|||||||
BMessenger::Private messengerPrivate(messenger);
|
BMessenger::Private messengerPrivate(messenger);
|
||||||
messengerPrivate.SetTo(fHeader->reply_team, fHeader->reply_port,
|
messengerPrivate.SetTo(fHeader->reply_team, fHeader->reply_port,
|
||||||
fHeader->reply_target);
|
fHeader->reply_target);
|
||||||
|
if ((fHeader->flags & MESSAGE_FLAG_REPLY_AS_KMESSAGE) != 0)
|
||||||
|
reply->fHeader->flags |= MESSAGE_FLAG_REPLY_AS_KMESSAGE;
|
||||||
|
|
||||||
if ((fHeader->flags & MESSAGE_FLAG_REPLY_REQUIRED) != 0) {
|
if ((fHeader->flags & MESSAGE_FLAG_REPLY_REQUIRED) != 0) {
|
||||||
if ((fHeader->flags & MESSAGE_FLAG_REPLY_DONE) != 0)
|
if ((fHeader->flags & MESSAGE_FLAG_REPLY_DONE) != 0)
|
||||||
@@ -923,11 +925,9 @@ BMessage::SendReply(BMessage* reply, BMessenger replyTo, bigtime_t timeout)
|
|||||||
status_t result = messenger.SendMessage(reply, replyTo, timeout);
|
status_t result = messenger.SendMessage(reply, replyTo, timeout);
|
||||||
reply->fHeader->flags &= ~MESSAGE_FLAG_IS_REPLY;
|
reply->fHeader->flags &= ~MESSAGE_FLAG_IS_REPLY;
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK && set_port_owner(messengerPrivate.Port(),
|
||||||
if (set_port_owner(messengerPrivate.Port(),
|
|
||||||
messengerPrivate.Team()) == B_BAD_TEAM_ID) {
|
messengerPrivate.Team()) == B_BAD_TEAM_ID) {
|
||||||
delete_port(messengerPrivate.Port());
|
delete_port(messengerPrivate.Port());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -993,7 +993,8 @@ BMessage::SendReply(BMessage* reply, BMessage* replyToReply,
|
|||||||
return B_BAD_REPLY;
|
return B_BAD_REPLY;
|
||||||
|
|
||||||
reply->AddMessage("_previous_", this);
|
reply->AddMessage("_previous_", this);
|
||||||
reply->fHeader->flags |= MESSAGE_FLAG_IS_REPLY;
|
reply->fHeader->flags |= MESSAGE_FLAG_IS_REPLY
|
||||||
|
| (fHeader->flags & MESSAGE_FLAG_REPLY_AS_KMESSAGE);
|
||||||
status_t result = messenger.SendMessage(reply, replyToReply, sendTimeout,
|
status_t result = messenger.SendMessage(reply, replyToReply, sendTimeout,
|
||||||
replyTimeout);
|
replyTimeout);
|
||||||
reply->fHeader->flags &= ~MESSAGE_FLAG_IS_REPLY;
|
reply->fHeader->flags &= ~MESSAGE_FLAG_IS_REPLY;
|
||||||
@@ -2164,6 +2165,13 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token,
|
|||||||
header->message_area = transfered;
|
header->message_area = transfered;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
} else if ((fHeader->flags & MESSAGE_FLAG_REPLY_AS_KMESSAGE) != 0) {
|
||||||
|
KMessage toMessage;
|
||||||
|
result = BPrivate::MessageAdapter::ConvertToKMessage(this, toMessage);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return toMessage.SendTo(port, token);
|
||||||
} else {
|
} else {
|
||||||
size = FlattenedSize();
|
size = FlattenedSize();
|
||||||
buffer = (char*)malloc(size);
|
buffer = (char*)malloc(size);
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2007, Haiku Inc. All rights reserved.
|
* Copyright 2005-2015, Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
* Michael Lotz <[email protected]>
|
* Michael Lotz <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <MessageAdapter.h>
|
#include <MessageAdapter.h>
|
||||||
#include <MessagePrivate.h>
|
#include <MessagePrivate.h>
|
||||||
#include <MessageUtils.h>
|
#include <MessageUtils.h>
|
||||||
@@ -237,6 +239,44 @@ MessageAdapter::Unflatten(uint32 format, BMessage *into, BDataIO *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ status_t
|
||||||
|
MessageAdapter::ConvertToKMessage(const BMessage* from, KMessage& to)
|
||||||
|
{
|
||||||
|
if (from == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BMessage::Private fromPrivate(const_cast<BMessage*>(from));
|
||||||
|
BMessage::message_header* header = fromPrivate.GetMessageHeader();
|
||||||
|
uint8* data = fromPrivate.GetMessageData();
|
||||||
|
|
||||||
|
// Iterate through the fields and import them in the target message
|
||||||
|
BMessage::field_header* field = fromPrivate.GetMessageFields();
|
||||||
|
for (uint32 i = 0; i < header->field_count; i++, field++) {
|
||||||
|
const char* name = (const char*)data + field->offset;
|
||||||
|
const uint8* fieldData = data + field->offset + field->name_length;
|
||||||
|
bool fixedSize = (field->flags & FIELD_FLAG_FIXED_SIZE) != 0;
|
||||||
|
|
||||||
|
if (fixedSize) {
|
||||||
|
status_t status = to.AddArray(name, field->type, fieldData,
|
||||||
|
field->data_size / field->count, field->count);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
for (uint32 i = 0; i < field->count; i++) {
|
||||||
|
uint32 itemSize = *(uint32*)fieldData;
|
||||||
|
fieldData += sizeof(uint32);
|
||||||
|
status_t status = to.AddData(name, field->type, fieldData,
|
||||||
|
itemSize, false);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
fieldData += itemSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
MessageAdapter::_ConvertFromKMessage(const KMessage *fromMessage,
|
MessageAdapter::_ConvertFromKMessage(const KMessage *fromMessage,
|
||||||
BMessage *toMessage)
|
BMessage *toMessage)
|
||||||
@@ -252,6 +292,10 @@ MessageAdapter::_ConvertFromKMessage(const KMessage *fromMessage,
|
|||||||
toPrivate.SetTarget(fromMessage->TargetToken());
|
toPrivate.SetTarget(fromMessage->TargetToken());
|
||||||
toPrivate.SetReply(B_SYSTEM_TEAM, fromMessage->ReplyPort(),
|
toPrivate.SetReply(B_SYSTEM_TEAM, fromMessage->ReplyPort(),
|
||||||
fromMessage->ReplyToken());
|
fromMessage->ReplyToken());
|
||||||
|
if (fromMessage->ReplyPort() >= 0) {
|
||||||
|
toPrivate.GetMessageHeader()->flags |= MESSAGE_FLAG_REPLY_AS_KMESSAGE
|
||||||
|
| MESSAGE_FLAG_REPLY_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate through the fields and import them in the target message
|
// Iterate through the fields and import them in the target message
|
||||||
KMessageField field;
|
KMessageField field;
|
||||||
|
|||||||
Reference in New Issue
Block a user