Removing old BMessage implementation. Message4 will replace it in the next commit.

This will allow to fix message related problems like drag and drop and scripting.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16708 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2006-03-11 17:52:56 +00:00
parent be25ae8698
commit 16ba0dc5ca
9 changed files with 0 additions and 4585 deletions

View File

@ -1,434 +0,0 @@
/*
* Copyright 2001-2005, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Erik Jaesler (erik@cgsoftware.com)
* DarkWyrm <bpmagic@columbus.rr.com>
*/
#ifdef USING_MESSAGE4
# include <Message4.h>
#else
#ifndef _MESSAGE_H
#define _MESSAGE_H
#include <DataIO.h>
#include <Flattenable.h>
#include <Messenger.h>
#include <OS.h>
#include <Rect.h>
// for convenience
#include <AppDefs.h>
#include <TypeConstants.h>
class BBlockCache;
class BMessenger;
class BHandler;
class BString;
struct entry_ref;
// Private or reserved ---------------------------------------------------------
extern "C" void _msg_cache_cleanup_();
extern "C" int _init_message_();
extern "C" int _delete_message_();
// Name lengths and Scripting specifiers ---------------------------------------
#define B_FIELD_NAME_LENGTH 255
#define B_PROPERTY_NAME_LENGTH 255
enum {
B_NO_SPECIFIER = 0,
B_DIRECT_SPECIFIER,
B_INDEX_SPECIFIER,
B_REVERSE_INDEX_SPECIFIER,
B_RANGE_SPECIFIER,
B_REVERSE_RANGE_SPECIFIER,
B_NAME_SPECIFIER,
B_ID_SPECIFIER,
B_SPECIFIERS_END = 128
// app-defined specifiers start at B_SPECIFIERS_END+1
};
namespace BPrivate {
class BMessageBody;
}
// BMessage class --------------------------------------------------------------
class BMessage {
public:
uint32 what;
BMessage();
BMessage(uint32 what);
BMessage(const BMessage &a_message);
virtual ~BMessage();
BMessage &operator=(const BMessage &msg);
// Statistics and misc info
status_t GetInfo(type_code typeRequested, int32 which, char **name,
type_code *typeReturned, int32 *count = NULL) const;
status_t GetInfo(const char *name, type_code *type, int32 *c = 0) const;
status_t GetInfo(const char *name, type_code *type, bool *fixed_size) const;
int32 CountNames(type_code type) const;
bool IsEmpty() const;
bool IsSystem() const;
bool IsReply() const;
void PrintToStream() const;
status_t Rename(const char *old_entry, const char *new_entry);
// Delivery info
bool WasDelivered() const;
bool IsSourceWaiting() const;
bool IsSourceRemote() const;
BMessenger ReturnAddress() const;
const BMessage *Previous() const;
bool WasDropped() const;
BPoint DropPoint(BPoint *offset = NULL) const;
// Replying
status_t SendReply(uint32 command, BHandler *reply_to = NULL);
status_t SendReply(BMessage *the_reply, BHandler *reply_to = NULL,
bigtime_t timeout = B_INFINITE_TIMEOUT);
status_t SendReply(BMessage *the_reply, BMessenger reply_to,
bigtime_t timeout = B_INFINITE_TIMEOUT);
status_t SendReply(uint32 command, BMessage *reply_to_reply);
status_t SendReply(BMessage *the_reply, BMessage *reply_to_reply,
bigtime_t send_timeout = B_INFINITE_TIMEOUT,
bigtime_t reply_timeout = B_INFINITE_TIMEOUT);
// Flattening data
ssize_t FlattenedSize() const;
status_t Flatten(char *buffer, ssize_t size) const;
status_t Flatten(BDataIO *stream, ssize_t *size = NULL) const;
status_t Unflatten(const char *flat_buffer);
status_t Unflatten(BDataIO *stream);
// Specifiers (scripting)
status_t AddSpecifier(const char *property);
status_t AddSpecifier(const char *property, int32 index);
status_t AddSpecifier(const char *property, int32 index, int32 range);
status_t AddSpecifier(const char *property, const char *name);
status_t AddSpecifier(const BMessage *specifier);
status_t SetCurrentSpecifier(int32 index);
status_t GetCurrentSpecifier(int32 *index, BMessage *specifier = NULL,
int32 *form = NULL, const char **property = NULL) const;
bool HasSpecifiers() const;
status_t PopSpecifier();
// Adding data
status_t AddRect(const char *name, BRect a_rect);
status_t AddPoint(const char *name, BPoint a_point);
status_t AddString(const char *name, const char *a_string);
status_t AddString(const char *name, const BString& a_string);
status_t AddInt8(const char *name, int8 val);
status_t AddInt16(const char *name, int16 val);
status_t AddInt32(const char *name, int32 val);
status_t AddInt64(const char *name, int64 val);
status_t AddBool(const char *name, bool a_boolean);
status_t AddFloat(const char *name, float a_float);
status_t AddDouble(const char *name, double a_double);
status_t AddPointer(const char *name, const void *ptr);
status_t AddMessenger(const char *name, BMessenger messenger);
status_t AddRef(const char *name, const entry_ref *ref);
status_t AddMessage(const char *name, const BMessage *msg);
status_t AddFlat(const char *name, BFlattenable *obj, int32 count = 1);
status_t AddData(const char *name, type_code type, const void *data,
ssize_t numBytes, bool is_fixed_size = true, int32 count = 1);
// Removing data
status_t RemoveData(const char *name, int32 index = 0);
status_t RemoveName(const char *name);
status_t MakeEmpty();
// Finding data
status_t FindRect(const char *name, BRect *rect) const;
status_t FindRect(const char *name, int32 index, BRect *rect) const;
status_t FindPoint(const char *name, BPoint *pt) const;
status_t FindPoint(const char *name, int32 index, BPoint *pt) const;
status_t FindString(const char *name, const char **str) const;
status_t FindString(const char *name, int32 index, const char **str) const;
status_t FindString(const char *name, BString *str) const;
status_t FindString(const char *name, int32 index, BString *str) const;
status_t FindInt8(const char *name, int8 *value) const;
status_t FindInt8(const char *name, int32 index, int8 *val) const;
status_t FindInt16(const char *name, int16 *value) const;
status_t FindInt16(const char *name, int32 index, int16 *val) const;
status_t FindInt32(const char *name, int32 *value) const;
status_t FindInt32(const char *name, int32 index, int32 *val) const;
status_t FindInt64(const char *name, int64 *value) const;
status_t FindInt64(const char *name, int32 index, int64 *val) const;
status_t FindBool(const char *name, bool *value) const;
status_t FindBool(const char *name, int32 index, bool *value) const;
status_t FindFloat(const char *name, float *f) const;
status_t FindFloat(const char *name, int32 index, float *f) const;
status_t FindDouble(const char *name, double *d) const;
status_t FindDouble(const char *name, int32 index, double *d) const;
status_t FindPointer(const char *name, void **ptr) const;
status_t FindPointer(const char *name, int32 index, void **ptr) const;
status_t FindMessenger(const char *name, BMessenger *m) const;
status_t FindMessenger(const char *name, int32 index, BMessenger *m) const;
status_t FindRef(const char *name, entry_ref *ref) const;
status_t FindRef(const char *name, int32 index, entry_ref *ref) const;
status_t FindMessage(const char *name, BMessage *msg) const;
status_t FindMessage(const char *name, int32 index, BMessage *msg) const;
status_t FindFlat(const char *name, BFlattenable *obj) const;
status_t FindFlat(const char *name, int32 index, BFlattenable *obj) const;
status_t FindData(const char *name, type_code type,
const void **data, ssize_t *numBytes) const;
status_t FindData(const char *name, type_code type, int32 index,
const void **data, ssize_t *numBytes) const;
// Replacing data
status_t ReplaceRect(const char *name, BRect a_rect);
status_t ReplaceRect(const char *name, int32 index, BRect a_rect);
status_t ReplacePoint(const char *name, BPoint a_point);
status_t ReplacePoint(const char *name, int32 index, BPoint a_point);
status_t ReplaceString(const char *name, const char *string);
status_t ReplaceString(const char *name, int32 index, const char *string);
status_t ReplaceString(const char *name, const BString& string);
status_t ReplaceString(const char *name, int32 index, const BString& string);
status_t ReplaceInt8(const char *name, int8 val);
status_t ReplaceInt8(const char *name, int32 index, int8 val);
status_t ReplaceInt16(const char *name, int16 val);
status_t ReplaceInt16(const char *name, int32 index, int16 val);
status_t ReplaceInt32(const char *name, int32 val);
status_t ReplaceInt32(const char *name, int32 index, int32 val);
status_t ReplaceInt64(const char *name, int64 val);
status_t ReplaceInt64(const char *name, int32 index, int64 val);
status_t ReplaceBool(const char *name, bool a_bool);
status_t ReplaceBool(const char *name, int32 index, bool a_bool);
status_t ReplaceFloat(const char *name, float a_float);
status_t ReplaceFloat(const char *name, int32 index, float a_float);
status_t ReplaceDouble(const char *name, double a_double);
status_t ReplaceDouble(const char *name, int32 index, double a_double);
status_t ReplacePointer(const char *name, const void *ptr);
status_t ReplacePointer(const char *name,int32 index,const void *ptr);
status_t ReplaceMessenger(const char *name, BMessenger messenger);
status_t ReplaceMessenger(const char *name, int32 index, BMessenger msngr);
status_t ReplaceRef( const char *name,const entry_ref *ref);
status_t ReplaceRef( const char *name, int32 index, const entry_ref *ref);
status_t ReplaceMessage(const char *name, const BMessage *msg);
status_t ReplaceMessage(const char *name, int32 index, const BMessage *msg);
status_t ReplaceFlat(const char *name, BFlattenable *obj);
status_t ReplaceFlat(const char *name, int32 index, BFlattenable *obj);
status_t ReplaceData(const char *name, type_code type,
const void *data, ssize_t data_size);
status_t ReplaceData(const char *name, type_code type, int32 index,
const void *data, ssize_t data_size);
void *operator new(size_t size);
void *operator new(size_t, void* p);
void operator delete(void *ptr, size_t size);
// Private, reserved, or obsolete ----------------------------------------------
bool HasRect(const char *, int32 n = 0) const;
bool HasPoint(const char *, int32 n = 0) const;
bool HasString(const char *, int32 n = 0) const;
bool HasInt8(const char *, int32 n = 0) const;
bool HasInt16(const char *, int32 n = 0) const;
bool HasInt32(const char *, int32 n = 0) const;
bool HasInt64(const char *, int32 n = 0) const;
bool HasBool(const char *, int32 n = 0) const;
bool HasFloat(const char *, int32 n = 0) const;
bool HasDouble(const char *, int32 n = 0) const;
bool HasPointer(const char *, int32 n = 0) const;
bool HasMessenger(const char *, int32 n = 0) const;
bool HasRef(const char *, int32 n = 0) const;
bool HasMessage(const char *, int32 n = 0) const;
bool HasFlat(const char *, const BFlattenable *) const;
bool HasFlat(const char *,int32 ,const BFlattenable *) const;
bool HasData(const char *, type_code , int32 n = 0) const;
BRect FindRect(const char *, int32 n = 0) const;
BPoint FindPoint(const char *, int32 n = 0) const;
const char *FindString(const char *, int32 n = 0) const;
int8 FindInt8(const char *, int32 n = 0) const;
int16 FindInt16(const char *, int32 n = 0) const;
int32 FindInt32(const char *, int32 n = 0) const;
int64 FindInt64(const char *, int32 n = 0) const;
bool FindBool(const char *, int32 n = 0) const;
float FindFloat(const char *, int32 n = 0) const;
double FindDouble(const char *, int32 n = 0) const;
class Private;
private:
class Header;
friend class BMessageQueue;
friend class BMessenger;
friend class BApplication;
friend class Header;
friend class Private;
friend inline void _set_message_target_(BMessage *, int32, bool);
friend inline void _set_message_reply_(BMessage *, BMessenger);
friend inline int32 _get_message_target_(BMessage *);
friend inline bool _use_preferred_target_(BMessage *);
// deprecated
BMessage(BMessage *a_message);
virtual void _ReservedMessage1();
virtual void _ReservedMessage2();
virtual void _ReservedMessage3();
void init_data();
status_t flatten_target_info(BDataIO *stream,
ssize_t size,
uchar flags) const;
status_t real_flatten(char *result,
ssize_t size) const;
status_t real_flatten(BDataIO *stream) const;
char *stack_flatten(char *stack_ptr,
ssize_t stack_size,
bool incl_reply,
ssize_t *size = NULL) const;
status_t _UnflattenKMessage(const char *buffer);
ssize_t calc_size(uchar flags) const;
ssize_t calc_hdr_size(uchar flags) const;
status_t nfind_data( const char *name,
type_code type,
int32 index,
const void **data,
ssize_t *data_size) const;
status_t copy_data( const char *name,
type_code type,
int32 index,
void *data,
ssize_t data_size) const;
status_t _send_(port_id port,
int32 token,
bigtime_t timeout,
bool reply_required,
BMessenger &reply_to) const;
status_t send_message(port_id port,
team_id port_owner,
int32 token,
BMessage *reply,
bigtime_t send_timeout,
bigtime_t reply_timeout) const;
static status_t _SendFlattenedMessage(void *data, int32 size,
port_id port, int32 token, bigtime_t timeout);
static void _StaticInit();
static void _StaticCleanup();
static void _StaticCacheCleanup();
enum { sNumReplyPorts = 3 };
static port_id sReplyPorts[sNumReplyPorts];
static long sReplyPortInUse[sNumReplyPorts];
static int32 sGetCachedReplyPort();
static BBlockCache *sMsgCache;
struct dyn_array {
int32 fLogicalBytes;
int32 fPhysicalBytes;
int32 fChunkSize;
int32 fCount;
int32 fEntryHdrSize;
};
struct entry_hdr : public dyn_array {
entry_hdr *fNext;
uint32 fType;
uchar fNameLength;
char fName[1];
};
struct var_chunk {
int32 fDataSize;
char fData[1];
};
entry_hdr *entry_find(const char *name, uint32 type,status_t *result=NULL) const;
void entry_remove(entry_hdr *entry);
void *da_create(int32 header_size, int32 chunk_size,
bool fixed, int32 nchunks);
status_t da_add_data(dyn_array **da, const void *data, int32 size);
void *da_find_data(dyn_array *da, int32 index,
int32 *size = NULL) const;
status_t da_delete_data(dyn_array **pda, int32 index);
status_t da_replace_data(dyn_array **pda, int32 index,
const void *data, int32 dsize);
int32 da_calc_size(int32 hdr_size, int32 chunksize,
bool is_fixed, int32 nchunks) const;
void *da_grow(dyn_array **pda, int32 increase);
void da_dump(dyn_array *da);
int32 da_chunk_hdr_size() const
{ return sizeof(int32); }
int32 da_chunk_size(var_chunk *v) const
{ return (v->fDataSize + da_chunk_hdr_size() + 7) & ~7; }
var_chunk *da_first_chunk(dyn_array *da) const
{ return (var_chunk *) da_start_of_data(da); }
var_chunk *da_next_chunk(var_chunk *v) const
{ return (var_chunk *) (((char*) v) + da_chunk_size(v)); }
var_chunk *da_chunk_ptr(void *data) const
{ return (var_chunk*) (((char *) data) - da_chunk_hdr_size()); }
int32 da_pad_8(int32 val) const
{ return (val + 7) & ~7; }
int32 da_total_size(dyn_array *da) const
{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
da->fPhysicalBytes; }
int32 da_total_logical_size(dyn_array *da) const
{ return (int32)sizeof(dyn_array) + da->fEntryHdrSize +
da->fLogicalBytes; }
char *da_start_of_data(dyn_array *da) const
{ return ((char *) da) + (sizeof(dyn_array) +
da->fEntryHdrSize); }
bool da_is_mini_data(dyn_array *da) const
{ return ((da->fLogicalBytes <= (int32) UCHAR_MAX) &&
(da->fCount <= (int32) UCHAR_MAX));}
void da_swap_var_sized(dyn_array *da);
void da_swap_fixed_sized(dyn_array *da);
BMessage *fQueueLink;
int32 fTarget;
BMessage *fOriginal;
uint32 fChangeCount;
int32 fCurSpecifier;
uint32 fPtrOffset;
// ejaesler: Stealing one for my whacky BMessageBody l33tness
uint32 _reserved[2];
BPrivate::BMessageBody* fBody;
BMessage::entry_hdr *fEntries;
struct reply_to_info {
port_id port;
int32 target;
team_id team;
bool preferred;
} fReplyTo;
bool fPreferred;
bool fReplyRequired;
bool fReplyDone;
bool fIsReply;
bool fWasDelivered;
bool fReadOnly;
bool fHasSpecifiers;
};
#endif // _MESSAGE_H
#endif // USING_MESSAGE4

