2007-06-28 00:33:51 +04:00
|
|
|
/*
|
2009-11-26 00:34:59 +03:00
|
|
|
* Copyright 2005-2009, Haiku Inc. All rights reserved.
|
2007-06-28 00:33:51 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Michael Lotz <mmlr@mlotz.ch>
|
|
|
|
*/
|
|
|
|
#ifndef _MESSAGE_PRIVATE_H_
|
|
|
|
#define _MESSAGE_PRIVATE_H_
|
2005-10-29 20:27:43 +04:00
|
|
|
|
|
|
|
#include <Message.h>
|
2009-11-26 00:34:59 +03:00
|
|
|
#include <Messenger.h>
|
|
|
|
#include <MessengerPrivate.h>
|
2005-10-29 20:27:43 +04:00
|
|
|
#include <TokenSpace.h>
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
|
2009-11-26 00:34:59 +03:00
|
|
|
#define MESSAGE_BODY_HASH_TABLE_SIZE 5
|
2007-06-28 00:33:51 +04:00
|
|
|
#define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10
|
|
|
|
#define MAX_FIELD_PREALLOCATION 50
|
|
|
|
|
|
|
|
|
|
|
|
static const int32 kPortMessageCode = 'pjpp';
|
|
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MESSAGE_FLAG_VALID = 0x0001,
|
|
|
|
MESSAGE_FLAG_REPLY_REQUIRED = 0x0002,
|
|
|
|
MESSAGE_FLAG_REPLY_DONE = 0x0004,
|
|
|
|
MESSAGE_FLAG_IS_REPLY = 0x0008,
|
|
|
|
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
|
|
|
|
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
|
2009-11-26 00:34:59 +03:00
|
|
|
MESSAGE_FLAG_WAS_DROPPED = 0x0040,
|
|
|
|
MESSAGE_FLAG_PASS_BY_AREA = 0x0080
|
2007-06-28 00:33:51 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
FIELD_FLAG_VALID = 0x0001,
|
|
|
|
FIELD_FLAG_FIXED_SIZE = 0x0002,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct BMessage::field_header {
|
2009-11-26 00:34:59 +03:00
|
|
|
uint16 flags;
|
|
|
|
uint16 name_length;
|
2007-06-28 00:33:51 +04:00
|
|
|
type_code type;
|
2009-11-26 00:34:59 +03:00
|
|
|
uint32 count;
|
|
|
|
uint32 data_size;
|
|
|
|
uint32 offset;
|
2007-06-28 00:33:51 +04:00
|
|
|
int32 next_field;
|
2009-11-26 00:34:59 +03:00
|
|
|
} _PACKED;
|
2007-06-28 00:33:51 +04:00
|
|
|
|
|
|
|
|
|
|
|
struct BMessage::message_header {
|
|
|
|
uint32 format;
|
|
|
|
uint32 what;
|
|
|
|
uint32 flags;
|
|
|
|
|
|
|
|
int32 target;
|
|
|
|
int32 current_specifier;
|
2009-11-26 00:34:59 +03:00
|
|
|
area_id message_area;
|
2007-06-28 00:33:51 +04:00
|
|
|
|
|
|
|
// reply info
|
|
|
|
port_id reply_port;
|
|
|
|
int32 reply_target;
|
|
|
|
team_id reply_team;
|
|
|
|
|
|
|
|
// body info
|
2009-11-26 00:34:59 +03:00
|
|
|
uint32 data_size;
|
|
|
|
uint32 field_count;
|
|
|
|
uint32 hash_table_size;
|
2007-06-28 00:33:51 +04:00
|
|
|
int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE];
|
|
|
|
|
|
|
|
/* The hash table does contain indexes into the field list and
|
|
|
|
not direct offsets to the fields. This has the advantage
|
|
|
|
of not needing to update offsets in two locations.
|
|
|
|
The hash table must be reevaluated when we remove a field
|
|
|
|
though.
|
|
|
|
*/
|
2009-11-26 00:34:59 +03:00
|
|
|
} _PACKED;
|
2007-06-28 00:33:51 +04:00
|
|
|
|
|
|
|
|
|
|
|
class BMessage::Private {
|
2005-10-29 20:27:43 +04:00
|
|
|
public:
|
2007-06-28 00:33:51 +04:00
|
|
|
Private(BMessage *msg)
|
2009-11-26 00:34:59 +03:00
|
|
|
:
|
|
|
|
fMessage(msg)
|
2007-06-28 00:33:51 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Private(BMessage &msg)
|
2009-11-26 00:34:59 +03:00
|
|
|
:
|
|
|
|
fMessage(&msg)
|
2007-06-28 00:33:51 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetTarget(int32 token)
|
|
|
|
{
|
|
|
|
fMessage->fHeader->target = token;
|
|
|
|
}
|
|
|
|
|
2009-11-26 00:34:59 +03:00
|
|
|
void
|
|
|
|
SetReply(BMessenger messenger)
|
|
|
|
{
|
|
|
|
BMessenger::Private messengerPrivate(messenger);
|
|
|
|
fMessage->fHeader->reply_port = messengerPrivate.Port();
|
|
|
|
fMessage->fHeader->reply_target = messengerPrivate.Token();
|
|
|
|
fMessage->fHeader->reply_team = messengerPrivate.Team();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetReply(team_id team, port_id port, int32 target)
|
|
|
|
{
|
|
|
|
fMessage->fHeader->reply_port = port;
|
|
|
|
fMessage->fHeader->reply_target = target;
|
|
|
|
fMessage->fHeader->reply_team = team;
|
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
int32
|
|
|
|
GetTarget()
|
|
|
|
{
|
|
|
|
return fMessage->fHeader->target;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
UsePreferredTarget()
|
|
|
|
{
|
|
|
|
return fMessage->fHeader->target == B_PREFERRED_TOKEN;
|
|
|
|
}
|
2005-10-29 20:27:43 +04:00
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
void
|
|
|
|
SetWasDropped(bool wasDropped)
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
if (wasDropped)
|
|
|
|
fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED;
|
|
|
|
else
|
|
|
|
fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED;
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
status_t
|
|
|
|
Clear()
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
return fMessage->_Clear();
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
status_t
|
|
|
|
InitHeader()
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
return fMessage->_InitHeader();
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
BMessage::message_header*
|
|
|
|
GetMessageHeader()
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
return fMessage->fHeader;
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
BMessage::field_header*
|
|
|
|
GetMessageFields()
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
return fMessage->fFields;
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
uint8*
|
|
|
|
GetMessageData()
|
2005-10-29 20:27:43 +04:00
|
|
|
{
|
2007-06-28 00:33:51 +04:00
|
|
|
return fMessage->fData;
|
2005-10-29 20:27:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2007-06-28 00:33:51 +04:00
|
|
|
BMessage* fMessage;
|
2005-10-29 20:27:43 +04:00
|
|
|
};
|
|
|
|
|
2007-06-28 00:33:51 +04:00
|
|
|
#endif // _MESSAGE_PRIVATE_H_
|