Introducing Message4. The changes to the related sources are ifdefed with USING_MESSAGE4 which is defined in Message4.h. To use Message4 the Message4.cpp, Message4.h, MessageUtils4.cpp, MessageUtils4.h and MessagePrivate4.h have to be linked to their counterparts without 4 suffix. Then MessageBody.cpp and MessageField.cpp have to be commented out in the app kit Jamfile and r5_message.cpp has to be added. There remain some bugs to be found. Feel free to change that.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14882 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2005-11-13 11:31:07 +00:00
parent 4cfc480f5d
commit cf10934e5f
18 changed files with 3742 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
#ifndef _MESSAGE_PRIVATE_H_
#define _MESSAGE_PRIVATE_H_
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <TokenSpace.h>
#define MESSAGE_BODY_HASH_TABLE_SIZE 10
#define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10
#define MAX_FIELD_PREALLOCATION 50
#define MAX_ITEM_PREALLOCATION B_PAGE_SIZE
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,
MESSAGE_FLAG_READ_ONLY = 0x0040
};
enum {
FIELD_FLAG_VALID = 0x0001,
FIELD_FLAG_FIXED_SIZE = 0x0002,
};
typedef struct field_header_s {
uint32 flags;
type_code type;
int32 nameLength;
int32 count;
ssize_t dataSize;
ssize_t allocated;
int32 offset;
int32 nextField;
} FieldHeader;
typedef struct message_header_s {
uint32 format;
uint32 what;
uint32 flags;
ssize_t fieldsSize;
ssize_t dataSize;
ssize_t fieldsAvailable;
ssize_t dataAvailable;
int32 target;
int32 currentSpecifier;
// reply info
port_id replyPort;
int32 replyTarget;
team_id replyTeam;
// body info
int32 fieldCount;
int32 hashTableSize;
int32 hashTable[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.
*/
} MessageHeader;
class BMessage::Private {
public:
Private(BMessage *msg)
: fMessage(msg)
{
}
Private(BMessage &msg)
: fMessage(&msg)
{
}
inline void SetTarget(int32 token, bool preferred)
{
fMessage->fHeader->target = (preferred
? B_PREFERRED_TOKEN : token);
}
inline void SetReply(BMessenger messenger)
{
BMessenger::Private messengerPrivate(messenger);
fMessage->fHeader->replyPort = messengerPrivate.Port();
fMessage->fHeader->replyTarget = messengerPrivate.Token();
fMessage->fHeader->replyTeam = messengerPrivate.Team();
}
inline int32 GetTarget()
{
return fMessage->fHeader->target;
}
inline bool UsePreferredTarget()
{
return fMessage->fHeader->target == B_PREFERRED_TOKEN;
}
inline status_t Clear()
{
return fMessage->_Clear();
}
inline status_t InitHeader()
{
return fMessage->_InitHeader();
}
inline MessageHeader *GetMessageHeader()
{
return fMessage->fHeader;
}
inline FieldHeader *GetMessageFields()
{
return fMessage->fFields;
}
inline uint8 *GetMessageData()
{
return fMessage->fData;
}
inline ssize_t NativeFlattenedSize() const
{
return fMessage->_NativeFlattenedSize();
}
inline status_t NativeFlatten(char *buffer, ssize_t size) const
{
return fMessage->_NativeFlatten(buffer, size);
}
inline status_t NativeFlatten(BDataIO *stream, ssize_t *size) const
{
return fMessage->_NativeFlatten(stream, size);
}
inline status_t SendMessage(port_id port, int32 token, bool preferred,
bigtime_t timeout, bool replyRequired,
BMessenger &replyTo) const
{
return fMessage->_SendMessage(port, token,
preferred, timeout, replyRequired, replyTo);
}
inline status_t SendMessage(port_id port, team_id portOwner,
int32 token, bool preferred, BMessage *reply,
bigtime_t sendTimeout, bigtime_t replyTimeout) const
{
return fMessage->_SendMessage(port, portOwner, token,
preferred, reply, sendTimeout, replyTimeout);
}
static
inline status_t SendFlattenedMessage(void *data, int32 size,
port_id port, int32 token, bool preferred,
bigtime_t timeout)
{
return BMessage::_SendFlattenedMessage(data, size,
port, token, preferred, timeout);
}
static
inline void StaticInit()
{
BMessage::_StaticInit();
}
static
inline void StaticCleanup()
{
BMessage::_StaticCleanup();
}
static
inline void StaticCacheCleanup()
{
BMessage::_StaticCacheCleanup();
}
private:
BMessage *fMessage;
};
#endif // _MESSAGE_PRIVATE_H_
+173
View File
@@ -0,0 +1,173 @@
#ifndef _MESSAGE_UTILS_H_
#define _MESSAGE_UTILS_H_
#include <ByteOrder.h>
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <SupportDefs.h>
namespace BPrivate { // Only putting these here because Be did
status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref);
status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size);
status_t entry_ref_swap(char* buffer, size_t size);
uint32 CalculateChecksum(const uint8 *buffer, int32 size);
} // namespace BPrivate
template<class T>
inline void
byte_swap(T &/*data*/)
{
// Specialize for data types which actually swap
}
inline void
write_helper(BDataIO *stream, const void *data, size_t size)
{
status_t error = stream->Write(data, size);
if (error < B_OK)
throw error;
}
class TReadHelper {
public:
TReadHelper(BDataIO *stream)
: fStream(stream),
fError(B_OK),
fSwap(false)
{
}
TReadHelper(BDataIO *stream, bool swap)
: fStream(stream),
fError(B_OK),
fSwap(swap)
{
}
template<class T>
inline void operator()(T &data)
{
fError = fStream->Read((void *)&data, sizeof(T));
if (fError > B_OK) {
if (IsSwapping())
byte_swap(data);
return;
}
if (fError == 0)
throw B_ERROR;
throw fError;
}
template<class T>
inline void operator()(T data, size_t len)
{
fError = fStream->Read((void *)data, len);
if (fError > B_OK)
return;
if (fError == 0)
throw B_ERROR;
throw fError;
}
status_t Status() { return fError; };
void SetSwap(bool yesNo) { fSwap = yesNo; };
bool IsSwapping() { return fSwap; };
private:
BDataIO *fStream;
status_t fError;
bool fSwap;
};
class TChecksumHelper {
public:
TChecksumHelper(uchar* buffer)
: fBuffer(buffer),
fBufPtr(buffer)
{
}
template<class T>
inline void Cache(const T &data)
{
*((T*)fBufPtr) = data;
fBufPtr += sizeof (T);
}
int32 CheckSum();
private:
uchar *fBuffer;
uchar *fBufPtr;
};
template<class T>
inline status_t
read_helper(BDataIO *stream, T &data)
{
return normalize_err(stream->Read((void *)&data, sizeof(T)));
}
template<>
inline void
byte_swap(double &data)
{
data = __swap_double(data);
}
template<>
inline void
byte_swap(float &data)
{
data = __swap_float(data);
}
template<>
inline void
byte_swap(int64 &data)
{
data = __swap_int64(data);
}
template<>
inline void
byte_swap(int32 &data)
{
data = __swap_int32(data);
}
template<>
inline void
byte_swap(int16 &data)
{
data = __swap_int16(data);
}
template<>
inline void
byte_swap(entry_ref &data)
{
byte_swap(data.device);
byte_swap(data.directory);
}
#endif // _MESSAGE_UTILS_H_