View File

@ -1,256 +0,0 @@
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: MessageBody.h
// Author(s): Erik Jaesler (erik@cgsoftware.com)
// Description: BMessageBody handles data storage and retrieval for
// BMessage.
//------------------------------------------------------------------------------
#ifndef MESSAGEBODY_H
#define MESSAGEBODY_H
#include <MessageField.h>
// Standard Includes -----------------------------------------------------------
#include <map>
#include <new>
#include <stdio.h>
#include <string>
// System Includes -------------------------------------------------------------
#include <Entry.h>
#include <Path.h>
#include <Point.h>
#include <Rect.h>
//#include <StreamIO.h>
#include <String.h>
#include <SupportDefs.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
enum { B_FLATTENABLE_TYPE = 'FLAT' };
using namespace std;
namespace BPrivate {
class BMessageBody
{
public:
BMessageBody();
BMessageBody(const BMessageBody& rhs);
~BMessageBody();
BMessageBody& operator=(const BMessageBody& rhs);
// Statistics and misc info
status_t GetInfo(type_code typeRequested, int32 which, char **name,
type_code *typeReturned, int32 *count = NULL) const;
status_t GetInfo(const char *name, type_code *type, int32 *c = 0) const;
status_t GetInfo(const char *name, type_code *type, bool *fixed_size) const;
int32 CountNames(type_code type) const;
bool IsEmpty() const;
bool IsSystem() const;
bool IsReply() const;
void PrintToStream() const;
status_t Rename(const char *old_entry, const char *new_entry);
// Flattening data
ssize_t FlattenedSize() const;
status_t Flatten(BDataIO *stream) const;
// Removing data
status_t RemoveData(const char *name, int32 index = 0);
status_t RemoveName(const char *name);
status_t MakeEmpty();
bool HasData(const char* name, type_code t, int32 n) const;
template<class T1>
status_t AddData(const char* name, const T1& data, type_code type);
status_t AddData(const char* name, type_code type, const void* data, ssize_t numBytes, bool is_fixed_size, int32);
status_t FindData(const char* name, type_code type, int32 index,
const void** data, ssize_t* numBytes) const;
template<class T1>
status_t FindData(const char* name, int32 index, T1* data, type_code type);
template<class T1>
status_t ReplaceData(const char* name, int32 index, const T1& data, type_code type);
#if 0
void *operator new(size_t size);
void operator delete(void *ptr, size_t size);
#endif
private:
BMessageField* FindData(const char *name, type_code type,
status_t& err) const;
typedef std::map<std::string, BMessageField*> TMsgDataMap;
TMsgDataMap fData;
ssize_t fFlattenedSize;
};
//------------------------------------------------------------------------------
template<class T1>
status_t BMessageBody::AddData(const char *name, const T1 &data, type_code type)
{
// The flattened message format in R5 only allows 1 byte
// for the length of field names
if (!name || (strlen(name) > 255)) return B_BAD_VALUE;
status_t err = B_OK;
BMessageField* BMF = FindData(name, type, err);
if (err)
{
if (err == B_NAME_NOT_FOUND)
{
// Reset err; we'll create the field
err = B_OK;
}
else
{
// Looking for B_BAD_TYPE here in particular, which would indicate
// that we tried to add data of type X when we already had data of
// type Y with the same name
return err;
}
}
if (!BMF)
{
BMF = new(nothrow) BMessageFieldImpl<T1>(name, type);
if (BMF)
{
fData[name] = BMF;
}
else
{
err = B_NO_MEMORY;
}
}
if (!err)
{
BMessageFieldImpl<T1>* RItem =
dynamic_cast<BMessageFieldImpl<T1>*>(BMF);
if (!RItem)
{
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me\033[m screwed\n\n");
}
RItem->AddItem(data);
}
return err;
}
//------------------------------------------------------------------------------
template<class T1>
status_t BMessageBody::FindData(const char *name, int32 index, T1 *data,
type_code type)
{
if (!name)
{
return B_BAD_VALUE;
}
if (index < 0)
{
return B_BAD_INDEX;
}
status_t err = B_OK;
BMessageField* Item = FindData(name, type, err);
if (Item)
{
BMessageFieldImpl<T1>* RItem =
dynamic_cast<BMessageFieldImpl<T1>*>(Item);
if (!RItem)
{
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me"
"\033[m screwed\n\n");
}
if (index < RItem->CountItems())
{
*data = RItem->Data()[index];
}
else
{
err = B_BAD_INDEX;
}
}
return err;
}
//------------------------------------------------------------------------------
template<class T1>
status_t BMessageBody::ReplaceData(const char *name, int32 index,
const T1 &data, type_code type)
{
if (!name)
{
return B_BAD_VALUE;
}
if (index < 0)
{
return B_BAD_INDEX;
}
status_t err = B_OK;
BMessageField* Item = FindData(name, type, err);
if (Item)
{
BMessageFieldImpl<T1>* RItem =
dynamic_cast<BMessageFieldImpl<T1>*>(Item);
if (!RItem)
{
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me\033[m screwed\n\n");
}
if (index < (int32)RItem->Data().Size())
{
RItem->Data()[index] = data;
}
else
{
err = B_BAD_INDEX;
}
}
return err;
}
//------------------------------------------------------------------------------
} // namespace BPrivate
#endif //MESSAGEBODY_H
/*
* $Log $
*
* $Id $
*
*/

View File

@ -1,791 +0,0 @@
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: MessageField.h
// Author(s): Erik Jaesler (erik@cgsoftware.com)
// Description: BMessageField contains and manages the data for indiviual
// named field in BMessageBody
//------------------------------------------------------------------------------
#ifndef MESSAGEFIELD_H
#define MESSAGEFIELD_H
// Standard Includes -----------------------------------------------------------
#include <new>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <string>
// System Includes -------------------------------------------------------------
#include <Entry.h>
#include <Path.h>
#include <Point.h>
#include <Rect.h>
#include <String.h>
#include <SupportDefs.h>
// Project Includes ------------------------------------------------------------
#include <DataBuffer.h>
#include <MessageUtils.h>
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// flags for each entry (the bitfield is 1 byte)
#define MSG_FLAG_VALID 0x01
#define MSG_FLAG_MINI_DATA 0x02
#define MSG_FLAG_FIXED_SIZE 0x04
#define MSG_FLAG_SINGLE_ITEM 0x08
#define MSG_FLAG_ALL 0x0F
#define MSG_LAST_ENTRY 0x0
using namespace std;
// Globals ---------------------------------------------------------------------
namespace BPrivate {
class BMessageField
{
public:
static const char* sNullData;
BMessageField(const std::string& name, type_code t)
: fType(t), fName(name)
{;}
virtual ~BMessageField() {}
virtual const std::string& Name() const { return fName; }
virtual type_code Type() const { return fType; }
virtual bool FixedSize() const { return true; }
virtual ssize_t FlattenedSize() const { return 0; }
virtual status_t Flatten(BDataIO& stream) const = 0;
virtual ssize_t CountItems() const { return 0; }
virtual void RemoveItem(ssize_t index) = 0;
virtual void PrintToStream(const char* name) const;
virtual const void* DataAt(int32 index, ssize_t* size) const = 0;
virtual BMessageField* Clone() const = 0;
protected:
virtual void PrintDataItem(int32 index) const = 0;
private:
type_code fType;
std::string fName;
};
//------------------------------------------------------------------------------
template<class T>
struct BMessageFieldStoragePolicy
{
class Store
{
public:
// Compiler-generated versions should be just fine
#if 0
Store();
Store(const Store& rhs);
~Store();
Store& operator=(const Store& rhs);
#endif
inline size_t Size() const { return fData.size(); }
inline T& operator[](uint index) { return fData[index]; }
inline const T& operator[](uint index) const { return fData[index]; }
inline void Add(const T& data) { fData.push_back(data); }
inline void Remove(uint index) { fData.erase(fData.begin() + index); }
inline void Copy(const Store& rhs) { fData = rhs.fData; }
private:
std::vector<T> fData;
};
};
//------------------------------------------------------------------------------
template<class T>
struct BMessageFieldSizePolicy
{
typedef typename BMessageFieldStoragePolicy<T>::Store Store;
inline static size_t Size(const T&) { return sizeof (T); }
inline static size_t Size(const Store& data)
{
return sizeof (T) * data.Size();
}
inline static bool Fixed() { return true; }
inline static size_t Padding(const T&) { return 0; }
inline static size_t Padding(const Store& data) { return 0; }
};
//------------------------------------------------------------------------------
template<class T>
struct BMessageFieldPrintPolicy
{
static void PrintData(const T& data) {;}
};
//------------------------------------------------------------------------------
template<class T>
struct BMessageFieldFlattenPolicy
{
typedef BMessageFieldSizePolicy<T> SizePolicy;
inline static status_t Flatten(BDataIO& stream, const T& data)
{
return stream.Write((const void*)&data, SizePolicy::Size(data));
}
};
//------------------------------------------------------------------------------
template<class T>
struct BMessageFieldGetDataPolicy
{
inline static const void* GetData(const T* data)
{ return (const void*)data; }
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy = BMessageFieldStoragePolicy<T1>,
class SizePolicy = BMessageFieldSizePolicy<T1>,
class PrintPolicy = BMessageFieldPrintPolicy<T1>,
class FlattenPolicy = BMessageFieldFlattenPolicy<T1>,
class GetDataPolicy = BMessageFieldGetDataPolicy<T1>
>
class BMessageFieldImpl : public BMessageField
{
public:
typedef typename StoragePolicy::Store StorageType;
BMessageFieldImpl(const std::string& name, type_code type)
: BMessageField(name, type),
fMaxSize(0),
fFlags(MSG_FLAG_ALL)
{;}
virtual ~BMessageFieldImpl() {}
virtual bool FixedSize() const
{ return fFlags & MSG_FLAG_FIXED_SIZE; }
virtual ssize_t FlattenedSize() const;
virtual status_t Flatten(BDataIO& stream) const;
virtual ssize_t CountItems() const { return fData.Size(); }
virtual void AddItem(const T1& data);
virtual void RemoveItem(ssize_t index)
{ fData.Remove(index); };
virtual const void* DataAt(int32 index, ssize_t* size) const;
virtual BMessageField* Clone() const;
StorageType& Data() { return fData; }
protected:
virtual void PrintDataItem(int32 index) const;
private:
StorageType fData;
size_t fMaxSize;
uchar fFlags;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
ssize_t
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
FlattenedSize() const
{
// Mandatory stuff
ssize_t size = 1; // field flags byte
size += sizeof (type_code); // field type bytes
if (!(fFlags & MSG_FLAG_SINGLE_ITEM)) // item count byte
{
if (fFlags & MSG_FLAG_MINI_DATA)
++size; // item count byte for mini data
else
size += 4; // item count bytes for maxi data
}
if (fFlags & MSG_FLAG_MINI_DATA)
++size; // data length byte for mini data
else
size += 4; // data length bytes for maxi data
++size; // name length byte
size += Name().length(); // name length
// item data length
size += SizePolicy::Size(fData);
// Calculate any necessary padding
if (!SizePolicy::Fixed())
{
size += 4 * fData.Size();
size += SizePolicy::Padding(fData);
#if 0
for (uint32 i = 0; i < fData.Size(); ++i)
{
// pad to 8-byte boundary, including size bytes in calculation
size += calc_padding(SizePolicy::Size(fData[i]) + 4, 8);
// item size bytes
size += 4;
}
#endif
}
return size;
}
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
status_t
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
Flatten(BDataIO& stream) const
{
status_t err = B_OK;
type_code type = Type();
uint32 count = fData.Size();
uint8 nameLen = Name().length();
size_t size = SizePolicy::Size(fData);
err = stream.Write(&fFlags, sizeof (fFlags));
// Field type_code
if (err >= 0)
err = stream.Write(&type, sizeof (type_code));
// Item count, if more than one
if (err >= 0 && !(fFlags & MSG_FLAG_SINGLE_ITEM))
{
if (fFlags & MSG_FLAG_MINI_DATA)
{
uint8 miniCount = count;
err = stream.Write(&miniCount, sizeof (miniCount));
}
else
{
err = stream.Write(&count, sizeof (count));
}
}
// Data length
if (err >= 0)
{
if (!(fFlags & MSG_FLAG_FIXED_SIZE))
{
// Add the bytes for holding the item size for each item
size += 4 * fData.Size();
size += SizePolicy::Padding(fData);
}
if (fFlags & MSG_FLAG_MINI_DATA)
{
uint8 miniSize = size;
err = stream.Write(&miniSize, sizeof (miniSize));
}
else
{
err = stream.Write(&size, sizeof (size));
}
}
// Name length
if (err >= 0)
err = stream.Write(&nameLen, sizeof (nameLen));
// Name
if (err >= 0)
err = stream.Write(Name().c_str(), Name().length());
// Actual data items
for (uint32 i = 0; i < fData.Size() && err >= 0; ++i)
{
if (!SizePolicy::Fixed())
{
size = (int32)SizePolicy::Size(fData[i]);
err = stream.Write(&size, sizeof (size));
}
if (err >= 0)
{
err = FlattenPolicy::Flatten(stream, fData[i]);
}
if (err >= 0 && !SizePolicy::Fixed())
{
// Add any necessary padding
err = stream.Write(BMessageField::sNullData,
SizePolicy::Padding(fData[i]));
}
}
if (err >= 0)
err = B_OK;
return err;
}
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
void
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
AddItem(const T1& data)
{
fData.Add(data);
if (fMaxSize)
{
if ((fFlags & MSG_FLAG_FIXED_SIZE) &&
(!SizePolicy::Fixed() ||
fMaxSize != SizePolicy::Size(data)))
{
fMaxSize = max(SizePolicy::Size(data), fMaxSize);
fFlags &= ~MSG_FLAG_FIXED_SIZE;
}
}
else
{
if (!SizePolicy::Fixed())
{
fFlags &= ~MSG_FLAG_FIXED_SIZE;
}
fMaxSize = SizePolicy::Size(data);
}
if (fFlags & MSG_FLAG_MINI_DATA)
{
int32 size = SizePolicy::Size(fData);
if (!(fFlags & MSG_FLAG_FIXED_SIZE))
{
size += 4 * fData.Size();
size += SizePolicy::Padding(fData);
}
if (size > 255)
fFlags &= ~MSG_FLAG_MINI_DATA;
}
if (fData.Size() > 1)
fFlags &= ~MSG_FLAG_SINGLE_ITEM;
}
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
const void*
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
DataAt(int32 index, ssize_t* size) const
{
if (index < CountItems())
{
*size = SizePolicy::Size(fData[index]);
const T1& ref = fData[index];
const T1* data = &ref;
return GetDataPolicy::GetData(data);//(const void*)data;
}
return NULL;
}
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
BMessageField*
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
Clone() const
{
BMessageFieldImpl<T1>* BMF =
new(nothrow) BMessageFieldImpl<T1>(Name(), Type());
if (BMF)
{
BMF->fMaxSize = fMaxSize;
BMF->fFlags = fFlags;
BMF->fData.Copy(fData);
}
return BMF;
}
//------------------------------------------------------------------------------
template
<
class T1,
class StoragePolicy,
class SizePolicy,
class PrintPolicy,
class FlattenPolicy,
class GetDataPolicy
>
void
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy, GetDataPolicy>::
PrintDataItem(int32 index) const
{
if (index && FixedSize())
{
std::printf(" ");
}
else
{
std::printf("size=%2ld, ", SizePolicy::Size(fData[index]));
}
std::printf("data[%ld]: ", index);
PrintPolicy::PrintData(fData[index]);
}
//------------------------------------------------------------------------------
// Print policy specializations ------------------------------------------------
template<> struct BMessageFieldPrintPolicy<bool>
{
static void PrintData(const bool& b) { std::printf("%d", int(b)); }
};
template<> struct BMessageFieldPrintPolicy<int8>
{
static void PrintData(const int8& i)
{ std::printf("0x%X (%d, '%c')", int(i), int(i), char(i)); }
};
template<> struct BMessageFieldPrintPolicy<int16>
{
static void PrintData(const int16& i)
{ std::printf("0x%X (%d, '%c')", i, i, char(i)); }
};
template<> struct BMessageFieldPrintPolicy<int32>
{
static void PrintData(const int32& i)
{ std::printf("0x%lX (%ld, '%c')", i, i, char(i)); }
};
template<> struct BMessageFieldPrintPolicy<int64>
{
static void PrintData(const int64& i)
{ std::printf("0x%LX (%Ld, '%c')", i, i, char(i)); }
};
template<> struct BMessageFieldPrintPolicy<float>
{
static void PrintData(const float& f) { std::printf("%.4f", f); }
};
template<> struct BMessageFieldPrintPolicy<double>
{
static void PrintData(const double& d) { std::printf("%.8f", d); }
};
template<> struct BMessageFieldPrintPolicy<BString>
{
static void PrintData(const BString& s) { std::printf("\"%s\"", s.String()); }
};
template<> struct BMessageFieldPrintPolicy<BPoint>
{
static void PrintData(const BPoint& p) { std::printf("BPoint(x:%.1f, y:%.1f)", p.x, p.y); }
};
template<> struct BMessageFieldPrintPolicy<BRect>
{
static void PrintData(const BRect& r)
{ std::printf("BRect(l:%.1f, t:%.1f, r:%.1f, b:%.1f)", r.left, r.top, r.right, r.bottom); }
};
template<> struct BMessageFieldPrintPolicy<entry_ref>
{
static void PrintData(const entry_ref& ref)
{
std::printf("device=%ld, directory=%Ld, name=\"%s\", path=\"%s\"",
ref.device, ref.directory, ref.name, BPath(&ref).Path());
}
};
// Storage policy specializations ----------------------------------------------
template<>
struct BMessageFieldStoragePolicy<bool>
{
class Store
{
private:
struct Boolean
{
Boolean() : data(bool()) {;}
Boolean(bool b) : data(b) {;}
bool data;
};
public:
inline size_t Size() const
{ return fData.size(); }
inline bool& operator[](uint index)
{ return fData[index].data; }
inline const bool& operator[](uint index) const
{ return fData[index].data; }
inline void Add(const bool& data)
{
fData.push_back(data);
}
inline void Remove(uint index)
{
fData.erase(fData.begin() + index);
}
inline void Copy(const Store& rhs)
{
if (&fData != &rhs.fData)
{
fData = rhs.fData;
}
}
private:
std::vector<Boolean> fData;
};
};
//------------------------------------------------------------------------------
template<>
struct BMessageFieldStoragePolicy<BDataBuffer>
{
class Store
{
public:
inline size_t Size() const
{ return fData.size(); }
inline BDataBuffer& operator[](uint index)
{ return fData[index]; }
inline const BDataBuffer& operator[](uint index) const
{ return fData[index]; }
inline void Add(const BDataBuffer& data)
{ fData.push_back(data); }
inline void Remove(uint index)
{ fData.erase(fData.begin() + index); }
void Copy(const Store& rhs)
{
if (&fData == &rhs.fData)
{
return;
}
fData.clear();
for (size_t i = 0; i < rhs.Size(); ++i)
{
Add(BDataBuffer(rhs[i], true));
}
}
private:
std::vector<BDataBuffer> fData;
};
};
// Size policy specializations -------------------------------------------------
template<> struct BMessageFieldSizePolicy<BString>
{
typedef BMessageFieldStoragePolicy<BString>::Store Store;
inline static size_t Size(const BString& s) { return s.Length() + 1; }
inline static size_t Size(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Size(data[i]);
}
return size;
}
inline static bool Fixed() { return false; }
inline static size_t Padding(const BString& s)
{
// Padding calculations are only done for variable-sized items,
// which by definition have four bytes of size info preceeding the
// actual data; those four bytes are included in the padding
// calculation. Padding is calculated to an 8-byte boundary
return calc_padding(Size(s) + 4, 8);
}
inline static size_t Padding(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Padding(data[i]);
}
return size;
}
};
//------------------------------------------------------------------------------
template<> struct BMessageFieldSizePolicy<BDataBuffer>
{
typedef BMessageFieldStoragePolicy<BDataBuffer>::Store Store;
inline static size_t Size(const BDataBuffer& db)
{ return db.BufferSize(); }
inline static size_t Size(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Size(data[i]);
}
return size;
}
inline static bool Fixed() { return false; }
inline static size_t Padding(const BDataBuffer& db)
{
// Padding calculations are only done for variable-sized items,
// which by definition have four bytes of size info preceeding the
// actual data; those four bytes are included in the padding
// calculation. Padding is calculated to an 8-byte boundary
return calc_padding(Size(db) + 4, 8);
}
inline static size_t Padding(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Padding(data[i]);
}
return size;
}
};
//------------------------------------------------------------------------------
template<> struct BMessageFieldSizePolicy<BMessage*>
{
typedef BMessageFieldStoragePolicy<BMessage*>::Store Store;
inline static size_t Size(const BMessage* msg)
{ return msg->FlattenedSize(); }
inline static size_t Size(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Size(data[i]);
}
return size;
}
inline static bool Fixed() { return false; }
inline static size_t Padding(const BMessage* msg)
{
// Padding calculations are only done for variable-sized items,
// which by definition have four bytes of size info preceeding the
// actual data; those four bytes are included in the padding
// calculation. Padding is calculated to an 8-byte boundary
return calc_padding(Size(msg) + 4, 8);
}
inline static size_t Padding(const Store& data)
{
size_t size = 0;
for (uint32 i = 0; i < data.Size(); ++i)
{
size += Padding(data[i]);
}
return size;
}
};
// Flatten policy specializations ----------------------------------------------
template<>
struct BMessageFieldFlattenPolicy<BString>
{
typedef BMessageFieldSizePolicy<BString> SizePolicy;
static status_t Flatten(BDataIO& stream, const BString& data)
{
size_t size = SizePolicy::Size(data);
status_t err = stream.Write((const void*)data.String(), size);
if (err > 0)
err = B_OK;
return err;
}
};
//------------------------------------------------------------------------------
template<>
struct BMessageFieldFlattenPolicy<BMessage*>
{
typedef BMessageFieldSizePolicy<BMessage*> SizePolicy;
static status_t Flatten(BDataIO& stream, const BMessage* data)
{
status_t err = data->Flatten(&stream);
if (err > 0)
err = B_OK;
return err;
}
};
//------------------------------------------------------------------------------
template<>
struct BMessageFieldFlattenPolicy<BDataBuffer>
{
typedef BMessageFieldSizePolicy<BDataBuffer> SizePolicy;
static status_t Flatten(BDataIO& stream, const BDataBuffer& db)
{
size_t size = SizePolicy::Size(db);
status_t err = stream.Write(db.Buffer(), size);
if (err > 0)
err = B_OK;
return err;
}
};
// GetData policy specializations ----------------------------------------------
template<>
struct BMessageFieldGetDataPolicy<BDataBuffer>
{
inline static const void* GetData(const BDataBuffer* data)
{ return data->Buffer(); }
};
//------------------------------------------------------------------------------
template<>
struct BMessageFieldGetDataPolicy<BString>
{
inline static const void* GetData(const BString* data)
{ return data->String(); }
};
//------------------------------------------------------------------------------
} // namespace BPrivate
#endif // MESSAGEFIELD_H
/*
* $Log $
*
* $Id $
*
*/

View File

@ -1,83 +0,0 @@
//------------------------------------------------------------------------------
// MessagePrivate.h
//
//------------------------------------------------------------------------------
#ifdef USING_MESSAGE4
# include <MessagePrivate4.h>
#else
#ifndef MESSAGEPRIVATE_H
#define MESSAGEPRIVATE_H
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <TokenSpace.h>
class BMessage::Private {
public:
Private(BMessage* msg) : fMessage(msg) {;}
Private(BMessage& msg) : fMessage(&msg) {;}
inline void SetTarget(int32 token)
{
fMessage->fTarget = token;
fMessage->fPreferred = token == B_PREFERRED_TOKEN;
}
inline void SetReply(team_id team, port_id port, int32 token)
{
fMessage->fReplyTo.port = port;
fMessage->fReplyTo.target = token;
fMessage->fReplyTo.team = team;
fMessage->fReplyTo.preferred = token == B_PREFERRED_TOKEN;
}
inline void SetReply(BMessenger messenger)
{
BMessenger::Private mp(messenger);
fMessage->fReplyTo.port = mp.Port();
fMessage->fReplyTo.target = mp.Token();
fMessage->fReplyTo.team = mp.Team();
fMessage->fReplyTo.preferred = mp.IsPreferredTarget();
}
inline int32 GetTarget()
{
return fMessage->fTarget;
}
inline bool UsePreferredTarget()
{
return fMessage->fPreferred;
}
static inline status_t SendFlattenedMessage(void *data, int32 size,
port_id port, int32 token, bigtime_t timeout)
{
return BMessage::_SendFlattenedMessage(data, size, port, token,
timeout);
}
static inline void StaticInit()
{
BMessage::_StaticInit();
}
static inline void StaticCleanup()
{
BMessage::_StaticCleanup();
}
static inline void StaticCacheCleanup()
{
BMessage::_StaticCacheCleanup();
}
private:
BMessage* fMessage;
};
#endif // MESSAGEPRIVATE_H
#endif // USING_MESSAGE4

View File

@ -1,205 +0,0 @@
#ifdef USING_MESSAGE4
# include <MessageUtils4.h>
#else
//------------------------------------------------------------------------------
// MessageUtils.h
//
//------------------------------------------------------------------------------
#ifndef MESSAGEUTILS_H
#define MESSAGEUTILS_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <ByteOrder.h>
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <SupportDefs.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
uint32 _checksum_(const uchar *buf, int32 size);
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);
size_t calc_padding(size_t size, size_t boundary);
} // namespace BPrivate
//------------------------------------------------------------------------------
// _set_message_target_
/*! \brief Sets the target of a message.
\param message The message.
\param token The target handler token.
\param preferred Indicates whether to use the looper's preferred handler.
*/
inline
void
_set_message_target_(BMessage *message, int32 token, bool preferred)
{
message->fTarget = token;
message->fPreferred = preferred;
}
//------------------------------------------------------------------------------
// _set_message_reply_
/*! \brief Sets a message's reply target.
\param message The message.
\param messenger The reply messenger.
*/
inline
void
_set_message_reply_(BMessage *message, BMessenger messenger)
{
BMessenger::Private messengerPrivate(messenger);
message->fReplyTo.port = messengerPrivate.Port();
message->fReplyTo.target = messengerPrivate.Token();
message->fReplyTo.team = messengerPrivate.Team();
message->fReplyTo.preferred = messengerPrivate.IsPreferredTarget();
}
//------------------------------------------------------------------------------
inline int32 _get_message_target_(BMessage *msg)
{
return msg->fTarget;
}
//------------------------------------------------------------------------------
inline bool _use_preferred_target_(BMessage *msg)
{
return msg->fPreferred;
}
//------------------------------------------------------------------------------
inline status_t normalize_err(status_t err)
{
return err >= 0 ? B_OK : err;
}
//------------------------------------------------------------------------------
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& err)
{
err = normalize_err(stream->Write(data, size));
}
//------------------------------------------------------------------------------
// Will the template madness never cease??
template<class T>
inline status_t write_helper(BDataIO* stream, T& data, status_t& err)
{
return normalize_err(stream->Write((const void*)data, sizeof (T)));
}
//------------------------------------------------------------------------------
class TReadHelper
{
public:
TReadHelper(BDataIO* stream)
: fStream(stream), err(B_OK), fSwap(false)
{
;
}
TReadHelper(BDataIO* stream, bool swap)
: fStream(stream), err(B_OK), fSwap(swap)
{
;
}
template<class T> inline void operator()(T& data)
{
err = normalize_err(fStream->Read((void*)&data, sizeof (T)));
if (err)
throw err;
if (IsSwapping())
{
byte_swap(data);
}
}
template<class T> inline void operator()(T data, size_t len)
{
err = normalize_err(fStream->Read((void*)data, len));
if (err)
throw err;
}
status_t Status() { return err; }
void SetSwap(bool yesNo) { fSwap = yesNo; }
bool IsSwapping() { return fSwap; }
private:
BDataIO* fStream;
status_t err;
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 // MESSAGEUTILS_H
#endif // USING_MESSAGE4

File diff suppressed because it is too large Load Diff

View File

@ -1,400 +0,0 @@
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: MessageBody.cpp
// Author(s): Erik Jaesler (erik@cgsoftware.com)
// Description: BMessageBody handles data storage and retrieval for
// BMessage.
//------------------------------------------------------------------------------
#ifndef USING_MESSAGE4
// Standard Includes -----------------------------------------------------------
#include <stdio.h>
// System Includes -------------------------------------------------------------
#include <TypeConstants.h>
// Project Includes ------------------------------------------------------------
#include <MessageBody.h>
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
namespace BPrivate {
//------------------------------------------------------------------------------
BMessageBody::BMessageBody()
: fFlattenedSize(0)
{
}
//------------------------------------------------------------------------------
BMessageBody::BMessageBody(const BMessageBody &rhs)
{
*this = rhs;
}
//------------------------------------------------------------------------------
BMessageBody::~BMessageBody()
{
MakeEmpty();
}
//------------------------------------------------------------------------------
BMessageBody& BMessageBody::operator=(const BMessageBody &rhs)
{
if (this != &rhs)
{
MakeEmpty();
for (TMsgDataMap::const_iterator i = rhs.fData.begin();
i != rhs.fData.end();
++i)
{
BMessageField* BMF = i->second;
fData[BMF->Name()] = BMF->Clone();
}
fFlattenedSize = rhs.fFlattenedSize;
}
return *this;
}
//------------------------------------------------------------------------------
status_t BMessageBody::GetInfo(type_code typeRequested, int32 which,
char** name, type_code* typeReturned,
int32* count) const
{
TMsgDataMap::const_iterator i = fData.begin();
int32 index = 0;
for (index = 0; i != fData.end(); ++i)
{
if (B_ANY_TYPE == typeRequested || i->second->Type() == typeRequested)
{
if (index == which)
{
break;
}
++index;
}
}
// We couldn't find any appropriate data
if (i == fData.end())
{
// TODO: research
// Which gets returned on an empty message with
// typeRequested == B_ANY_TYPE?
if (index)
{
// TODO: research
// Is B_NAME_NOT_FOUND ever really returned from this function, as
// the BeBook claims?
return B_BAD_INDEX;
}
else
{
if (count) *count = 0;
return B_BAD_TYPE;
}
}
// TODO: BC Break
// Change 'name' parameter to const char*
*name = const_cast<char*>(i->first.c_str());
*typeReturned = i->second->Type();
if (count) *count = i->second->CountItems();
return B_OK;
}
//------------------------------------------------------------------------------
status_t BMessageBody::GetInfo(const char* name, type_code* type,
int32* c) const
{
status_t err;
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
if (BMF) {
if (type)
*type = BMF->Type();
if (c)
*c = BMF->CountItems();
} else if (c)
*c = 0;
return err;
}
//------------------------------------------------------------------------------
status_t BMessageBody::GetInfo(const char* name, type_code* type,
bool* fixed_size) const
{
status_t err;
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
if (BMF)
{
*type = BMF->Type();
*fixed_size = BMF->FixedSize();
}
return err;
}
//------------------------------------------------------------------------------
int32 BMessageBody::CountNames(type_code type) const
{
if (type == B_ANY_TYPE)
{
return fData.size();
}
int32 count = 0;
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
{
if (type == B_ANY_TYPE || i->second->Type() == type)
{
++count;
}
}
return count;
}
//------------------------------------------------------------------------------
bool BMessageBody::IsEmpty() const
{
return fData.empty();
}
//------------------------------------------------------------------------------
void BMessageBody::PrintToStream() const
{
// TODO: test
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
{
i->second->PrintToStream(i->first.c_str());
printf("\n");
}
}
//------------------------------------------------------------------------------
status_t BMessageBody::Rename(const char* old_entry, const char* new_entry)
{
TMsgDataMap::iterator i = fData.find(old_entry);
if (i == fData.end())
{
return B_NAME_NOT_FOUND;
}
BMessageField* BMF = i->second;
RemoveName(new_entry);
fData[new_entry] = BMF;
fData.erase(old_entry);
return B_OK;
}
//------------------------------------------------------------------------------
ssize_t BMessageBody::FlattenedSize() const
{
ssize_t size = 1; // For MSG_LAST_ENTRY
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
{
BMessageField* BMF = i->second;
size += BMF->FlattenedSize();
}
return size;
}
//------------------------------------------------------------------------------
status_t BMessageBody::Flatten(BDataIO* stream) const
{
status_t err = B_OK;
for (TMsgDataMap::const_iterator i = fData.begin();
i != fData.end() && !err;
++i)
{
BMessageField* BMF = i->second;
err = BMF->Flatten(*stream);
}
if (!err)
{
err = stream->Write("", 1); // For MSG_LAST_ENTRY
if (err >= 0)
err = B_OK;
}
return err;
}
//------------------------------------------------------------------------------
status_t BMessageBody::AddData(const char* name, type_code type,
const void* data, ssize_t numBytes,
bool is_fixed_size, int32 /* count */)
{
/**
@note The same logic applies here are in AddFlat(): is_fixed_size and
count aren't useful to us because dynamically adding items isn't
an issue. Nevertheless, we keep is_fixed_size to set flags
appropriately when flattening the message.
*/
// TODO: test
// In particular, we want to see what happens if is_fixed_size == true and
// the user attempts to add something bigger or smaller. We may need to
// enforce the size thing.
return B_ERROR;
}
//------------------------------------------------------------------------------
status_t BMessageBody::RemoveData(const char* name, int32 index)
{
if (index < 0)
{
return B_BAD_VALUE;
}
status_t err = B_OK;
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
if (BMF)
{
if (index < BMF->CountItems())
{
BMF->RemoveItem(index);
if (!BMF->CountItems())
{
RemoveName(name);
}
}
else
{
err = B_BAD_INDEX;
}
}
return err;
}
//------------------------------------------------------------------------------
status_t BMessageBody::RemoveName(const char* name)
{
TMsgDataMap::iterator i = fData.find(name);
if (i == fData.end())
{
return B_NAME_NOT_FOUND;
}
delete i->second;
fData.erase(i);
return B_OK;
}
//------------------------------------------------------------------------------
status_t BMessageBody::MakeEmpty()
{
for (TMsgDataMap::iterator i = fData.begin();
i != fData.end();
++i)
{
delete i->second;
}
fData.clear();
return B_OK;
}
//------------------------------------------------------------------------------
#if 0
void* BMessageBody::operator new(size_t size)
{
return ::new BMessageBody;
}
//------------------------------------------------------------------------------
void BMessageBody::operator delete(void* ptr, size_t size)
{
::delete(ptr);
}
#endif
//------------------------------------------------------------------------------
bool BMessageBody::HasData(const char* name, type_code t, int32 n) const
{
if (!name || n < 0)
{
return false;
}
status_t err;
BMessageField* BMF = FindData(name, t, err);
if (!BMF)
{
return false;
}
if (n >= BMF->CountItems())
{
return false;
}
return true;
}
//------------------------------------------------------------------------------
status_t BMessageBody::FindData(const char *name, type_code type, int32 index,
const void **data, ssize_t *numBytes) const
{
status_t err;
*data = NULL;
BMessageField* Field = FindData(name, type, err);
if (!err)
{
*data = Field->DataAt(index, numBytes);
// TODO: verify
if (!*data)
{
err = B_BAD_INDEX;
}
}
return err;
}
//------------------------------------------------------------------------------
BMessageField* BMessageBody::FindData(const char* name, type_code type,
status_t& err) const
{
BMessageField* Item = NULL;
if (!name)
{
err = B_BAD_VALUE;
return Item;
}
err = B_OK;
TMsgDataMap::const_iterator i = fData.find(name);
if (i == fData.end())
{
err = B_NAME_NOT_FOUND;
}
else
{
Item = i->second;
if (type != B_ANY_TYPE && Item->Type() != type)
{
err = B_BAD_TYPE;
Item = NULL;
}
}
return Item;
}
//------------------------------------------------------------------------------
} // namespace BPrivate
#endif // USING_MESSAGE4

View File

@ -1,45 +0,0 @@
#ifndef USING_MESSAGE4
//------------------------------------------------------------------------------
// MessageField.cpp
//
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <ByteOrder.h>
// Project Includes ------------------------------------------------------------
#include "MessageField.h"
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
namespace BPrivate {
const char* BMessageField::sNullData = "\0\0\0\0\0\0\0\0";
//------------------------------------------------------------------------------
void BMessageField::PrintToStream(const char* name) const
{
int32 type = B_BENDIAN_TO_HOST_INT32(Type());
printf(" entry %14s, type='%.4s', c=%2ld, ",
name, (char*)&type, CountItems());
for (int32 i = 0; i < CountItems(); ++i)
{
if (i)
{
printf(" ");
}
PrintDataItem(i);
}
}
//------------------------------------------------------------------------------
} // namespace BPrivate
#endif // USING_MESSAGE4

View File

@ -1,135 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Erik Jaesler (erik@cgsoftware.com)
*/
#ifdef USING_MESSAGE4
# include "MessageUtils4.cpp"
#else
/** Extra messaging utility functions */
#include <string.h>
#include <ByteOrder.h>
#include <MessageUtils.h>
uint32
_checksum_(const uchar* buf, int32 size)
{
uint32 sum = 0;
uint32 temp = 0;
while (size > 3) {
#if defined(__INTEL__)
sum += B_SWAP_INT32(*(int*)buf);
#else
sum += *(int*)buf;
#endif
buf += 4;
size -= 4;
}
while (size > 0) {
temp = (temp << 8) + *buf++;
size -= 1;
}
return sum + temp;
}
namespace BPrivate { // Only putting these here because Be did
status_t
entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref)
{
memcpy((void*)buffer, (const void*)&ref->device, sizeof (ref->device));
buffer += sizeof (ref->device);
memcpy((void*)buffer, (const void*)&ref->directory, sizeof (ref->directory));
buffer += sizeof (ref->directory);
size_t len = 0;
if (ref->name) {
len = strlen(ref->name) + 1; // extra for NULL terminator
memcpy((void*)buffer, (const void*)ref->name, len);
}
*size = sizeof (ref->device) + sizeof (ref->directory) + len;
return B_OK;
}
status_t
entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size)
{
if (size < (sizeof (ref->device) + sizeof (ref->directory))) {
*ref = entry_ref();
return B_BAD_VALUE;
}
memcpy((void*)&ref->device, (const void*)buffer, sizeof (ref->device));
buffer += sizeof (ref->device);
memcpy((void*)&ref->directory, (const void*)buffer,
sizeof (ref->directory));
buffer += sizeof (ref->directory);
if (ref->device != -1
&& size > (sizeof (ref->device) + sizeof (ref->directory))) {
ref->set_name(buffer);
if (ref->name == NULL) {
*ref = entry_ref();
return B_NO_MEMORY;
}
} else
ref->set_name(NULL);
return B_OK;
}
status_t
entry_ref_swap(char* buffer, size_t size)
{
if (size < (sizeof (dev_t) + sizeof (ino_t)))
return B_BAD_DATA;
dev_t* dev = (dev_t*)buffer;
*dev = B_SWAP_INT32(*dev);
buffer += sizeof (dev_t);
ino_t* ino = (ino_t*)buffer;
*ino = B_SWAP_INT64(*ino);
return B_OK;
}
size_t
calc_padding(size_t size, size_t boundary)
{
size_t pad = size % boundary;
if (pad)
pad = boundary - pad;
return pad;
}
} // namespace BPrivate
// #pragma mark -
int32
TChecksumHelper::CheckSum()
{
return _checksum_(fBuffer, fBufPtr - fBuffer);
}
#endif // USING_MESSAGE4