From 85b31e1b69d40529bdb8c0b008131f456ab438c3 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 21 Nov 2005 18:47:51 +0000 Subject: [PATCH] Removing Message2 and Message3. They did not proof to be good enough so they don't need to take up space either. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15062 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/app/Message2.h | 454 ------ headers/private/app/Message3.h | 368 ----- headers/private/app/MessageBody2.h | 87 -- headers/private/app/MessageBody3.h | 103 -- headers/private/app/MessageField2.h | 96 -- headers/private/app/MessageField3.h | 120 -- headers/private/app/MessageUtils2.h | 222 --- headers/private/app/MessageUtils3.h | 230 --- src/kits/app/Message2.cpp | 2072 --------------------------- src/kits/app/Message3.cpp | 2034 -------------------------- src/kits/app/MessageBody2.cpp | 553 ------- src/kits/app/MessageBody3.cpp | 654 --------- src/kits/app/MessageField2.cpp | 348 ----- src/kits/app/MessageField3.cpp | 281 ---- 14 files changed, 7622 deletions(-) delete mode 100644 headers/private/app/Message2.h delete mode 100644 headers/private/app/Message3.h delete mode 100644 headers/private/app/MessageBody2.h delete mode 100644 headers/private/app/MessageBody3.h delete mode 100644 headers/private/app/MessageField2.h delete mode 100644 headers/private/app/MessageField3.h delete mode 100644 headers/private/app/MessageUtils2.h delete mode 100644 headers/private/app/MessageUtils3.h delete mode 100644 src/kits/app/Message2.cpp delete mode 100644 src/kits/app/Message3.cpp delete mode 100644 src/kits/app/MessageBody2.cpp delete mode 100644 src/kits/app/MessageBody3.cpp delete mode 100644 src/kits/app/MessageField2.cpp delete mode 100644 src/kits/app/MessageField3.cpp diff --git a/headers/private/app/Message2.h b/headers/private/app/Message2.h deleted file mode 100644 index 9a09b23c2c..0000000000 --- a/headers/private/app/Message2.h +++ /dev/null @@ -1,454 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku -// -// 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: Message.h -// Author(s): Erik Jaesler (erik@cgsoftware.com) -// DarkWyrm -// Description: BMessage class creates objects that store data and that -// can be processed in a message loop. BMessage objects -// are also used as data containers by the archiving and -// the scripting mechanisms. -//------------------------------------------------------------------------------ - -#ifndef _MESSAGE_H -#define _MESSAGE_H - -#include -#include -#include -#include -#include - -#include /* For convenience */ -#include /* For convenience */ - -class BBlockCache; -class BMessenger; -class BHandler; -class BString; - -// 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 = 1, - 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, ssize_t *size) 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, - bool preferred, - bigtime_t timeout, - bool reply_required, - BMessenger &reply_to) const; - status_t send_message(port_id port, - team_id port_owner, - int32 token, - bool preferred, - BMessage *reply, - bigtime_t send_timeout, - bigtime_t reply_timeout) const; -static status_t _SendFlattenedMessage(void *data, int32 size, - port_id port, int32 token, bool preferred, - 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 *link; - 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 diff --git a/headers/private/app/Message3.h b/headers/private/app/Message3.h deleted file mode 100644 index 1a6eb476f0..0000000000 --- a/headers/private/app/Message3.h +++ /dev/null @@ -1,368 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku -// -// 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: Message.h -// Author(s): Erik Jaesler (erik@cgsoftware.com) -// DarkWyrm -// Description: BMessage class creates objects that store data and that -// can be processed in a message loop. BMessage objects -// are also used as data containers by the archiving and -// the scripting mechanisms. -//------------------------------------------------------------------------------ - -#ifndef _MESSAGE_H -#define _MESSAGE_H - -#include -#include -#include -#include -#include - -#include /* For convenience */ -#include /* For convenience */ - -class BBlockCache; -class BMessenger; -class BHandler; -class BString; - -// 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 = 1, - 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 real_flatten(char *result, ssize_t size) const; - status_t real_flatten(BDataIO *stream, ssize_t *size) 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_hdr_size() const; - - status_t _send_(port_id port, int32 token, - bool preferred, bigtime_t timeout, - bool reply_required, - BMessenger &reply_to) const; - status_t send_message(port_id port, team_id port_owner, - int32 token, bool preferred, - BMessage *reply, - bigtime_t send_timeout, - bigtime_t reply_timeout) const; - -static status_t _SendFlattenedMessage(void *data, int32 size, - port_id port, int32 token, bool preferred, - 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; - - BMessage *fUnused1; - int32 fTarget; - BMessage *fOriginal; - uint32 fUnused2; - int32 fCurSpecifier; - uint32 fReserved[4]; - - BPrivate::BMessageBody *fBody; - - 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 diff --git a/headers/private/app/MessageBody2.h b/headers/private/app/MessageBody2.h deleted file mode 100644 index 354c1cf9a1..0000000000 --- a/headers/private/app/MessageBody2.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageBody handles data storage and retrieval for BMessage. */ - -#ifndef _MESSAGE_BODY_H_ -#define _MESSAGE_BODY_H_ - -#include -#include "MessageField2.h" - -enum { - B_FLATTENABLE_TYPE = 'FLAT' -}; - -namespace BPrivate { - -class BMessageBody { -public: - BMessageBody(); - BMessageBody(const BMessageBody &other); - ~BMessageBody(); - - BMessageBody &operator=(const BMessageBody &other); - - status_t GetInfo(type_code typeRequested, int32 which, - char **name, type_code *typeFound, - int32 *countFound = NULL) const; - status_t GetInfo(const char *name, type_code *typeFound, - int32 *countFound = NULL) const; - status_t GetInfo(const char *name, type_code *typeFound, - bool *fixedSize) const; - - int32 CountNames(type_code type) const; - bool IsEmpty() const; - - ssize_t FlattenedSize() const; - status_t Flatten(BDataIO *stream) const; - status_t Unflatten(BDataIO *stream); - - status_t AddData(const char *name, type_code type, - size_t length, void **buffer, - bool fixedSize = false, int32 count = 1); - status_t RemoveData(const char *name, int32 index = 0); - - bool HasData(const char *name, type_code t, int32 n) const; - status_t FindData(const char *name, type_code type, - int32 index, const void **data, - ssize_t *numBytes) const; - status_t ReplaceData(const char *name, type_code type, - int32 index, size_t length, void **buffer); - - status_t Rename(const char *oldName, const char *newName); - status_t RemoveName(const char *name); - status_t MakeEmpty(); - - void PrintToStream() const; - - // hash table support - void HashInsert(BMessageField *field); - BMessageField *HashLookup(const char *name) const; - BMessageField *HashRemove(const char *name); - uint32 HashString(const char *string) const; - void HashClear(); - -private: - status_t InitCommon(); - BMessageField *AddField(const char *name, type_code type, - status_t &error); - BMessageField *FindData(const char *name, type_code type, - status_t &error) const; - - BList fFieldList; - BMessageField **fFieldTable; - int32 fFieldTableSize; - -mutable ssize_t fFlattenedSize; -}; - -} // namespace BPrivate - -#endif // _MESSAGE_BODY_H_ diff --git a/headers/private/app/MessageBody3.h b/headers/private/app/MessageBody3.h deleted file mode 100644 index c5e61d08d3..0000000000 --- a/headers/private/app/MessageBody3.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageBody handles data storage and retrieval for BMessage. */ - -#ifndef _MESSAGE_BODY_H_ -#define _MESSAGE_BODY_H_ - -#include - -enum { - B_FLATTENABLE_TYPE = 'FLAT' -}; - -namespace BPrivate { - -class BMessageField; - -class BMessageBody { -public: - BMessageBody(); - BMessageBody(const BMessageBody &other); - ~BMessageBody(); - - BMessageBody &operator=(const BMessageBody &other); - - status_t GetInfo(type_code typeRequested, int32 which, - char **name, type_code *typeFound, - int32 *countFound = NULL) const; - status_t GetInfo(const char *name, type_code *typeFound, - int32 *countFound = NULL) const; - status_t GetInfo(const char *name, type_code *typeFound, - bool *fixedSize) const; - - int32 CountNames(type_code type) const; - bool IsEmpty() const; - - ssize_t FlattenedSize() const; - status_t Flatten(BDataIO *stream) const; - status_t Unflatten(BDataIO *stream, int32 length); - - status_t AddData(const char *name, type_code type, - const void *item, ssize_t length, - bool fixedSize); - status_t AddData(const char *name, type_code type, - void **buffer, ssize_t length); - status_t ReplaceData(const char *name, type_code type, - int32 index, const void *item, ssize_t length); - status_t ReplaceData(const char *name, type_code type, - int32 index, void **buffer, ssize_t length); - - status_t RemoveData(const char *name, int32 index = 0); - - bool HasData(const char *name, type_code t, - int32 index) const; - status_t FindData(const char *name, type_code type, - int32 index, const void **data, - ssize_t *numBytes) const; - - status_t Rename(const char *oldName, const char *newName); - status_t RemoveName(const char *name); - status_t MakeEmpty(); - - void PrintToStream() const; - - // flat buffer management -inline uint8 *FlatBuffer() const { return fFlatBuffer; }; - uint8 *FlatInsert(int32 offset, ssize_t oldLength, - ssize_t newLength); - void FlatResize(int32 newSize); - - // hash table support - void HashInsert(BMessageField *field); - BMessageField *HashLookup(const char *name) const; - BMessageField *HashRemove(const char *name); - uint32 HashString(const char *string) const; - void HashClear(); - -private: - status_t InitCommon(); - BMessageField *AddData(const char *name, type_code type, - status_t &error); - BMessageField *FindData(const char *name, type_code type, - status_t &error) const; - - BList fFieldList; - BMessageField **fFieldTable; - int32 fFieldTableSize; - - uint8 *fFlatBuffer; - int32 fFlatLength; - int32 fFlatAllocated; - int32 fBlockSize; -}; - -} // namespace BPrivate - -#endif // _MESSAGE_BODY_H_ diff --git a/headers/private/app/MessageField2.h b/headers/private/app/MessageField2.h deleted file mode 100644 index 550f316902..0000000000 --- a/headers/private/app/MessageField2.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageField contains the data for indiviual named fields in BMessageBody */ - -#ifndef _MESSAGE_FIELD_H_ -#define _MESSAGE_FIELD_H_ - -#include -#include -#include - -#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 0x00 - -namespace BPrivate { - -typedef struct field_header_s { - uint8 flags; - type_code type; - int32 count; - ssize_t dataSize; - uint8 nameLength; - char name[255]; -} __attribute__((__packed__)) FieldHeader; - -class BMessageField { -public: - BMessageField(); - BMessageField(const char *name, type_code type); - BMessageField(uint8 flags, BDataIO *stream); - BMessageField(const BMessageField &other); - ~BMessageField(); - - BMessageField &operator=(const BMessageField &other); - - void Flatten(BDataIO *stream); - void Unflatten(uint8 flags, BDataIO *stream); - - uint8 Flags() { return fHeader.flags; }; - - void SetName(const char *name); - const char *Name() const { return fHeader.name; }; - uint8 NameLength() const { return fHeader.nameLength; }; - type_code Type() const { return fHeader.type; }; - - void *AddItem(size_t length); - void *ReplaceItem(int32 index, size_t newLength); - void RemoveItem(int32 index); - int32 CountItems() const { return fHeader.count; }; - - const void *BufferAt(int32 index, ssize_t *size) const; - - void MakeEmpty(); - - status_t SetFixedSize(int32 itemSize, int32 count); - bool IsFixedSize() const { return fHeader.flags & MSG_FLAG_FIXED_SIZE; }; - size_t TotalSize() const { return fHeader.dataSize; }; - - void PrintToStream() const; - - // hash table support - void SetNext(BMessageField *next) { fNext = next; }; - BMessageField *Next() const { return fNext; }; - -private: - void ResetHeader(const char *name, type_code type); - void FlatResize(int32 offset, size_t oldLength, - size_t newLength); - - FieldHeader fHeader; -mutable BMallocIO fFlatBuffer; - - // fixed size items - int32 fItemSize; - - // variable sized items - BList *fOffsets; - - // hash table support - BMessageField *fNext; -}; - -} // namespace BPrivate - -#endif // _MESSAGE_FIELD_H_ diff --git a/headers/private/app/MessageField3.h b/headers/private/app/MessageField3.h deleted file mode 100644 index c437db5c2d..0000000000 --- a/headers/private/app/MessageField3.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageField contains the data for indiviual named fields in BMessageBody */ - -#ifndef _MESSAGE_FIELD_H_ -#define _MESSAGE_FIELD_H_ - -#include -#include -#include -#include "MessageBody3.h" - -// we only support those -#define MSG_FLAG_VALID 0x01 -#define MSG_FLAG_FIXED_SIZE 0x04 -#define MSG_FLAG_ALL 0x05 - -// these are for R5 compatibility -#define MSG_FLAG_MINI_DATA 0x02 -#define MSG_FLAG_SINGLE_ITEM 0x08 - -#define MSG_LAST_ENTRY 0x00 - -namespace BPrivate { - -struct field_header_s { - uint8 flags; - type_code type; - int32 count; - ssize_t dataSize; - uint8 nameLength; -} __attribute__((__packed__)); - -struct item_info_s { - item_info_s(int32 _offset) - : offset(_offset) - { - } - - item_info_s(int32 _offset, int32 _length) - : offset(_offset), - length(_length) - { - } - - int32 offset; - int32 length; - int32 paddedLength; -}; - -typedef field_header_s FieldHeader; -typedef item_info_s ItemInfo; - -class BMessageField { -public: - BMessageField(BMessageBody *parent, - int32 offset, const char *name, - type_code type); - - // only use this constructor to unflatten - BMessageField(BMessageBody *parent); - int32 Unflatten(int32 offset); - - uint8 Flags() const { return Header()->flags; }; - status_t SetFixedSize(int32 itemSize); - bool FixedSize() const { return fFixedSize; }; - - void SetName(const char *newName); - const char *Name() const; - uint8 NameLength() const { return Header()->nameLength; }; - type_code Type() const { return Header()->type; }; - - void AddItem(const void *item, ssize_t length); - uint8 *AddItem(ssize_t length); - - void ReplaceItem(int32 index, const void *newItem, - ssize_t length); - uint8 *ReplaceItem(int32 index, ssize_t length); - - void *ItemAt(int32 index, ssize_t *size); - - void RemoveItem(int32 index); - int32 CountItems() const { return Header()->count; }; - - void PrintToStream() const; - - void SetOffset(int32 offset) { fOffset = offset; }; - int32 Offset() const { return fOffset; }; - - // always do MakeEmpty -> RemoveSelf -> delete - void MakeEmpty(); - void RemoveSelf(); - - // hash table support - void SetNext(BMessageField *next) { fNext = next; }; - BMessageField *Next() const { return fNext; }; - -private: -inline FieldHeader *Header() const { return (FieldHeader *)(fParent->FlatBuffer() + fOffset); }; - - BMessageBody *fParent; - int32 fOffset; - int32 fDataOffset; - - bool fFixedSize; - int32 fItemSize; - BList fItemInfos; - - BMessageField *fNext; -}; - -} // namespace BPrivate - -#endif // _MESSAGE_FIELD_H_ diff --git a/headers/private/app/MessageUtils2.h b/headers/private/app/MessageUtils2.h deleted file mode 100644 index 1087ba2aad..0000000000 --- a/headers/private/app/MessageUtils2.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef MESSAGEUTILS_H -#define MESSAGEUTILS_H - -#include -#include -#include -#include -#include -#include -#include - - -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 -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 - inline void operator()(T &data) - { - fError = fStream->Read((void *)&data, sizeof(T)); - if (fError < B_OK) - throw fError; - - if (IsSwapping()) - byte_swap(data); - } - - template - inline void operator()(T data, size_t len) - { - fError = fStream->Read((void *)data, len); - if (fError < B_OK) - 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 - inline void Cache(const T &data) - { - *((T*)fBufPtr) = data; - fBufPtr += sizeof (T); - } - - int32 CheckSum(); - -private: - uchar *fBuffer; - uchar *fBufPtr; -}; - - -template -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 diff --git a/headers/private/app/MessageUtils3.h b/headers/private/app/MessageUtils3.h deleted file mode 100644 index aac4ca3588..0000000000 --- a/headers/private/app/MessageUtils3.h +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef MESSAGEUTILS_H -#define MESSAGEUTILS_H - -#include -#include -#include -#include -#include -#include -#include - - -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 -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 - 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 - 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 - inline void Cache(const T &data) - { - *((T*)fBufPtr) = data; - fBufPtr += sizeof (T); - } - - int32 CheckSum(); - -private: - uchar *fBuffer; - uchar *fBufPtr; -}; - - -template -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 diff --git a/src/kits/app/Message2.cpp b/src/kits/app/Message2.cpp deleted file mode 100644 index 8f3ef19d00..0000000000 --- a/src/kits/app/Message2.cpp +++ /dev/null @@ -1,2072 +0,0 @@ -/* - * Copyright 2001-2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Erik Jaesler (erik@cgsoftware.com) - * DarkWyrm - * Ingo Weinhold - */ - -/** BMessage class creates objects that store data and that - * can be processed in a message loop. BMessage objects - * are also used as data containers by the archiving and - * the scripting mechanisms. - */ - -// debugging -//#define DBG(x) x -#define DBG(x) ; -#define PRINT(x) DBG({ printf("[%6ld] ", find_thread(NULL)); printf x; }) - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "MessageBody2.h" -#include "MessageField2.h" -#include "MessageUtils2.h" -#include "dano_message.h" - -// flags for the overall message (the bitfield is 1 byte) -#define MSG_FLAG_BIG_ENDIAN 0x01 -#define MSG_FLAG_INCL_TARGET 0x02 -#define MSG_FLAG_INCL_REPLY 0x04 -#define MSG_FLAG_SCRIPT_MSG 0x08 - -#if 0 -// These are for future improvement -#define MSG_FLAG_USE_PREFERRED 0x10 -#define MSG_FLAG_REPLY_WANTED 0x20 -#define MSG_FLAG_REPLY_DONE 0x40 -#define MSG_FLAG_IS_REPLY 0x80 - -#define MSG_FLAG_HDR_MASK 0xF0 -#endif - -#define MSG_HEADER_MAX_SIZE 38 -#define MSG_NAME_MAX_SIZE 256 - -using namespace BPrivate; - -static const uint32 kMessageMagic = 'FOB1'; -static const uint32 kMessageMagicSwapped = '1BOF'; -static const uint32 kMessageMagicDano = 'FOB2'; -static const uint32 kMessageMagicDanoSwapped = '2BOF'; - -const char* B_SPECIFIER_ENTRY = "specifiers"; -const char* B_PROPERTY_ENTRY = "property"; -const char* B_PROPERTY_NAME_ENTRY = "name"; - -BBlockCache *BMessage::sMsgCache = NULL; -port_id BMessage::sReplyPorts[sNumReplyPorts]; -long BMessage::sReplyPortInUse[sNumReplyPorts]; - -static status_t handle_reply(port_id replyPort, int32 *pCode, - bigtime_t timeout, BMessage *reply); -static status_t convert_message(const KMessage *fromMessage, - BMessage *toMessage); -static ssize_t min_hdr_size(); - -typedef struct message_header_s { - int32 checkSum; - int32 flattenedSize; - uint32 what; - uint8 flags; -} __attribute__((__packed__)) MessageHeader; - -typedef struct reply_data_s { - port_id replyPort; - int32 replyToken; - team_id replyTeam; - bool preferredTarget; - bool replyRequired; - bool replyDone; - bool isReply; -} __attribute__((__packed__)) ReplyData; - -class BMessage::Header { -public: - Header() {}; - Header(const BMessage &message) { ReadFrom(message); }; - - status_t SetMagic(uint32 magic); - - status_t ReadFrom(BDataIO &stream); - void ReadFrom(const BMessage &message); - status_t WriteTo(BDataIO &stream, bool calculateCheckSum = true) const; - void WriteTo(BMessage &message) const; - - uint32 CalculateCheckSum() const; - uint32 CalculateHeaderSize() const; - - bool IsSwapped() const { return fSwapped; }; - bool HasTarget() const { return (fFlags & MSG_FLAG_INCL_TARGET); }; - void SetTarget(int32 token, bool preferred); - - void Dump() const; - -private: - uint32 fMagic; - int32 fBodySize; - uint32 fWhat; - uint8 fFlags; - int32 fTargetToken; - port_id fReplyPort; - int32 fReplyToken; - team_id fReplyTeam; - bool fPreferredTarget; - bool fReplyRequired; - bool fReplyDone; - bool fIsReply; - bool fSwapped; -}; - - -status_t -BMessage::Header::SetMagic(uint32 magic) -{ - if (magic == kMessageMagicSwapped) - fSwapped = true; - else if (magic == kMessageMagic) - fSwapped = false; - else { - // This is *not* a message - return B_NOT_A_MESSAGE; - } - - fMagic = magic; - return B_OK; -} - - -status_t -BMessage::Header::ReadFrom(BDataIO &stream) -{ - int32 checkSum; - uchar csBuffer[MSG_HEADER_MAX_SIZE]; - - TReadHelper read_helper(&stream); - TChecksumHelper checksum_helper(csBuffer); - int32 flattenedSize; - - try { - read_helper.SetSwap(fSwapped); - - // get the checksum - read_helper(checkSum); - // get the size - read_helper(flattenedSize); - // get the what - read_helper(fWhat); - // get the flags - read_helper(fFlags); - - checksum_helper.Cache(flattenedSize); - checksum_helper.Cache(fWhat); - checksum_helper.Cache(fFlags); - - if (fFlags & MSG_FLAG_BIG_ENDIAN) { - // TODO: isn't this already indicated by the byte order of the - // message version? - } - - if (fFlags & MSG_FLAG_INCL_TARGET) { - // Get the target data - read_helper(fTargetToken); - checksum_helper.Cache(fTargetToken); - } - - if (fFlags & MSG_FLAG_INCL_REPLY) { - // Get the reply port - read_helper(fReplyPort); - read_helper(fReplyToken); - read_helper(fReplyTeam); - checksum_helper.Cache(fReplyPort); - checksum_helper.Cache(fReplyToken); - checksum_helper.Cache(fReplyTeam); - - // get the "big flags" - uint8 bigFlags; - // get the preferred flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fPreferredTarget = bigFlags; - - // get the reply requirement flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fReplyRequired = bigFlags; - - // get the reply done flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fReplyDone = bigFlags; - - // Get the "is reply" flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fIsReply = bigFlags; - } - } catch (status_t &error) { - return error; - } - - fBodySize = flattenedSize - CalculateHeaderSize(); - - if (checkSum != checksum_helper.CheckSum()) - return B_NOT_A_MESSAGE; - - return B_OK; -} - - -void -BMessage::Header::ReadFrom(const BMessage &message) -{ - fMagic = kMessageMagic; - - fBodySize = message.fBody->FlattenedSize(); - fWhat = message.what; - fFlags = 0; -#ifdef B_HOST_IS_BENDIAN - fFlags |= MSG_FLAG_BIG_ENDIAN; -#endif - if (message.HasSpecifiers()) - fFlags |= MSG_FLAG_SCRIPT_MSG; - - if (message.fTarget != B_NULL_TOKEN) - fFlags |= MSG_FLAG_INCL_TARGET; - - if (message.fReplyTo.port >= 0 && - message.fReplyTo.target != B_NULL_TOKEN && - message.fReplyTo.team >= 0) { - fFlags |= MSG_FLAG_INCL_REPLY; - } - - fTargetToken = message.fTarget; - fReplyPort = message.fReplyTo.port; - fReplyToken = message.fReplyTo.target; - fReplyTeam = message.fReplyTo.team; - fPreferredTarget = message.fPreferred; - fReplyRequired = message.fReplyRequired; - fReplyDone = message.fReplyDone; - fIsReply = message.fIsReply; -} - - -status_t -BMessage::Header::WriteTo(BDataIO &stream, bool calculateCheckSum) const -{ - try { - // write the version of the binary data format - int32 data = fMagic; - write_helper(&stream, (const void *)&data, sizeof(data)); - - // compute checksum - data = (calculateCheckSum ? CalculateCheckSum() : 0); - write_helper(&stream, (const void *)&data, sizeof(data)); - - // write the flattened size of the entire message - data = CalculateHeaderSize() + fBodySize; - write_helper(&stream, (const void *)&data, sizeof(data)); - - // write the 'what' member - write_helper(&stream, (const void *)&fWhat, sizeof(fWhat)); - - // write the header flags - write_helper(&stream, (const void *)&fFlags, sizeof(fFlags)); - - // write targeting info if necessary - if (fFlags & MSG_FLAG_INCL_TARGET) { - data = fPreferredTarget ? B_PREFERRED_TOKEN : fTargetToken; - write_helper(&stream, (const void *)&data, sizeof(data)); - } - - // write reply info if necessary - if (fFlags & MSG_FLAG_INCL_REPLY) { - write_helper(&stream, (const void *)&fReplyPort, sizeof(fReplyPort)); - write_helper(&stream, (const void *)&fReplyToken, sizeof(fReplyToken)); - write_helper(&stream, (const void *)&fReplyTeam, sizeof(fReplyTeam)); - - uint8 bigFlags; - bigFlags = fPreferredTarget ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fReplyRequired ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fReplyDone ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fIsReply ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - } - } catch (status_t &error) { - return error; - } - - return B_OK; -} - - -void -BMessage::Header::WriteTo(BMessage &message) const -{ - // make way for the new data - message.MakeEmpty(); - message.what = fWhat; - - message.fHasSpecifiers = fFlags & MSG_FLAG_SCRIPT_MSG; - - if (fFlags & MSG_FLAG_INCL_TARGET) { - // get the target data - message.fTarget = fTargetToken; - } - - if (fFlags & MSG_FLAG_INCL_REPLY) { - // get the reply port - message.fReplyTo.port = fReplyPort; - message.fReplyTo.target = fReplyToken; - message.fReplyTo.team = fReplyTeam; - - message.fWasDelivered = true; - - message.fPreferred = fPreferredTarget; - if (fPreferredTarget) - message.fTarget = B_PREFERRED_TOKEN; - - message.fReplyRequired = fReplyRequired; - message.fReplyDone = fReplyDone; - message.fIsReply = fIsReply; - } -} - - -uint32 -BMessage::Header::CalculateCheckSum() const -{ - uint8 buffer[MSG_HEADER_MAX_SIZE]; - BMemoryIO stream(buffer, sizeof(buffer)); - WriteTo(stream, false); - int32 size = stream.Position(); - return _checksum_(buffer + 8, size - 8); -} - - -uint32 -BMessage::Header::CalculateHeaderSize() const -{ - ssize_t size = min_hdr_size(); - - if (fTargetToken != B_NULL_TOKEN) - size += sizeof(fTargetToken); - - if (fReplyPort >= 0 && fReplyToken != B_NULL_TOKEN && fReplyTeam >= 0) { - size += sizeof(fReplyPort); - size += sizeof(fReplyToken); - size += sizeof(fReplyTeam); - - size += 4; // For the "big" flags - } - - return size; -} - - -void -BMessage::Header::SetTarget(int32 token, bool preferred) -{ - fTargetToken = token; - - if (fTargetToken == B_NULL_TOKEN) - fFlags &= ~MSG_FLAG_INCL_TARGET; - else - fFlags |= MSG_FLAG_INCL_TARGET; - - fPreferredTarget = preferred; -} - - -void -BMessage::Header::Dump() const -{ - printf("BMessage::Header:\n"); - printf(" magic: %lx\n", fMagic); - printf(" body size: %ld\n", fBodySize); - printf(" what: %lx\n", fWhat); - printf(" flags: %x\n", fFlags); - printf(" target token: %ld\n", fTargetToken); - printf(" reply port: %ld\n", fReplyPort); - printf(" reply token: %ld\n", fReplyToken); - printf(" reply team: %ld\n", fReplyTeam); - printf(" preferred target: %d\n", fPreferredTarget); - printf(" reply required: %d\n", fReplyRequired); - printf(" reply done: %d\n", fReplyDone); - printf(" is reply: %d\n", fIsReply); - printf(" swapped: %d\n", fSwapped); -} - - -void BMessage::_ReservedMessage1() {} -void BMessage::_ReservedMessage2() {} -void BMessage::_ReservedMessage3() {} - - -BMessage::BMessage() - : fBody(NULL) -{ - init_data(); -} - - -BMessage::BMessage(uint32 _what) - : fBody(NULL) -{ - init_data(); - what = _what; -} - - -BMessage::BMessage(const BMessage &other) - : fBody(NULL) -{ - init_data(); - *this = other; -} - - -BMessage::BMessage(BMessage *other) - : fBody(NULL) -{ - init_data(); - *this = *other; -} - - -BMessage::~BMessage() -{ - if (IsSourceWaiting()) { - SendReply(B_NO_REPLY); - } - - delete fBody; -} - - -BMessage & -BMessage::operator=(const BMessage &msg) -{ - what = msg.what; - - fQueueLink = msg.fQueueLink; - fTarget = msg.fTarget; - fOriginal = msg.fOriginal; - fChangeCount = msg.fChangeCount; - fCurSpecifier = msg.fCurSpecifier; - fPtrOffset = msg.fPtrOffset; - - fEntries = msg.fEntries; - - fReplyTo.port = msg.fReplyTo.port; - fReplyTo.target = msg.fReplyTo.target; - fReplyTo.team = msg.fReplyTo.team; - fReplyTo.preferred = msg.fReplyTo.preferred; - - fPreferred = msg.fPreferred; - fReplyRequired = msg.fReplyRequired; - fReplyDone = msg.fReplyDone; - fIsReply = msg.fIsReply; - fWasDelivered = msg.fWasDelivered; - fReadOnly = msg.fReadOnly; - fHasSpecifiers = msg.fHasSpecifiers; - - *fBody = *(msg.fBody); - return *this; -} - - -void -BMessage::init_data() -{ - what = 0; - - fQueueLink = NULL; - fTarget = B_NULL_TOKEN; - fOriginal = NULL; - fChangeCount = 0; - fCurSpecifier = -1; - fPtrOffset = 0; - - fEntries = NULL; - - fReplyTo.port = -1; - fReplyTo.target = B_NULL_TOKEN; - fReplyTo.team = -1; - fReplyTo.preferred = false; - - fPreferred = false; - fReplyRequired = false; - fReplyDone = false; - fIsReply = false; - fWasDelivered = false; - fReadOnly = false; - fHasSpecifiers = false; - - if (fBody) - fBody->MakeEmpty(); - else - fBody = new BPrivate::BMessageBody(); -} - - -status_t -BMessage::GetInfo(type_code typeRequested, int32 which, char **name, - type_code *typeReturned, int32 *count) const -{ - return fBody->GetInfo(typeRequested, which, name, typeReturned, count); -} - - -status_t -BMessage::GetInfo(const char *name, type_code *type, int32 *count) const -{ - return fBody->GetInfo(name, type, count); -} - - -status_t -BMessage::GetInfo(const char *name, type_code *type, bool *fixed_size) const -{ - return fBody->GetInfo(name, type, fixed_size); -} - - -int32 -BMessage::CountNames(type_code type) const -{ - return fBody->CountNames(type); -} - - -bool -BMessage::IsEmpty() const -{ - return fBody->IsEmpty(); -} - - -bool -BMessage::IsSystem() const -{ - char a = char(what >> 24); - char b = char(what >> 16); - char c = char(what >> 8); - char d = char(what); - - // The BeBook says: - // ... we've adopted a strict convention for assigning values to all - // Be-defined constants. The value assigned will always be formed by - // combining four characters into a multicharacter constant, with the - // characters limited to uppercase letters and the underbar - // Between that and what's in AppDefs.h, this algo seems like a safe bet: - if (a == '_' && isupper(b) && isupper(c) && isupper(d)) - return true; - - return false; -} - - -bool -BMessage::IsReply() const -{ - return fIsReply; -} - - -void -BMessage::PrintToStream() const -{ - printf("\nBMessage: what = '%c%c%c%c' (0x%lX or %ld)\n", - (uint8)(what >> 24), (uint8)(what >> 16), (uint8)(what >> 8), - (uint8)what, what, what); - - fBody->PrintToStream(); -} - - -status_t -BMessage::Rename(const char *old_entry, const char *new_entry) -{ - return fBody->Rename(old_entry, new_entry); -} - - -bool -BMessage::WasDelivered() const -{ - return fWasDelivered; -} - - -bool -BMessage::IsSourceWaiting() const -{ - return fReplyRequired && !fReplyDone; -} - - -bool -BMessage::IsSourceRemote() const -{ - return WasDelivered() && fReplyTo.team != BPrivate::current_team(); -} - - -BMessenger -BMessage::ReturnAddress() const -{ - if (WasDelivered()) { - BMessenger messenger; - BMessenger::Private(messenger).SetTo(fReplyTo.team, fReplyTo.port, - fReplyTo.target, fReplyTo.preferred); - return messenger; - } - - return BMessenger(); -} - - -const BMessage * -BMessage::Previous() const -{ - // TODO: test - // In particular, look to see if the "_previous_" field is used in R5 - if (!fOriginal) { - BMessage *fOriginal = new BMessage; - - if (FindMessage("_previous_", fOriginal) != B_OK) { - delete fOriginal; - fOriginal = NULL; - } - } - - return fOriginal; -} - - -bool -BMessage::WasDropped() const -{ - return fReadOnly; -} - - -BPoint -BMessage::DropPoint(BPoint *offset) const -{ - // TODO: Where do we get this stuff??? - if (offset) - *offset = FindPoint("_drop_offset_"); - - return FindPoint("_drop_point_"); -} - - -status_t -BMessage::SendReply(uint32 command, BHandler *reply_to) -{ - BMessage msg(command); - return SendReply(&msg, reply_to); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BHandler *reply_to, bigtime_t timeout) -{ - BMessenger messenger(reply_to); - return SendReply(the_reply, messenger, timeout); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BMessenger reply_to, bigtime_t timeout) -{ - // TODO: test - BMessenger messenger; - BMessenger::Private messengerPrivate(messenger); - messengerPrivate.SetTo(fReplyTo.team, fReplyTo.port, fReplyTo.target, - fReplyTo.preferred); - - if (fReplyRequired) { - if (fReplyDone) - return B_DUPLICATE_REPLY; - - fReplyDone = true; - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to, timeout); - the_reply->fIsReply = false; - - if (error) { - if (set_port_owner(messengerPrivate.Port(), - messengerPrivate.Team()) == B_BAD_TEAM_ID) { - delete_port(messengerPrivate.Port()); - } - } - - return error; - } - - // no reply required - if (!fWasDelivered) - return B_BAD_REPLY; - - the_reply->AddMessage("_previous_", this); - the_reply->fIsReply = true; - - status_t error = messenger.SendMessage(the_reply, reply_to, timeout); - the_reply->fIsReply = false; - the_reply->RemoveName("_previous_"); - - return error; -} - - -status_t -BMessage::SendReply(uint32 command, BMessage *reply_to_reply) -{ - BMessage msg(command); - return SendReply(&msg, reply_to_reply); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BMessage *reply_to_reply, - bigtime_t send_timeout, bigtime_t reply_timeout) -{ - // TODO: test - BMessenger messenger; - BMessenger::Private messengerPrivate(messenger); - messengerPrivate.SetTo(fReplyTo.team, fReplyTo.port, fReplyTo.target, - fReplyTo.preferred); - - if (fReplyRequired) { - if (fReplyDone) - return B_DUPLICATE_REPLY; - - fReplyDone = true; - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to_reply, - send_timeout, reply_timeout); - the_reply->fIsReply = false; - - if (error) { - if (set_port_owner(messengerPrivate.Port(), - messengerPrivate.Team()) == B_BAD_TEAM_ID) { - delete_port(messengerPrivate.Port()); - } - } - - return error; - } - - // no reply required - if (!fWasDelivered) - return B_BAD_REPLY; - - the_reply->AddMessage("_previous_", this); - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to_reply, - send_timeout, reply_timeout); - the_reply->fIsReply = false; - the_reply->RemoveName("_previous_"); - return error; -} - - -ssize_t -BMessage::FlattenedSize() const -{ - return calc_hdr_size(0) + fBody->FlattenedSize(); -} - - -status_t -BMessage::Flatten(char *buffer, ssize_t size) const -{ - return real_flatten(buffer, size); -} - - -status_t -BMessage::Flatten(BDataIO *stream, ssize_t *size) const -{ - return real_flatten(stream, size); -} - - -status_t -BMessage::Unflatten(const char *buffer) -{ - if (!buffer) - return B_BAD_VALUE; - - uint32 magic = *(uint32 *)buffer; - - // we support several message formats - this list is ordered - // by importance and frequency - - if (magic == kMessageMagic) { - // it appears to be a normal flattened BMessage - BMemoryIO memoryStream(buffer, ((uint32 *)buffer)[2]); - return Unflatten(&memoryStream); - } - - // check whether this is a KMessage - if (((KMessage::Header *)buffer)->magic == KMessage::kMessageHeaderMagic) - return _UnflattenKMessage(buffer); - - if (magic == kMessageMagicSwapped) { - // it appears to be a swapped flattened BMessage - uint32 size = ((uint32 *)buffer)[2]; - BMemoryIO memoryStream(buffer, __swap_int32(size)); - return Unflatten(&memoryStream); - } - - if (magic == kMessageMagicDano || magic == kMessageMagicDanoSwapped) { - // dano style message - BMemoryIO memoryStream(buffer, BPrivate::dano_message_size(buffer)); - return Unflatten(&memoryStream); - } - - return B_NOT_A_MESSAGE; -} - - -status_t -BMessage::Unflatten(BDataIO *stream) -{ - TReadHelper reader(stream); - Header header; - status_t status = B_OK; - - // ToDo: while reading from a stream is certainly more convenient than - // from a buffer, it causes a lot of unnecessary copies, and therefore - // probably shouldn't be the preferred (or only) route. - - try { - uint32 magic; - reader(magic); - - status = header.SetMagic(magic); - if (status < B_OK) { - // we support reading Dano messages from disk as well - if (magic == kMessageMagicDano) - return BPrivate::unflatten_dano_message(magic, *stream, *this); - - return status; - } - - status = header.ReadFrom(*stream); - if (status < B_OK) { - printf("BMessage::Unflatten(): Reading the header failed: %lx\n", status); - return status; - } - - header.WriteTo(*this); - - status = fBody->Unflatten(stream); - } catch (status_t &error) { - status = error; - } - - return status; -} - - -status_t -BMessage::AddSpecifier(const char *property) -{ - BMessage message(B_DIRECT_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, int32 index) -{ - BMessage message(B_INDEX_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddInt32("index", index); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, int32 index, int32 range) -{ - if (range < 0) - return B_BAD_VALUE; - - BMessage message(B_RANGE_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddInt32("index", index); - if (error) - return error; - - error = message.AddInt32("range", range); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, const char *name) -{ - BMessage message(B_NAME_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddString(B_PROPERTY_NAME_ENTRY, name); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const BMessage *specifier) -{ - status_t error = AddMessage(B_SPECIFIER_ENTRY, specifier); - if (!error) { - fCurSpecifier++; - fHasSpecifiers = true; - } - - return error; -} - - -status_t -BMessage::SetCurrentSpecifier(int32 index) -{ - type_code type; - int32 count; - status_t error = GetInfo(B_SPECIFIER_ENTRY, &type, &count); - if (error) - return error; - - if (index < 0 || index >= count) - return B_BAD_INDEX; - - fCurSpecifier = index; - return B_OK; -} - - -status_t -BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *what, - const char **property) const -{ - if (fCurSpecifier == -1 || !WasDelivered()) - return B_BAD_SCRIPT_SYNTAX; - - if (index) - *index = fCurSpecifier; - - if (specifier) { - if (FindMessage(B_SPECIFIER_ENTRY, fCurSpecifier, specifier)) - return B_BAD_SCRIPT_SYNTAX; - - if (what) - *what = specifier->what; - - if (property) { - if (specifier->FindString(B_PROPERTY_ENTRY, property)) - return B_BAD_SCRIPT_SYNTAX; - } - } - - return B_OK; -} - - -bool -BMessage::HasSpecifiers() const -{ - return fHasSpecifiers; -} - - -status_t -BMessage::PopSpecifier() -{ - if (fCurSpecifier < 0 || !WasDelivered()) - return B_BAD_VALUE; - - fCurSpecifier--; - return B_OK; -} - - -#define DEFINE_FUNCTIONS(TYPE, fnName, TYPESPEC) \ -status_t \ -BMessage::Add ## fnName(const char *name, TYPE val) \ -{ \ - return AddData(name, TYPESPEC, &val, sizeof(TYPE), true); \ -} \ - \ -status_t \ -BMessage::Find ## fnName(const char *name, TYPE *p) const \ -{ \ - return Find ## fnName(name, 0, p); \ -} \ - \ -status_t \ -BMessage::Find ## fnName(const char *name, int32 index, TYPE *p) const \ -{ \ - void *ptr = NULL; \ - ssize_t bytes = 0; \ - status_t error = B_OK; \ - \ - *p = TYPE(); \ - error = FindData(name, TYPESPEC, index, (const void**)&ptr, &bytes); \ - \ - if (error == B_OK) \ - memcpy(p, ptr, sizeof(TYPE)); \ - \ - return error; \ -} \ - \ -status_t \ -BMessage::Replace ## fnName(const char* name, TYPE val) \ -{ \ - return Replace ## fnName(name, 0, val); \ -} \ - \ -status_t \ -BMessage::Replace ## fnName(const char *name, int32 index, TYPE val) \ -{ \ - return ReplaceData(name, TYPESPEC, index, &val, sizeof(TYPE)); \ -} \ - \ -bool \ -BMessage::Has ## fnName(const char *name, int32 n) const \ -{ \ - return fBody->HasData(name, TYPESPEC, n); \ -} - -DEFINE_FUNCTIONS(int8, Int8, B_INT8_TYPE); -DEFINE_FUNCTIONS(int16, Int16, B_INT16_TYPE); -DEFINE_FUNCTIONS(int32, Int32, B_INT32_TYPE); -DEFINE_FUNCTIONS(int64, Int64, B_INT64_TYPE); -DEFINE_FUNCTIONS(BPoint, Point, B_POINT_TYPE); -DEFINE_FUNCTIONS(BRect, Rect, B_RECT_TYPE); -DEFINE_FUNCTIONS(float, Float, B_FLOAT_TYPE); -DEFINE_FUNCTIONS(double, Double, B_DOUBLE_TYPE); -DEFINE_FUNCTIONS(bool, Bool, B_BOOL_TYPE); - -#undef DEFINE_FUNCTIONS - -#define DEFINE_HAS_FUNCTION(fnName, TYPESPEC) \ -bool \ -BMessage::Has ## fnName(const char* name, int32 n) const \ -{ \ - return HasData(name, TYPESPEC, n); \ -} - -DEFINE_HAS_FUNCTION(Message, B_MESSAGE_TYPE); -DEFINE_HAS_FUNCTION(String, B_STRING_TYPE); -DEFINE_HAS_FUNCTION(Pointer, B_POINTER_TYPE); -DEFINE_HAS_FUNCTION(Messenger, B_MESSENGER_TYPE); -DEFINE_HAS_FUNCTION(Ref, B_REF_TYPE); - -#undef DEFINE_HAS_FUNCTION - -#define DEFINE_LAZY_FIND_FUNCTION(TYPE, fnName) \ -TYPE \ -BMessage::Find ## fnName(const char* name, int32 n) const \ -{ \ - TYPE i = 0; \ - Find ## fnName(name, n, &i); \ - return i; \ -} - -DEFINE_LAZY_FIND_FUNCTION(int8, Int8); -DEFINE_LAZY_FIND_FUNCTION(int16, Int16); -DEFINE_LAZY_FIND_FUNCTION(int32, Int32); -DEFINE_LAZY_FIND_FUNCTION(int64, Int64); -DEFINE_LAZY_FIND_FUNCTION(float, Float); -DEFINE_LAZY_FIND_FUNCTION(double, Double); -DEFINE_LAZY_FIND_FUNCTION(bool, Bool); -DEFINE_LAZY_FIND_FUNCTION(const char *, String); - -#undef DEFINE_LAZY_FIND_FUNCTION - - -status_t -BMessage::AddString(const char *name, const char *string) -{ - return AddData(name, B_STRING_TYPE, string, strlen(string) + 1, false); -} - - -status_t -BMessage::AddString(const char* name, const BString &string) -{ - return AddData(name, B_STRING_TYPE, string.String(), string.Length() + 1, false); -} - - -status_t -BMessage::AddPointer(const char *name, const void *pointer) -{ - return AddData(name, B_POINTER_TYPE, &pointer, sizeof(pointer), true); -} - - -status_t -BMessage::AddMessenger(const char *name, BMessenger messenger) -{ - return AddData(name, B_MESSENGER_TYPE, &messenger, sizeof(messenger), true); -} - - -status_t -BMessage::AddRef(const char *name, const entry_ref *ref) -{ - size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH; - char flatRef[size]; - status_t error = entry_ref_flatten(flatRef, &size, ref); - - if (error < B_OK) - return error; - - void *buffer; - error = fBody->AddData(name, B_REF_TYPE, size, &buffer, false); - - if (error >= B_OK) - memcpy(buffer, flatRef, size); - - return error; -} - - -status_t -BMessage::AddMessage(const char *name, const BMessage *msg) -{ - size_t size = msg->FlattenedSize(); - - void *buffer; - status_t error = fBody->AddData(name, B_MESSAGE_TYPE, size, &buffer, false); - - if (error < B_OK) - return error; - - return msg->Flatten((char *)buffer, size); -} - - -status_t -BMessage::AddFlat(const char *name, BFlattenable *object, int32 count) -{ - ssize_t size = object->FlattenedSize(); - - void *buffer; - status_t error = fBody->AddData(name, object->TypeCode(), size, &buffer, false); - - if (error < B_OK) - return error; - - return object->Flatten(buffer, size); -} - - -status_t -BMessage::AddData(const char *name, type_code type, const void *data, - ssize_t numBytes, bool is_fixed_size, int32 count) -{ - void *buffer; - status_t error = fBody->AddData(name, type, numBytes, &buffer, is_fixed_size, count); - - if (error < B_OK) - return error; - - memcpy(buffer, data, numBytes); - return B_OK; -} - - -status_t -BMessage::RemoveData(const char *name, int32 index) -{ - return fReadOnly ? B_ERROR : fBody->RemoveData(name, index); -} - - -status_t -BMessage::RemoveName(const char *name) -{ - return fReadOnly ? B_ERROR : fBody->RemoveName(name); -} - - -status_t -BMessage::MakeEmpty() -{ - return fReadOnly ? B_ERROR : fBody->MakeEmpty(); -} - - -status_t -BMessage::FindString(const char *name, const char **string) const -{ - return FindString(name, 0, string); -} - - -status_t -BMessage::FindString(const char *name, int32 index, const char **string) const -{ - ssize_t bytes; - return FindData(name, B_STRING_TYPE, index, - (const void**)string, &bytes); -} - - -status_t -BMessage::FindString(const char *name, BString *string) const -{ - return FindString(name, 0, string); -} - - -status_t -BMessage::FindString(const char *name, int32 index, BString *string) const -{ - const char *cstr; - status_t err = FindString(name, index, &cstr); - if (err < B_OK) - return err; - - *string = cstr; - return B_OK; -} - - -status_t -BMessage::FindPointer(const char *name, void **ptr) const -{ - return FindPointer(name, 0, ptr); -} - - -status_t -BMessage::FindPointer(const char *name, int32 index, void **ptr) const -{ - void **data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_POINTER_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - *ptr = *data; - else - *ptr = NULL; - - return error; -} - - -status_t -BMessage::FindMessenger(const char *name, BMessenger *m) const -{ - return FindMessenger(name, 0, m); -} - - -status_t -BMessage::FindMessenger(const char *name, int32 index, BMessenger *m) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_MESSENGER_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - memcpy(m, data, sizeof(BMessenger)); - else - *m = BMessenger(); - - return error; -} - - -status_t -BMessage::FindRef(const char *name, entry_ref *ref) const -{ - return FindRef(name, 0, ref); -} - - -status_t -BMessage::FindRef(const char *name, int32 index, entry_ref *ref) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_REF_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - error = entry_ref_unflatten(ref, (char *)data, size); - else - *ref = entry_ref(); - - return error; -} - - -status_t -BMessage::FindMessage(const char *name, BMessage *msg) const -{ - return FindMessage(name, 0, msg); -} - - -status_t -BMessage::FindMessage(const char *name, int32 index, BMessage *msg) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_MESSAGE_TYPE, index, (const void **)&data, &size); - - if (!error) - error = msg->Unflatten((const char *)data); - else - *msg = BMessage(); - - return error; -} - - -status_t -BMessage::FindFlat(const char *name, BFlattenable *obj) const -{ - return FindFlat(name, 0, obj); -} - - -status_t -BMessage::FindFlat(const char *name, int32 index, BFlattenable *obj) const -{ - void *data = NULL; - ssize_t numBytes = 0; - status_t error = FindData(name, obj->TypeCode(), index, (const void **)&data, &numBytes); - - if (!error) - error = obj->Unflatten(obj->TypeCode(), data, numBytes); - - return error; -} - - -status_t -BMessage::FindData(const char *name, type_code type, const void **data, - ssize_t *numBytes) const -{ - return fBody->FindData(name, type, 0, data, numBytes); -} - - -status_t -BMessage::FindData(const char *name, type_code type, int32 index, - const void **data, ssize_t *numBytes) const -{ - return fBody->FindData(name, type, index, data, numBytes); -} - - -BRect -BMessage::FindRect(const char *name, int32 n) const -{ - BRect r(0, 0, -1, -1); - FindRect(name, n, &r); - return r; -} - - -BPoint -BMessage::FindPoint(const char *name, int32 n) const -{ - BPoint p(0, 0); - FindPoint(name, n, &p); - return p; -} - - -status_t -BMessage::ReplaceString(const char *name, const char *string) -{ - return ReplaceString(name, 0, string); -} - - -status_t -BMessage::ReplaceString(const char *name, int32 index, const char *string) -{ - return ReplaceData(name, B_STRING_TYPE, index, string, strlen(string)+1); -} - - -status_t -BMessage::ReplaceString(const char *name, const BString &string) -{ - return ReplaceString(name, 0, string); -} - - -status_t -BMessage::ReplaceString(const char *name, int32 index, const BString &string) -{ - return ReplaceData(name, B_STRING_TYPE, index, string.String(), string.Length()+1); -} - - -status_t -BMessage::ReplacePointer(const char *name, const void *ptr) -{ - return ReplacePointer(name, 0, ptr); -} - - -status_t -BMessage::ReplacePointer(const char *name, int32 index, const void *ptr) -{ - return ReplaceData(name, B_POINTER_TYPE, index, &ptr, sizeof(ptr)); -} - - -status_t -BMessage::ReplaceMessenger(const char *name, BMessenger messenger) -{ - return ReplaceData(name, B_MESSENGER_TYPE, 0, &messenger, sizeof(BMessenger)); -} - - -status_t -BMessage::ReplaceMessenger(const char *name, int32 index, BMessenger messenger) -{ - return ReplaceData(name, B_MESSENGER_TYPE, index, &messenger, sizeof(BMessenger)); -} - - -status_t -BMessage::ReplaceRef(const char *name, const entry_ref *ref) -{ - return ReplaceRef(name, 0, ref); -} - - -status_t -BMessage::ReplaceRef(const char *name, int32 index, const entry_ref *ref) -{ - size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH; - char flatRef[size]; - status_t error = entry_ref_flatten(flatRef, &size, ref); - - if (error < B_OK) - return error; - - void *buffer; - error = fBody->ReplaceData(name, B_REF_TYPE, index, size, &buffer); - - if (error < B_OK) - return error; - - memcpy(buffer, flatRef, size); - return B_OK; -} - - -status_t -BMessage::ReplaceMessage(const char *name, const BMessage *msg) -{ - return ReplaceMessage(name, 0, msg); -} - - -status_t -BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *msg) -{ - size_t size = msg->FlattenedSize(); - - void *buffer; - status_t error = fBody->ReplaceData(name, B_MESSAGE_TYPE, index, size, &buffer); - - if (error < B_OK) - return error; - - return msg->Flatten((char *)buffer, size); -} - - -status_t -BMessage::ReplaceFlat(const char *name, BFlattenable *object) -{ - return ReplaceFlat(name, 0, object); -} - - -status_t -BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object) -{ - ssize_t size = object->FlattenedSize(); - - void *buffer; - status_t error = fBody->ReplaceData(name, object->TypeCode(), index, size, &buffer); - - if (error < B_OK) - return error; - - return object->Flatten(buffer, size); -} - - -status_t -BMessage::ReplaceData(const char *name, type_code type, const void *data, - ssize_t data_size) -{ - return ReplaceData(name, type, 0, data, data_size); -} - - -status_t -BMessage::ReplaceData(const char *name, type_code type, int32 index, - const void *data, ssize_t data_size) -{ - void *buffer; - status_t error = fBody->ReplaceData(name, type, index, data_size, &buffer); - - if (error < B_OK) - return error; - - memcpy(buffer, data, data_size); - return B_OK; -} - - -bool -BMessage::HasFlat(const char *name, const BFlattenable *flat) const -{ - return HasFlat(name, 0, flat); -} - - -bool -BMessage::HasFlat(const char *name, int32 n, const BFlattenable *flat) const -{ - return fBody->HasData(name, flat->TypeCode(), n); -} - - -bool -BMessage::HasData(const char *name, type_code t, int32 n) const -{ - return fBody->HasData(name, t, n); -} - - -void * -BMessage::operator new(size_t size) -{ - if (!sMsgCache) - sMsgCache = new BBlockCache(10, size, B_OBJECT_CACHE); - - return sMsgCache->Get(size); -} - - -void * -BMessage::operator new(size_t, void *p) -{ - return p; -} - - -void -BMessage::operator delete(void *ptr, size_t size) -{ - sMsgCache->Save(ptr, size); -} - - -status_t -BMessage::real_flatten(char *result, ssize_t size) const -{ - BMemoryIO stream((void *)result, size); - return real_flatten(&stream, NULL); -} - - -status_t -BMessage::real_flatten(BDataIO *stream, ssize_t *size) const -{ - Header header(*this); - - status_t error = header.WriteTo(*stream); - if (error >= B_OK) - error = fBody->Flatten(stream); - - if (size) - *size = FlattenedSize(); - - return error; -} - - -char * -BMessage::stack_flatten(char *stack_ptr, ssize_t stack_size, - bool /*incl_reply*/, ssize_t *size) const -{ - const ssize_t calcd_size = calc_hdr_size(0) + fBody->FlattenedSize(); - char *new_ptr = NULL; - if (calcd_size > stack_size) { - stack_ptr = new char[calcd_size]; - new_ptr = stack_ptr; - } - - real_flatten(stack_ptr, calcd_size); - if (size) - *size = calcd_size; - - return new_ptr; -} - - -status_t -BMessage::_UnflattenKMessage(const char *buffer) -{ - // init a real KMessage - KMessage message; - status_t error = message.SetTo(buffer, ((KMessage::Header*)buffer)->size); - if (error != B_OK) - return error; - - // let convert_message() do the real job - return convert_message(&message, this); -} - - -ssize_t -BMessage::calc_hdr_size(uchar flags) const -{ - ssize_t size = min_hdr_size(); - - if (fTarget != B_NULL_TOKEN) - size += sizeof(fTarget); - - if (fReplyTo.port >= 0 - && fReplyTo.target != B_NULL_TOKEN - && fReplyTo.team >= 0) { - size += sizeof(fReplyTo.port); - size += sizeof(fReplyTo.target); - size += sizeof(fReplyTo.team); - - size += 4; // For the "big" flags - } - - return size; -} - - -status_t -BMessage::_send_(port_id port, int32 token, bool preferred, bigtime_t timeout, - bool reply_required, BMessenger &reply_to) const -{ - PRINT(("BMessage::_send_(port: %ld, token: %ld, preferred: %d): " - "what: %lx (%.4s)\n", port, token, preferred, what, (char *)&what)); - - bool oldPreferred = fPreferred; - int32 oldTarget = fTarget; - reply_to_info oldReplyTo = fReplyTo; - - if (!reply_to.IsValid()) { - BMessenger::Private(reply_to).SetTo(fReplyTo.team, - fReplyTo.port, fReplyTo.target, fReplyTo.preferred); - if (!reply_to.IsValid()) - reply_to = be_app_messenger; - } - - BMessage *self = const_cast(this); - BMessenger::Private replyToPrivate(reply_to); - self->fPreferred = preferred; - self->fTarget = token; - self->fReplyRequired = reply_required; - self->fReplyTo.team = replyToPrivate.Team(); - self->fReplyTo.port = replyToPrivate.Port(); - self->fReplyTo.target = (replyToPrivate.IsPreferredTarget() - ? B_PREFERRED_TOKEN : replyToPrivate.Token()); - self->fReplyTo.preferred = replyToPrivate.IsPreferredTarget(); - - char tmp[0x800]; - ssize_t size; - char *p = stack_flatten(tmp, sizeof(tmp), true /* include reply */, &size); - char *pMem = p ? p : tmp; - status_t error; - - do { - error = write_port_etc(port, 'pjpp', pMem, size, B_RELATIVE_TIMEOUT, timeout); - } while (error == B_INTERRUPTED); - - if (p) - delete[] p; - - self->fPreferred = oldPreferred; - self->fTarget = oldTarget; - self->fReplyRequired = false; // To this copy, no reply is required. - // Only relevant when forwarding anyway. - self->fReplyTo = oldReplyTo; - - PRINT(("BMessage::_send_() done: %lx\n", error)); - return error; -} - - -status_t -BMessage::send_message(port_id port, team_id port_owner, int32 token, - bool preferred, BMessage *reply, bigtime_t send_timeout, - bigtime_t reply_timeout) const -{ - const int32 cached_reply_port = sGetCachedReplyPort(); - port_id reply_port; - status_t error; - - if (cached_reply_port == -1) { - // All the cached reply ports are in use; create a new one - reply_port = create_port(1 /* for one message */, "tmp_reply_port"); - if (reply_port < 0) - return reply_port; - } else { - assert(cached_reply_port < sNumReplyPorts); - reply_port = sReplyPorts[cached_reply_port]; - } - - team_id team = B_BAD_TEAM_ID; - if (be_app != NULL) - team = be_app->Team(); - else { - port_info pi; - error = get_port_info(reply_port, &pi); - if (error) - goto error; - - team = pi.team; - } - - error = set_port_owner(reply_port, port_owner); - if (error) - goto error; - - { - BMessenger messenger; - BMessenger::Private(messenger).SetTo(team, reply_port, - B_PREFERRED_TOKEN, false); - error = _send_(port, token, preferred, send_timeout, true, messenger); - } - - if (error) - goto error; - - int32 code; - error = handle_reply(reply_port, &code, reply_timeout, reply); - if (error && cached_reply_port >= 0) { - delete_port(reply_port); - sReplyPorts[cached_reply_port] = create_port(1, "tmp_rport"); - } - -error: - if (cached_reply_port >= 0) { - // Reclaim ownership of cached port - set_port_owner(reply_port, team); - // Flag as available - atomic_add(&sReplyPortInUse[cached_reply_port], -1); - return error; - } - - delete_port(reply_port); - return error; -} - - -// Note, that in case of a flattened BMessage setting the target token will -// change the header size, if no token was set when the message was flattened. -// Hence the message would need to unflattened and flattened again before it -// can be sent. -status_t -BMessage::_SendFlattenedMessage(void *data, int32 size, port_id port, - int32 token, bool preferred, bigtime_t timeout) -{ - if (!data) - return B_BAD_VALUE; - - uint32 magic = *(uint32 *)data; - - // prepare flattened fields - if (((KMessage::Header*)data)->magic == KMessage::kMessageHeaderMagic) { - // a KMessage - KMessage::Header *header = (KMessage::Header*)data; - header->targetToken = (preferred ? B_PREFERRED_TOKEN : token); - } else if (magic == kMessageMagic || magic == kMessageMagicSwapped) { - // get the header - BMemoryIO stream(data, size); - - stream.Read(&magic, sizeof(uint32)); - // "discard" the magic (we already know it anyway) - - Header header; - status_t error = header.SetMagic(magic); - if (error < B_OK) - return error; - - error = header.ReadFrom(stream); - if (error < B_OK) - return error; - - if (!header.HasTarget()) { - // fallback implementation -- the header size would change by - // setting the token - - // unflatten the message - BMessage message; - error = message.Unflatten((const char*)data); - if (error != B_OK) - return error; - - // send the message - BMessenger messenger; - return message._send_(port, token, preferred, timeout, false, - messenger); - } - - // set the target token and replace the header - header.SetTarget(token, preferred); - stream.Seek(0LL, SEEK_SET); - error = header.WriteTo(stream); - if (error != B_OK) - return error; - } else - return B_NOT_A_MESSAGE; - - // send the message - status_t error; - do { - error = write_port_etc(port, 'pjpp', data, size, B_RELATIVE_TIMEOUT, - timeout); - } while (error == B_INTERRUPTED); - - return error; -} - - -void -BMessage::_StaticCacheCleanup() -{ - delete sMsgCache; - sMsgCache = NULL; -} - - -void -BMessage::_StaticInit() -{ - sReplyPorts[0] = create_port(1, "tmp_rport0"); - sReplyPorts[1] = create_port(1, "tmp_rport1"); - sReplyPorts[2] = create_port(1, "tmp_rport2"); - - sReplyPortInUse[0] = 0; - sReplyPortInUse[1] = 0; - sReplyPortInUse[2] = 0; -} - - -void -BMessage::_StaticCleanup() -{ - delete_port(sReplyPorts[0]); - sReplyPorts[0] = -1; - delete_port(sReplyPorts[1]); - sReplyPorts[1] = -1; - delete_port(sReplyPorts[2]); - sReplyPorts[2] = -1; -} - - -int32 -BMessage::sGetCachedReplyPort() -{ - int index = -1; - for (int32 i = 0; i < sNumReplyPorts; i++) { - int32 old = atomic_add(&(sReplyPortInUse[i]), 1); - if (old == 0) { - // This entry is free - index = i; - break; - } else { - // This entry is being used. - atomic_add(&(sReplyPortInUse[i]), -1); - } - } - - return index; -} - - -static status_t -handle_reply(port_id reply_port, int32 *pCode, bigtime_t timeout, - BMessage *reply) -{ - PRINT(("handle_reply(port: %ld)\n", reply_port)); - - status_t error; - do { - error = port_buffer_size_etc(reply_port, 8, timeout); - } while (error == B_INTERRUPTED); - - if (error < B_OK) { - PRINT(("handle_reply() error 1: %lx\n", err)); - return error; - } - - // The API lied. It really isn't an error code, but the message size... - char *pAllocd = NULL; - char *pMem = NULL; - char tmp[0x800]; - - if (error < 0x800) - pMem = tmp; - else { - pAllocd = new char[error]; - pMem = pAllocd; - } - - do { - error = read_port(reply_port, pCode, pMem, error); - } while (error == B_INTERRUPTED); - - if (error < 0) { - PRINT(("handle_reply() error 2: %lx\n", error)); - return error; - } - - if (*pCode == 'PUSH') { - PRINT(("handle_reply() error 3: %x\n", B_ERROR)); - return B_ERROR; - } - - if (*pCode != 'pjpp') { - PRINT(("handle_reply() error 4: port message code not 'pjpp' but " - "'%lx'\n", *pCode)); - return B_ERROR; - } - - error = reply->Unflatten(pMem); - - // There seems to be a bug in the original Be implementation. - // It never free'd pAllocd ! - if (pAllocd) - delete[] pAllocd; - - PRINT(("handle_reply() done: %lx\n", error)); - return error; -} - - -// convert_message -static status_t -convert_message(const KMessage *fromMessage, BMessage *toMessage) -{ - if (!fromMessage || !toMessage) - return B_BAD_VALUE; - - // make empty and init what of the target message - toMessage->MakeEmpty(); - toMessage->what = fromMessage->What(); - - // iterate through the fields and import them in the target message - KMessageField field; - while (fromMessage->GetNextField(&field) == B_OK) { - int32 elementCount = field.CountElements(); - if (elementCount > 0) { - for (int32 i = 0; i < elementCount; i++) { - int32 size; - const void *data = field.ElementAt(i, &size); - status_t error; - if (field.TypeCode() == B_MESSAGE_TYPE) { - // message type: if it's a KMessage, convert it - KMessage message; - if (message.SetTo(data, size) == B_OK) { - BMessage bMessage; - error = convert_message(&message, &bMessage); - if (error != B_OK) - return error; - error = toMessage->AddMessage(field.Name(), &bMessage); - } else { - // just add it - error = toMessage->AddData(field.Name(), - field.TypeCode(), data, size, - field.HasFixedElementSize(), 1); - } - } else { - error = toMessage->AddData(field.Name(), field.TypeCode(), - data, size, field.HasFixedElementSize(), 1); - } - - if (error != B_OK) - return error; - } - } - } - return B_OK; -} - - -static ssize_t -min_hdr_size() -{ - ssize_t size = 0; - - size += 4; // version - size += 4; // checksum - size += 4; // flattened size - size += 4; // 'what' - size += 1; // flags - - return size; -} diff --git a/src/kits/app/Message3.cpp b/src/kits/app/Message3.cpp deleted file mode 100644 index 37841ddc6a..0000000000 --- a/src/kits/app/Message3.cpp +++ /dev/null @@ -1,2034 +0,0 @@ -/* - * Copyright 2001-2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Erik Jaesler (erik@cgsoftware.com) - * DarkWyrm - * Ingo Weinhold - * Michael Lotz - */ - -/** BMessage class creates objects that store data and that - * can be processed in a message loop. BMessage objects - * are also used as data containers by the archiving and - * the scripting mechanisms. - */ - -// debugging -//#define DBG(x) x -#define DBG(x) ; -#define PRINT(x) DBG({ printf("[%6ld] ", find_thread(NULL)); printf x; }) - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "MessageBody3.h" -#include "MessageField3.h" -#include "MessageUtils3.h" -#include "dano_message.h" - -// flags for the overall message (the bitfield is 1 byte) -#define MSG_FLAG_BIG_ENDIAN 0x01 -#define MSG_FLAG_INCL_TARGET 0x02 -#define MSG_FLAG_INCL_REPLY 0x04 -#define MSG_FLAG_SCRIPT_MSG 0x08 - -#if 0 -// These are for future improvement -#define MSG_FLAG_USE_PREFERRED 0x10 -#define MSG_FLAG_REPLY_WANTED 0x20 -#define MSG_FLAG_REPLY_DONE 0x40 -#define MSG_FLAG_IS_REPLY 0x80 - -#define MSG_FLAG_HDR_MASK 0xF0 -#endif - -#define MSG_HEADER_MAX_SIZE 38 -#define MSG_NAME_MAX_SIZE 256 - -using namespace BPrivate; - -static const uint32 kMessageMagic = 'FOB1'; -static const uint32 kMessageMagicSwapped = '1BOF'; -static const uint32 kMessageMagicDano = 'FOB2'; -static const uint32 kMessageMagicDanoSwapped = '2BOF'; - -const char* B_SPECIFIER_ENTRY = "specifiers"; -const char* B_PROPERTY_ENTRY = "property"; -const char* B_PROPERTY_NAME_ENTRY = "name"; - -BBlockCache *BMessage::sMsgCache = NULL; -port_id BMessage::sReplyPorts[sNumReplyPorts]; -long BMessage::sReplyPortInUse[sNumReplyPorts]; - -static status_t handle_reply(port_id replyPort, int32 *pCode, - bigtime_t timeout, BMessage *reply); -static status_t convert_message(const KMessage *fromMessage, - BMessage *toMessage); -static ssize_t min_hdr_size(); - - -class BMessage::Header { -public: - Header() {}; - Header(const BMessage &message) { ReadFrom(message); }; - - status_t SetMagic(uint32 magic); - - status_t ReadFrom(BDataIO &stream); - void ReadFrom(const BMessage &message); - status_t WriteTo(BDataIO &stream, bool calculateCheckSum = true) const; - void WriteTo(BMessage &message) const; - - uint32 CalculateCheckSum() const; - uint32 CalculateHeaderSize() const; - uint32 CalculatedBodySize() const; - - bool IsSwapped() const { return fSwapped; }; - bool HasTarget() const { return (fFlags & MSG_FLAG_INCL_TARGET); }; - void SetTarget(int32 token, bool preferred); - - void Dump() const; - -private: - uint32 fMagic; - int32 fBodySize; - uint32 fWhat; - uint8 fFlags; - int32 fTargetToken; - port_id fReplyPort; - int32 fReplyToken; - team_id fReplyTeam; - bool fPreferredTarget; - bool fReplyRequired; - bool fReplyDone; - bool fIsReply; - bool fSwapped; -}; - - -status_t -BMessage::Header::SetMagic(uint32 magic) -{ - if (magic == kMessageMagicSwapped) - fSwapped = true; - else if (magic == kMessageMagic) - fSwapped = false; - else { - // This is *not* a message - return B_NOT_A_MESSAGE; - } - - fMagic = magic; - return B_OK; -} - - -status_t -BMessage::Header::ReadFrom(BDataIO &stream) -{ - int32 checkSum; - uchar csBuffer[MSG_HEADER_MAX_SIZE]; - - TReadHelper read_helper(&stream); - TChecksumHelper checksum_helper(csBuffer); - int32 flattenedSize; - - try { - read_helper.SetSwap(fSwapped); - - // get the checksum - read_helper(checkSum); - // get the size - read_helper(flattenedSize); - // get the what - read_helper(fWhat); - // get the flags - read_helper(fFlags); - - checksum_helper.Cache(flattenedSize); - checksum_helper.Cache(fWhat); - checksum_helper.Cache(fFlags); - - if (fFlags & MSG_FLAG_BIG_ENDIAN) { - // TODO: isn't this already indicated by the byte order of the - // message version? - } - - if (fFlags & MSG_FLAG_INCL_TARGET) { - // Get the target data - read_helper(fTargetToken); - checksum_helper.Cache(fTargetToken); - } - - if (fFlags & MSG_FLAG_INCL_REPLY) { - // Get the reply port - read_helper(fReplyPort); - read_helper(fReplyToken); - read_helper(fReplyTeam); - checksum_helper.Cache(fReplyPort); - checksum_helper.Cache(fReplyToken); - checksum_helper.Cache(fReplyTeam); - - // get the "big flags" - uint8 bigFlags; - // get the preferred flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fPreferredTarget = bigFlags; - - // get the reply requirement flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fReplyRequired = bigFlags; - - // get the reply done flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fReplyDone = bigFlags; - - // Get the "is reply" flag - read_helper(bigFlags); - checksum_helper.Cache(bigFlags); - fIsReply = bigFlags; - } - } catch (status_t &error) { - return error; - } - - fBodySize = flattenedSize - CalculateHeaderSize(); - - if (checkSum != checksum_helper.CheckSum()) - return B_NOT_A_MESSAGE; - - return B_OK; -} - - -void -BMessage::Header::ReadFrom(const BMessage &message) -{ - fMagic = kMessageMagic; - - fBodySize = message.fBody->FlattenedSize(); - fWhat = message.what; - fFlags = 0; -#ifdef B_HOST_IS_BENDIAN - fFlags |= MSG_FLAG_BIG_ENDIAN; -#endif - if (message.HasSpecifiers()) - fFlags |= MSG_FLAG_SCRIPT_MSG; - - if (message.fTarget != B_NULL_TOKEN) - fFlags |= MSG_FLAG_INCL_TARGET; - - if (message.fReplyTo.port >= 0 && - message.fReplyTo.target != B_NULL_TOKEN && - message.fReplyTo.team >= 0) { - fFlags |= MSG_FLAG_INCL_REPLY; - } - - fTargetToken = message.fTarget; - fReplyPort = message.fReplyTo.port; - fReplyToken = message.fReplyTo.target; - fReplyTeam = message.fReplyTo.team; - fPreferredTarget = message.fPreferred; - fReplyRequired = message.fReplyRequired; - fReplyDone = message.fReplyDone; - fIsReply = message.fIsReply; -} - - -status_t -BMessage::Header::WriteTo(BDataIO &stream, bool calculateCheckSum) const -{ - try { - // write the version of the binary data format - int32 data = fMagic; - write_helper(&stream, (const void *)&data, sizeof(data)); - - // compute checksum - data = (calculateCheckSum ? CalculateCheckSum() : 0); - write_helper(&stream, (const void *)&data, sizeof(data)); - - // write the flattened size of the entire message - data = CalculateHeaderSize() + fBodySize; - write_helper(&stream, (const void *)&data, sizeof(data)); - - // write the 'what' member - write_helper(&stream, (const void *)&fWhat, sizeof(fWhat)); - - // write the header flags - write_helper(&stream, (const void *)&fFlags, sizeof(fFlags)); - - // write targeting info if necessary - if (fFlags & MSG_FLAG_INCL_TARGET) { - data = fPreferredTarget ? B_PREFERRED_TOKEN : fTargetToken; - write_helper(&stream, (const void *)&data, sizeof(data)); - } - - // write reply info if necessary - if (fFlags & MSG_FLAG_INCL_REPLY) { - write_helper(&stream, (const void *)&fReplyPort, sizeof(fReplyPort)); - write_helper(&stream, (const void *)&fReplyToken, sizeof(fReplyToken)); - write_helper(&stream, (const void *)&fReplyTeam, sizeof(fReplyTeam)); - - uint8 bigFlags; - bigFlags = fPreferredTarget ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fReplyRequired ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fReplyDone ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - - bigFlags = fIsReply ? 1 : 0; - write_helper(&stream, (const void *)&bigFlags, sizeof(bigFlags)); - } - } catch (status_t &error) { - return error; - } - - return B_OK; -} - - -void -BMessage::Header::WriteTo(BMessage &message) const -{ - // make way for the new data - message.MakeEmpty(); - message.what = fWhat; - - message.fHasSpecifiers = fFlags & MSG_FLAG_SCRIPT_MSG; - - if (fFlags & MSG_FLAG_INCL_TARGET) { - // get the target data - message.fTarget = fTargetToken; - } - - if (fFlags & MSG_FLAG_INCL_REPLY) { - // get the reply port - message.fReplyTo.port = fReplyPort; - message.fReplyTo.target = fReplyToken; - message.fReplyTo.team = fReplyTeam; - - message.fWasDelivered = true; - - message.fPreferred = fPreferredTarget; - if (fPreferredTarget) - message.fTarget = B_PREFERRED_TOKEN; - - message.fReplyRequired = fReplyRequired; - message.fReplyDone = fReplyDone; - message.fIsReply = fIsReply; - } -} - - -uint32 -BMessage::Header::CalculateCheckSum() const -{ - uint8 buffer[MSG_HEADER_MAX_SIZE]; - BMemoryIO stream(buffer, sizeof(buffer)); - WriteTo(stream, false); - int32 size = stream.Position(); - return _checksum_(buffer + 8, size - 8); -} - - -uint32 -BMessage::Header::CalculateHeaderSize() const -{ - ssize_t size = min_hdr_size(); - - if (fTargetToken != B_NULL_TOKEN) - size += sizeof(fTargetToken); - - if (fReplyPort >= 0 && fReplyToken != B_NULL_TOKEN && fReplyTeam >= 0) { - size += sizeof(fReplyPort); - size += sizeof(fReplyToken); - size += sizeof(fReplyTeam); - - size += 4; // For the "big" flags - } - - return size; -} - - -uint32 -BMessage::Header::CalculatedBodySize() const -{ - return fBodySize; -} - - -void -BMessage::Header::SetTarget(int32 token, bool preferred) -{ - fTargetToken = token; - - if (fTargetToken == B_NULL_TOKEN) - fFlags &= ~MSG_FLAG_INCL_TARGET; - else - fFlags |= MSG_FLAG_INCL_TARGET; - - fPreferredTarget = preferred; -} - - -void -BMessage::Header::Dump() const -{ - printf("BMessage::Header:\n"); - printf(" magic: %lx\n", fMagic); - printf(" body size: %ld\n", fBodySize); - printf(" what: %lx\n", fWhat); - printf(" flags: %x\n", fFlags); - printf(" target token: %ld\n", fTargetToken); - printf(" reply port: %ld\n", fReplyPort); - printf(" reply token: %ld\n", fReplyToken); - printf(" reply team: %ld\n", fReplyTeam); - printf(" preferred target: %d\n", fPreferredTarget); - printf(" reply required: %d\n", fReplyRequired); - printf(" reply done: %d\n", fReplyDone); - printf(" is reply: %d\n", fIsReply); - printf(" swapped: %d\n", fSwapped); -} - - -void BMessage::_ReservedMessage1() {} -void BMessage::_ReservedMessage2() {} -void BMessage::_ReservedMessage3() {} - - -BMessage::BMessage() - : fBody(NULL) -{ - init_data(); -} - - -BMessage::BMessage(uint32 _what) - : fBody(NULL) -{ - init_data(); - what = _what; -} - - -BMessage::BMessage(const BMessage &other) - : fBody(NULL) -{ - init_data(); - *this = other; -} - - -BMessage::BMessage(BMessage *other) - : fBody(NULL) -{ - init_data(); - *this = *other; -} - - -BMessage::~BMessage() -{ - if (IsSourceWaiting()) { - SendReply(B_NO_REPLY); - } - - delete fBody; -} - - -BMessage & -BMessage::operator=(const BMessage &msg) -{ - what = msg.what; - - fTarget = msg.fTarget; - fOriginal = msg.fOriginal; - fCurSpecifier = msg.fCurSpecifier; - - fReplyTo.port = msg.fReplyTo.port; - fReplyTo.target = msg.fReplyTo.target; - fReplyTo.team = msg.fReplyTo.team; - fReplyTo.preferred = msg.fReplyTo.preferred; - - fPreferred = msg.fPreferred; - fReplyRequired = msg.fReplyRequired; - fReplyDone = msg.fReplyDone; - fIsReply = msg.fIsReply; - fWasDelivered = msg.fWasDelivered; - fReadOnly = msg.fReadOnly; - fHasSpecifiers = msg.fHasSpecifiers; - - *fBody = *(msg.fBody); - return *this; -} - - -void -BMessage::init_data() -{ - what = 0; - - fTarget = B_NULL_TOKEN; - fOriginal = NULL; - fCurSpecifier = -1; - - fReplyTo.port = -1; - fReplyTo.target = B_NULL_TOKEN; - fReplyTo.team = -1; - fReplyTo.preferred = false; - - fPreferred = false; - fReplyRequired = false; - fReplyDone = false; - fIsReply = false; - fWasDelivered = false; - fReadOnly = false; - fHasSpecifiers = false; - - if (fBody) - fBody->MakeEmpty(); - else - fBody = new BPrivate::BMessageBody(); -} - - -status_t -BMessage::GetInfo(type_code typeRequested, int32 which, char **name, - type_code *typeReturned, int32 *count) const -{ - return fBody->GetInfo(typeRequested, which, name, typeReturned, count); -} - - -status_t -BMessage::GetInfo(const char *name, type_code *type, int32 *count) const -{ - return fBody->GetInfo(name, type, count); -} - - -status_t -BMessage::GetInfo(const char *name, type_code *type, bool *fixed_size) const -{ - return fBody->GetInfo(name, type, fixed_size); -} - - -int32 -BMessage::CountNames(type_code type) const -{ - return fBody->CountNames(type); -} - - -bool -BMessage::IsEmpty() const -{ - return fBody->IsEmpty(); -} - - -bool -BMessage::IsSystem() const -{ - char a = char(what >> 24); - char b = char(what >> 16); - char c = char(what >> 8); - char d = char(what); - - // The BeBook says: - // ... we've adopted a strict convention for assigning values to all - // Be-defined constants. The value assigned will always be formed by - // combining four characters into a multicharacter constant, with the - // characters limited to uppercase letters and the underbar - // Between that and what's in AppDefs.h, this algo seems like a safe bet: - if (a == '_' && isupper(b) && isupper(c) && isupper(d)) - return true; - - return false; -} - - -bool -BMessage::IsReply() const -{ - return fIsReply; -} - - -void -BMessage::PrintToStream() const -{ - printf("BMessage: what = "); - printf("%c%c%c%c", (uint8)(what >> 24), (uint8)(what >> 16), - (uint8)(what >> 8), (uint8)what); - printf(" (0x%lX or %ld)\n", what, what); - - fBody->PrintToStream(); -} - - -status_t -BMessage::Rename(const char *old_entry, const char *new_entry) -{ - return fBody->Rename(old_entry, new_entry); -} - - -bool -BMessage::WasDelivered() const -{ - return fWasDelivered; -} - - -bool -BMessage::IsSourceWaiting() const -{ - return fReplyRequired && !fReplyDone; -} - - -bool -BMessage::IsSourceRemote() const -{ - return WasDelivered() && fReplyTo.team != BPrivate::current_team(); -} - - -BMessenger -BMessage::ReturnAddress() const -{ - if (WasDelivered()) { - BMessenger messenger; - BMessenger::Private(messenger).SetTo(fReplyTo.team, fReplyTo.port, - fReplyTo.target, fReplyTo.preferred); - return messenger; - } - - return BMessenger(); -} - - -const BMessage * -BMessage::Previous() const -{ - // TODO: test - // In particular, look to see if the "_previous_" field is used in R5 - if (!fOriginal) { - BMessage *fOriginal = new BMessage; - - if (FindMessage("_previous_", fOriginal) != B_OK) { - delete fOriginal; - fOriginal = NULL; - } - } - - return fOriginal; -} - - -bool -BMessage::WasDropped() const -{ - return fReadOnly; -} - - -BPoint -BMessage::DropPoint(BPoint *offset) const -{ - // TODO: Where do we get this stuff??? - if (offset) - *offset = FindPoint("_drop_offset_"); - - return FindPoint("_drop_point_"); -} - - -status_t -BMessage::SendReply(uint32 command, BHandler *reply_to) -{ - BMessage msg(command); - return SendReply(&msg, reply_to); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BHandler *reply_to, bigtime_t timeout) -{ - BMessenger messenger(reply_to); - return SendReply(the_reply, messenger, timeout); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BMessenger reply_to, bigtime_t timeout) -{ - // TODO: test - BMessenger messenger; - BMessenger::Private messengerPrivate(messenger); - messengerPrivate.SetTo(fReplyTo.team, fReplyTo.port, fReplyTo.target, - fReplyTo.preferred); - - if (fReplyRequired) { - if (fReplyDone) - return B_DUPLICATE_REPLY; - - fReplyDone = true; - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to, timeout); - the_reply->fIsReply = false; - - if (error) { - if (set_port_owner(messengerPrivate.Port(), - messengerPrivate.Team()) == B_BAD_TEAM_ID) { - delete_port(messengerPrivate.Port()); - } - } - - return error; - } - - // no reply required - if (!fWasDelivered) - return B_BAD_REPLY; - - the_reply->AddMessage("_previous_", this); - the_reply->fIsReply = true; - - status_t error = messenger.SendMessage(the_reply, reply_to, timeout); - the_reply->fIsReply = false; - the_reply->RemoveName("_previous_"); - - return error; -} - - -status_t -BMessage::SendReply(uint32 command, BMessage *reply_to_reply) -{ - BMessage msg(command); - return SendReply(&msg, reply_to_reply); -} - - -status_t -BMessage::SendReply(BMessage *the_reply, BMessage *reply_to_reply, - bigtime_t send_timeout, bigtime_t reply_timeout) -{ - // TODO: test - BMessenger messenger; - BMessenger::Private messengerPrivate(messenger); - messengerPrivate.SetTo(fReplyTo.team, fReplyTo.port, fReplyTo.target, - fReplyTo.preferred); - - if (fReplyRequired) { - if (fReplyDone) - return B_DUPLICATE_REPLY; - - fReplyDone = true; - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to_reply, - send_timeout, reply_timeout); - the_reply->fIsReply = false; - - if (error) { - if (set_port_owner(messengerPrivate.Port(), - messengerPrivate.Team()) == B_BAD_TEAM_ID) { - delete_port(messengerPrivate.Port()); - } - } - - return error; - } - - // no reply required - if (!fWasDelivered) - return B_BAD_REPLY; - - the_reply->AddMessage("_previous_", this); - the_reply->fIsReply = true; - status_t error = messenger.SendMessage(the_reply, reply_to_reply, - send_timeout, reply_timeout); - the_reply->fIsReply = false; - the_reply->RemoveName("_previous_"); - return error; -} - - -ssize_t -BMessage::FlattenedSize() const -{ - return calc_hdr_size() + fBody->FlattenedSize(); -} - - -status_t -BMessage::Flatten(char *buffer, ssize_t size) const -{ - return real_flatten(buffer, size); -} - - -status_t -BMessage::Flatten(BDataIO *stream, ssize_t *size) const -{ - return real_flatten(stream, size); -} - - -status_t -BMessage::Unflatten(const char *buffer) -{ - if (!buffer) - return B_BAD_VALUE; - - uint32 magic = *(uint32 *)buffer; - - // we support several message formats - this list is ordered - // by importance and frequency - - if (magic == kMessageMagic) { - // it appears to be a normal flattened BMessage - BMemoryIO memoryStream(buffer, ((uint32 *)buffer)[2]); - return Unflatten(&memoryStream); - } - - // check whether this is a KMessage - if (((KMessage::Header *)buffer)->magic == KMessage::kMessageHeaderMagic) - return _UnflattenKMessage(buffer); - - if (magic == kMessageMagicSwapped) { - // it appears to be a swapped flattened BMessage - uint32 size = ((uint32 *)buffer)[2]; - BMemoryIO memoryStream(buffer, __swap_int32(size)); - return Unflatten(&memoryStream); - } - - if (magic == kMessageMagicDano || magic == kMessageMagicDanoSwapped) { - // dano style message - BMemoryIO memoryStream(buffer, BPrivate::dano_message_size(buffer)); - return Unflatten(&memoryStream); - } - - return B_NOT_A_MESSAGE; -} - - -status_t -BMessage::Unflatten(BDataIO *stream) -{ - TReadHelper reader(stream); - Header header; - status_t status = B_OK; - - // ToDo: while reading from a stream is certainly more convenient than - // from a buffer, it causes a lot of unnecessary copies, and therefore - // probably shouldn't be the preferred (or only) route. - - try { - uint32 magic; - reader(magic); - - status = header.SetMagic(magic); - if (status < B_OK) { - // we support reading Dano messages from disk as well - if (magic == kMessageMagicDano) - return BPrivate::unflatten_dano_message(magic, *stream, *this); - - return status; - } - - status = header.ReadFrom(*stream); - if (status < B_OK) { - printf("BMessage::Unflatten(): Reading the header failed: %lx\n", status); - return status; - } - - header.WriteTo(*this); - - status = fBody->Unflatten(stream, header.CalculatedBodySize()); - } catch (status_t &error) { - status = error; - } - - return status; -} - - -status_t -BMessage::AddSpecifier(const char *property) -{ - BMessage message(B_DIRECT_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, int32 index) -{ - BMessage message(B_INDEX_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddInt32("index", index); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, int32 index, int32 range) -{ - if (range < 0) - return B_BAD_VALUE; - - BMessage message(B_RANGE_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddInt32("index", index); - if (error) - return error; - - error = message.AddInt32("range", range); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const char *property, const char *name) -{ - BMessage message(B_NAME_SPECIFIER); - status_t error = message.AddString(B_PROPERTY_ENTRY, property); - if (error) - return error; - - error = message.AddString(B_PROPERTY_NAME_ENTRY, name); - if (error) - return error; - - return AddSpecifier(&message); -} - - -status_t -BMessage::AddSpecifier(const BMessage *specifier) -{ - status_t error = AddMessage(B_SPECIFIER_ENTRY, specifier); - if (!error) { - fCurSpecifier++; - fHasSpecifiers = true; - } - - return error; -} - - -status_t -BMessage::SetCurrentSpecifier(int32 index) -{ - type_code type; - int32 count; - status_t error = GetInfo(B_SPECIFIER_ENTRY, &type, &count); - if (error) - return error; - - if (index < 0 || index >= count) - return B_BAD_INDEX; - - fCurSpecifier = index; - return B_OK; -} - - -status_t -BMessage::GetCurrentSpecifier(int32 *index, BMessage *specifier, int32 *what, - const char **property) const -{ - if (fCurSpecifier == -1 || !WasDelivered()) - return B_BAD_SCRIPT_SYNTAX; - - if (index) - *index = fCurSpecifier; - - if (specifier) { - if (FindMessage(B_SPECIFIER_ENTRY, fCurSpecifier, specifier)) - return B_BAD_SCRIPT_SYNTAX; - - if (what) - *what = specifier->what; - - if (property) { - if (specifier->FindString(B_PROPERTY_ENTRY, property)) - return B_BAD_SCRIPT_SYNTAX; - } - } - - return B_OK; -} - - -bool -BMessage::HasSpecifiers() const -{ - return fHasSpecifiers; -} - - -status_t -BMessage::PopSpecifier() -{ - if (fCurSpecifier < 0 || !WasDelivered()) - return B_BAD_VALUE; - - fCurSpecifier--; - return B_OK; -} - - -#define DEFINE_FUNCTIONS(TYPE, fnName, TYPESPEC) \ -status_t \ -BMessage::Add ## fnName(const char *name, TYPE val) \ -{ \ - return fBody->AddData(name, TYPESPEC, &val, sizeof(TYPE), true); \ -} \ - \ -status_t \ -BMessage::Find ## fnName(const char *name, TYPE *p) const \ -{ \ - return Find ## fnName(name, 0, p); \ -} \ - \ -status_t \ -BMessage::Find ## fnName(const char *name, int32 index, TYPE *p) const \ -{ \ - void *ptr = NULL; \ - ssize_t bytes = 0; \ - status_t error = B_OK; \ - \ - *p = TYPE(); \ - error = fBody->FindData(name, TYPESPEC, index, (const void **)&ptr, \ - &bytes); \ - \ - if (error == B_OK) \ - memcpy(p, ptr, sizeof(TYPE)); \ - \ - return error; \ -} \ - \ -status_t \ -BMessage::Replace ## fnName(const char* name, TYPE val) \ -{ \ - return fBody->ReplaceData(name, TYPESPEC, 0, &val, sizeof(TYPE)); \ -} \ - \ -status_t \ -BMessage::Replace ## fnName(const char *name, int32 index, TYPE val) \ -{ \ - return fBody->ReplaceData(name, TYPESPEC, index, &val, sizeof(TYPE)); \ -} \ - \ -bool \ -BMessage::Has ## fnName(const char *name, int32 n) const \ -{ \ - return fBody->HasData(name, TYPESPEC, n); \ -} - -DEFINE_FUNCTIONS(int8, Int8, B_INT8_TYPE); -DEFINE_FUNCTIONS(int16, Int16, B_INT16_TYPE); -DEFINE_FUNCTIONS(int32, Int32, B_INT32_TYPE); -DEFINE_FUNCTIONS(int64, Int64, B_INT64_TYPE); -DEFINE_FUNCTIONS(BPoint, Point, B_POINT_TYPE); -DEFINE_FUNCTIONS(BRect, Rect, B_RECT_TYPE); -DEFINE_FUNCTIONS(float, Float, B_FLOAT_TYPE); -DEFINE_FUNCTIONS(double, Double, B_DOUBLE_TYPE); -DEFINE_FUNCTIONS(bool, Bool, B_BOOL_TYPE); - -#undef DEFINE_FUNCTIONS - -#define DEFINE_HAS_FUNCTION(fnName, TYPESPEC) \ -bool \ -BMessage::Has ## fnName(const char* name, int32 n) const \ -{ \ - return fBody->HasData(name, TYPESPEC, n); \ -} - -DEFINE_HAS_FUNCTION(Message, B_MESSAGE_TYPE); -DEFINE_HAS_FUNCTION(String, B_STRING_TYPE); -DEFINE_HAS_FUNCTION(Pointer, B_POINTER_TYPE); -DEFINE_HAS_FUNCTION(Messenger, B_MESSENGER_TYPE); -DEFINE_HAS_FUNCTION(Ref, B_REF_TYPE); - -#undef DEFINE_HAS_FUNCTION - -#define DEFINE_LAZY_FIND_FUNCTION(TYPE, fnName) \ -TYPE \ -BMessage::Find ## fnName(const char* name, int32 n) const \ -{ \ - TYPE i = 0; \ - Find ## fnName(name, n, &i); \ - return i; \ -} - -DEFINE_LAZY_FIND_FUNCTION(int8, Int8); -DEFINE_LAZY_FIND_FUNCTION(int16, Int16); -DEFINE_LAZY_FIND_FUNCTION(int32, Int32); -DEFINE_LAZY_FIND_FUNCTION(int64, Int64); -DEFINE_LAZY_FIND_FUNCTION(float, Float); -DEFINE_LAZY_FIND_FUNCTION(double, Double); -DEFINE_LAZY_FIND_FUNCTION(bool, Bool); -DEFINE_LAZY_FIND_FUNCTION(const char *, String); - -#undef DEFINE_LAZY_FIND_FUNCTION - - -status_t -BMessage::AddString(const char *name, const char *string) -{ - return fBody->AddData(name, B_STRING_TYPE, string, strlen(string) + 1, false); -} - - -status_t -BMessage::AddString(const char* name, const BString &string) -{ - return fBody->AddData(name, B_STRING_TYPE, string.String(), string.Length() + 1, false); -} - - -status_t -BMessage::AddPointer(const char *name, const void *pointer) -{ - return fBody->AddData(name, B_POINTER_TYPE, &pointer, sizeof(pointer), true); -} - - -status_t -BMessage::AddMessenger(const char *name, BMessenger messenger) -{ - return fBody->AddData(name, B_MESSENGER_TYPE, &messenger, sizeof(messenger), true); -} - - -status_t -BMessage::AddRef(const char* name, const entry_ref* ref) -{ - size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH; - char buffer[size]; - - status_t error = entry_ref_flatten(buffer, &size, ref); - - if (error >= B_OK) - error = fBody->AddData(name, B_REF_TYPE, buffer, size, false); - - return error; -} - - -status_t -BMessage::AddMessage(const char *name, const BMessage *msg) -{ - ssize_t size = msg->FlattenedSize(); - void *buffer = NULL; - - status_t error = fBody->AddData(name, B_MESSAGE_TYPE, &buffer, size); - - if (error >= B_OK) - error = msg->Flatten((char *)buffer, size); - - return error; -} - - -status_t -BMessage::AddFlat(const char *name, BFlattenable *object, int32 count) -{ - ssize_t size = object->FlattenedSize(); - void *buffer = NULL; - - status_t error = fBody->AddData(name, object->TypeCode(), &buffer, size); - - if (error >= B_OK) - error = object->Flatten(buffer, size); - - return error; -} - - -status_t -BMessage::AddData(const char *name, type_code type, const void *data, - ssize_t numBytes, bool is_fixed_size, int32 /*count*/) -{ - return fBody->AddData(name, type, data, numBytes, is_fixed_size); -} - - -status_t -BMessage::RemoveData(const char *name, int32 index) -{ - return fReadOnly ? B_ERROR : fBody->RemoveData(name, index); -} - - -status_t -BMessage::RemoveName(const char *name) -{ - return fReadOnly ? B_ERROR : fBody->RemoveName(name); -} - - -status_t -BMessage::MakeEmpty() -{ - return fReadOnly ? B_ERROR : fBody->MakeEmpty(); -} - - -status_t -BMessage::FindString(const char *name, const char **string) const -{ - return FindString(name, 0, string); -} - - -status_t -BMessage::FindString(const char *name, int32 index, const char **string) const -{ - ssize_t bytes; - return FindData(name, B_STRING_TYPE, index, - (const void**)string, &bytes); -} - - -status_t -BMessage::FindString(const char *name, BString *string) const -{ - return FindString(name, 0, string); -} - - -status_t -BMessage::FindString(const char *name, int32 index, BString *string) const -{ - const char *cstr; - status_t err = FindString(name, index, &cstr); - if (err < B_OK) - return err; - - *string = cstr; - return B_OK; -} - - -status_t -BMessage::FindPointer(const char *name, void **ptr) const -{ - return FindPointer(name, 0, ptr); -} - - -status_t -BMessage::FindPointer(const char *name, int32 index, void **ptr) const -{ - void **data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_POINTER_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - *ptr = *data; - else - *ptr = NULL; - - return error; -} - - -status_t -BMessage::FindMessenger(const char *name, BMessenger *m) const -{ - return FindMessenger(name, 0, m); -} - - -status_t -BMessage::FindMessenger(const char *name, int32 index, BMessenger *m) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_MESSENGER_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - memcpy(m, data, sizeof(BMessenger)); - else - *m = BMessenger(); - - return error; -} - - -status_t -BMessage::FindRef(const char *name, entry_ref *ref) const -{ - return FindRef(name, 0, ref); -} - - -status_t -BMessage::FindRef(const char *name, int32 index, entry_ref *ref) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_REF_TYPE, index, (const void **)&data, &size); - - if (error == B_OK) - error = entry_ref_unflatten(ref, (char *)data, size); - else - *ref = entry_ref(); - - return error; -} - - -status_t -BMessage::FindMessage(const char *name, BMessage *msg) const -{ - return FindMessage(name, 0, msg); -} - - -status_t -BMessage::FindMessage(const char *name, int32 index, BMessage *msg) const -{ - void *data = NULL; - ssize_t size = 0; - status_t error = FindData(name, B_MESSAGE_TYPE, index, (const void **)&data, &size); - - if (!error) - error = msg->Unflatten((const char *)data); - else - *msg = BMessage(); - - return error; -} - - -status_t -BMessage::FindFlat(const char *name, BFlattenable *obj) const -{ - return FindFlat(name, 0, obj); -} - - -status_t -BMessage::FindFlat(const char *name, int32 index, BFlattenable *obj) const -{ - void *data = NULL; - ssize_t numBytes = 0; - status_t error = FindData(name, obj->TypeCode(), index, (const void **)&data, &numBytes); - - if (!error) - error = obj->Unflatten(obj->TypeCode(), data, numBytes); - - return error; -} - - -status_t -BMessage::FindData(const char *name, type_code type, const void **data, - ssize_t *numBytes) const -{ - return fBody->FindData(name, type, 0, data, numBytes); -} - - -status_t -BMessage::FindData(const char *name, type_code type, int32 index, - const void **data, ssize_t *numBytes) const -{ - return fBody->FindData(name, type, index, data, numBytes); -} - - -BRect -BMessage::FindRect(const char *name, int32 n) const -{ - BRect r(0, 0, -1, -1); - FindRect(name, n, &r); - return r; -} - - -BPoint -BMessage::FindPoint(const char *name, int32 n) const -{ - BPoint p(0, 0); - FindPoint(name, n, &p); - return p; -} - - -status_t -BMessage::ReplaceString(const char *name, const char *string) -{ - return ReplaceString(name, 0, string); -} - - -status_t -BMessage::ReplaceString(const char *name, int32 index, const char *string) -{ - return ReplaceData(name, B_STRING_TYPE, index, string, strlen(string)+1); -} - - -status_t -BMessage::ReplaceString(const char *name, const BString &string) -{ - return ReplaceString(name, 0, string); -} - - -status_t -BMessage::ReplaceString(const char *name, int32 index, const BString &string) -{ - return ReplaceData(name, B_STRING_TYPE, index, string.String(), string.Length()+1); -} - - -status_t -BMessage::ReplacePointer(const char *name, const void *ptr) -{ - return ReplacePointer(name, 0, ptr); -} - - -status_t -BMessage::ReplacePointer(const char *name, int32 index, const void *ptr) -{ - return ReplaceData(name, B_POINTER_TYPE, index, &ptr, sizeof(ptr)); -} - - -status_t -BMessage::ReplaceMessenger(const char *name, BMessenger messenger) -{ - return ReplaceData(name, B_MESSENGER_TYPE, 0, &messenger, sizeof(BMessenger)); -} - - -status_t -BMessage::ReplaceMessenger(const char *name, int32 index, BMessenger messenger) -{ - return ReplaceData(name, B_MESSENGER_TYPE, index, &messenger, sizeof(BMessenger)); -} - - -status_t -BMessage::ReplaceRef(const char *name, const entry_ref *ref) -{ - return ReplaceRef(name, 0, ref); -} - - -status_t -BMessage::ReplaceRef(const char *name, int32 index, const entry_ref *ref) -{ - size_t size = sizeof(entry_ref) + B_PATH_NAME_LENGTH; - char buffer[size]; - - status_t error = entry_ref_flatten(buffer, &size, ref); - - - if (error >= B_OK) - error = fBody->ReplaceData(name, B_REF_TYPE, index, &buffer, size); - - return error; -} - - -status_t -BMessage::ReplaceMessage(const char *name, const BMessage *msg) -{ - return ReplaceMessage(name, 0, msg); -} - - -status_t -BMessage::ReplaceMessage(const char *name, int32 index, const BMessage *msg) -{ - ssize_t size = msg->FlattenedSize(); - void *buffer = NULL; - - status_t error = fBody->ReplaceData(name, B_MESSAGE_TYPE, index, &buffer, size); - - if (error >= B_OK) - error = msg->Flatten((char *)buffer, size); - - return error; -} - - -status_t -BMessage::ReplaceFlat(const char *name, BFlattenable *object) -{ - return ReplaceFlat(name, 0, object); -} - - -status_t -BMessage::ReplaceFlat(const char *name, int32 index, BFlattenable *object) -{ - ssize_t size = object->FlattenedSize(); - void *buffer = NULL; - - status_t error = fBody->ReplaceData(name, object->TypeCode(), index, - &buffer, size); - - if (error >= B_OK) - error = object->Flatten(buffer, size); - - return error; -} - - -status_t -BMessage::ReplaceData(const char *name, type_code type, const void *data, - ssize_t data_size) -{ - return fBody->ReplaceData(name, type, 0, data, data_size); -} - - -status_t -BMessage::ReplaceData(const char *name, type_code type, int32 index, - const void *data, ssize_t data_size) -{ - return fBody->ReplaceData(name, type, index, data, data_size); -} - - -bool -BMessage::HasFlat(const char *name, const BFlattenable *flat) const -{ - return HasFlat(name, 0, flat); -} - - -bool -BMessage::HasFlat(const char *name, int32 n, const BFlattenable *flat) const -{ - return fBody->HasData(name, flat->TypeCode(), n); -} - - -bool -BMessage::HasData(const char *name, type_code t, int32 n) const -{ - return fBody->HasData(name, t, n); -} - - -void * -BMessage::operator new(size_t size) -{ - if (!sMsgCache) - sMsgCache = new BBlockCache(10, size, B_OBJECT_CACHE); - - return sMsgCache->Get(size); -} - - -void * -BMessage::operator new(size_t, void *p) -{ - return p; -} - - -void -BMessage::operator delete(void *ptr, size_t size) -{ - sMsgCache->Save(ptr, size); -} - - -status_t -BMessage::real_flatten(char *result, ssize_t size) const -{ - BMemoryIO stream((void *)result, size); - return real_flatten(&stream, NULL); -} - - -status_t -BMessage::real_flatten(BDataIO *stream, ssize_t *size) const -{ - Header header(*this); - - status_t error = header.WriteTo(*stream); - if (error >= B_OK) - error = fBody->Flatten(stream); - - if (size) - *size = FlattenedSize(); - - return error; -} - - -char * -BMessage::stack_flatten(char *stack_ptr, ssize_t stack_size, - bool /*incl_reply*/, ssize_t *size) const -{ - const ssize_t calcd_size = calc_hdr_size() + fBody->FlattenedSize(); - char *new_ptr = NULL; - if (calcd_size > stack_size) { - stack_ptr = new char[calcd_size]; - new_ptr = stack_ptr; - } - - real_flatten(stack_ptr, calcd_size); - if (size) - *size = calcd_size; - - return new_ptr; -} - - -status_t -BMessage::_UnflattenKMessage(const char *buffer) -{ - // init a real KMessage - KMessage message; - status_t error = message.SetTo(buffer, ((KMessage::Header*)buffer)->size); - if (error != B_OK) - return error; - - // let convert_message() do the real job - return convert_message(&message, this); -} - - -ssize_t -BMessage::calc_hdr_size() const -{ - ssize_t size = min_hdr_size(); - - if (fTarget != B_NULL_TOKEN) - size += sizeof(fTarget); - - if (fReplyTo.port >= 0 - && fReplyTo.target != B_NULL_TOKEN - && fReplyTo.team >= 0) { - size += sizeof(fReplyTo.port); - size += sizeof(fReplyTo.target); - size += sizeof(fReplyTo.team); - - size += 4; // For the "big" flags - } - - return size; -} - - -status_t -BMessage::_send_(port_id port, int32 token, bool preferred, bigtime_t timeout, - bool reply_required, BMessenger &reply_to) const -{ - PRINT(("BMessage::_send_(port: %ld, token: %ld, preferred: %d): " - "what: %lx (%.4s)\n", port, token, preferred, what, (char *)&what)); - - bool oldPreferred = fPreferred; - int32 oldTarget = fTarget; - reply_to_info oldReplyTo = fReplyTo; - - if (!reply_to.IsValid()) { - BMessenger::Private(reply_to).SetTo(fReplyTo.team, - fReplyTo.port, fReplyTo.target, fReplyTo.preferred); - if (!reply_to.IsValid()) - reply_to = be_app_messenger; - } - - BMessage *self = const_cast(this); - BMessenger::Private replyToPrivate(reply_to); - self->fPreferred = preferred; - self->fTarget = token; - self->fReplyRequired = reply_required; - self->fReplyTo.team = replyToPrivate.Team(); - self->fReplyTo.port = replyToPrivate.Port(); - self->fReplyTo.target = (replyToPrivate.IsPreferredTarget() - ? B_PREFERRED_TOKEN : replyToPrivate.Token()); - self->fReplyTo.preferred = replyToPrivate.IsPreferredTarget(); - - char tmp[0x800]; - ssize_t size; - char *p = stack_flatten(tmp, sizeof(tmp), true /* include reply */, &size); - char *pMem = p ? p : tmp; - status_t error; - - do { - error = write_port_etc(port, 'pjpp', pMem, size, B_RELATIVE_TIMEOUT, timeout); - } while (error == B_INTERRUPTED); - - if (p) - delete[] p; - - self->fPreferred = oldPreferred; - self->fTarget = oldTarget; - self->fReplyRequired = false; // To this copy, no reply is required. - // Only relevant when forwarding anyway. - self->fReplyTo = oldReplyTo; - - PRINT(("BMessage::_send_() done: %lx\n", error)); - return error; -} - - -status_t -BMessage::send_message(port_id port, team_id port_owner, int32 token, - bool preferred, BMessage *reply, bigtime_t send_timeout, - bigtime_t reply_timeout) const -{ - const int32 cached_reply_port = sGetCachedReplyPort(); - port_id reply_port; - status_t error; - - if (cached_reply_port == -1) { - // All the cached reply ports are in use; create a new one - reply_port = create_port(1 /* for one message */, "tmp_reply_port"); - if (reply_port < 0) - return reply_port; - } else { - assert(cached_reply_port < sNumReplyPorts); - reply_port = sReplyPorts[cached_reply_port]; - } - - team_id team = B_BAD_TEAM_ID; - if (be_app != NULL) - team = be_app->Team(); - else { - port_info pi; - error = get_port_info(reply_port, &pi); - if (error) - goto error; - - team = pi.team; - } - - error = set_port_owner(reply_port, port_owner); - if (error) - goto error; - - { - BMessenger messenger; - BMessenger::Private(messenger).SetTo(team, reply_port, - B_PREFERRED_TOKEN, false); - error = _send_(port, token, preferred, send_timeout, true, messenger); - } - - if (error) - goto error; - - int32 code; - error = handle_reply(reply_port, &code, reply_timeout, reply); - if (error && cached_reply_port >= 0) { - delete_port(reply_port); - sReplyPorts[cached_reply_port] = create_port(1, "tmp_rport"); - } - -error: - if (cached_reply_port >= 0) { - // Reclaim ownership of cached port - set_port_owner(reply_port, team); - // Flag as available - atomic_add(&sReplyPortInUse[cached_reply_port], -1); - return error; - } - - delete_port(reply_port); - return error; -} - - -// Note, that in case of a flattened BMessage setting the target token will -// change the header size, if no token was set when the message was flattened. -// Hence the message would need to unflattened and flattened again before it -// can be sent. -status_t -BMessage::_SendFlattenedMessage(void *data, int32 size, port_id port, - int32 token, bool preferred, bigtime_t timeout) -{ - if (!data) - return B_BAD_VALUE; - - uint32 magic = *(uint32 *)data; - - // prepare flattened fields - if (((KMessage::Header*)data)->magic == KMessage::kMessageHeaderMagic) { - // a KMessage - KMessage::Header *header = (KMessage::Header*)data; - header->targetToken = (preferred ? B_PREFERRED_TOKEN : token); - } else if (magic == kMessageMagic || magic == kMessageMagicSwapped) { - // get the header - BMemoryIO stream(data, size); - - stream.Read(&magic, sizeof(uint32)); - // "discard" the magic (we already know it anyway) - - Header header; - status_t error = header.SetMagic(magic); - if (error < B_OK) - return error; - - error = header.ReadFrom(stream); - if (error < B_OK) - return error; - - if (!header.HasTarget()) { - // fallback implementation -- the header size would change by - // setting the token - - // unflatten the message - BMessage message; - error = message.Unflatten((const char*)data); - if (error != B_OK) - return error; - - // send the message - BMessenger messenger; - return message._send_(port, token, preferred, timeout, false, - messenger); - } - - // set the target token and replace the header - header.SetTarget(token, preferred); - stream.Seek(0LL, SEEK_SET); - error = header.WriteTo(stream); - if (error != B_OK) - return error; - } else - return B_NOT_A_MESSAGE; - - // send the message - status_t error; - do { - error = write_port_etc(port, 'pjpp', data, size, B_RELATIVE_TIMEOUT, - timeout); - } while (error == B_INTERRUPTED); - - return error; -} - - -void -BMessage::_StaticCacheCleanup() -{ - delete sMsgCache; - sMsgCache = NULL; -} - - -void -BMessage::_StaticInit() -{ - sReplyPorts[0] = create_port(1, "tmp_rport0"); - sReplyPorts[1] = create_port(1, "tmp_rport1"); - sReplyPorts[2] = create_port(1, "tmp_rport2"); - - sReplyPortInUse[0] = 0; - sReplyPortInUse[1] = 0; - sReplyPortInUse[2] = 0; -} - - -void -BMessage::_StaticCleanup() -{ - delete_port(sReplyPorts[0]); - sReplyPorts[0] = -1; - delete_port(sReplyPorts[1]); - sReplyPorts[1] = -1; - delete_port(sReplyPorts[2]); - sReplyPorts[2] = -1; -} - - -int32 -BMessage::sGetCachedReplyPort() -{ - int index = -1; - for (int32 i = 0; i < sNumReplyPorts; i++) { - int32 old = atomic_add(&(sReplyPortInUse[i]), 1); - if (old == 0) { - // This entry is free - index = i; - break; - } else { - // This entry is being used. - atomic_add(&(sReplyPortInUse[i]), -1); - } - } - - return index; -} - - -static status_t -handle_reply(port_id reply_port, int32 *pCode, bigtime_t timeout, - BMessage *reply) -{ - PRINT(("handle_reply(port: %ld)\n", reply_port)); - - status_t error; - do { - error = port_buffer_size_etc(reply_port, 8, timeout); - } while (error == B_INTERRUPTED); - - if (error < B_OK) { - PRINT(("handle_reply() error 1: %lx\n", err)); - return error; - } - - // The API lied. It really isn't an error code, but the message size... - char *pAllocd = NULL; - char *pMem = NULL; - char tmp[0x800]; - - if (error < 0x800) - pMem = tmp; - else { - pAllocd = new char[error]; - pMem = pAllocd; - } - - do { - error = read_port(reply_port, pCode, pMem, error); - } while (error == B_INTERRUPTED); - - if (error < 0) { - PRINT(("handle_reply() error 2: %lx\n", error)); - return error; - } - - if (*pCode == 'PUSH') { - PRINT(("handle_reply() error 3: %x\n", B_ERROR)); - return B_ERROR; - } - - if (*pCode != 'pjpp') { - PRINT(("handle_reply() error 4: port message code not 'pjpp' but " - "'%lx'\n", *pCode)); - return B_ERROR; - } - - error = reply->Unflatten(pMem); - - // There seems to be a bug in the original Be implementation. - // It never free'd pAllocd ! - if (pAllocd) - delete[] pAllocd; - - PRINT(("handle_reply() done: %lx\n", error)); - return error; -} - - -// convert_message -static status_t -convert_message(const KMessage *fromMessage, BMessage *toMessage) -{ - if (!fromMessage || !toMessage) - return B_BAD_VALUE; - - // make empty and init what of the target message - toMessage->MakeEmpty(); - toMessage->what = fromMessage->What(); - - // iterate through the fields and import them in the target message - KMessageField field; - while (fromMessage->GetNextField(&field) == B_OK) { - int32 elementCount = field.CountElements(); - if (elementCount > 0) { - for (int32 i = 0; i < elementCount; i++) { - int32 size; - const void *data = field.ElementAt(i, &size); - status_t error; - if (field.TypeCode() == B_MESSAGE_TYPE) { - // message type: if it's a KMessage, convert it - KMessage message; - if (message.SetTo(data, size) == B_OK) { - BMessage bMessage; - error = convert_message(&message, &bMessage); - if (error != B_OK) - return error; - error = toMessage->AddMessage(field.Name(), &bMessage); - } else { - // just add it - error = toMessage->AddData(field.Name(), - field.TypeCode(), data, size, - field.HasFixedElementSize(), 1); - } - } else { - error = toMessage->AddData(field.Name(), field.TypeCode(), - data, size, field.HasFixedElementSize(), 1); - } - - if (error != B_OK) - return error; - } - } - } - return B_OK; -} - - -static ssize_t -min_hdr_size() -{ - ssize_t size = 0; - - size += 4; // version - size += 4; // checksum - size += 4; // flattened size - size += 4; // 'what' - size += 1; // flags - - return size; -} diff --git a/src/kits/app/MessageBody2.cpp b/src/kits/app/MessageBody2.cpp deleted file mode 100644 index de24e0a952..0000000000 --- a/src/kits/app/MessageBody2.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageBody handles data storage and retrieval for BMessage. */ - -#include -#include -#include -#include "MessageBody2.h" -#include "MessageUtils2.h" - -namespace BPrivate { - -BMessageBody::BMessageBody() -{ - InitCommon(); -} - - -BMessageBody::BMessageBody(const BMessageBody &other) -{ - InitCommon(); - *this = other; -} - - -BMessageBody::~BMessageBody() -{ - MakeEmpty(); - delete fFieldTable; -} - - -BMessageBody & -BMessageBody::operator=(const BMessageBody &other) -{ - if (this != &other) { - MakeEmpty(); - - for (int32 index = 0; index < other.fFieldList.CountItems(); index++) { - BMessageField *otherField = (BMessageField *)other.fFieldList.ItemAt(index); - BMessageField *newField = new BMessageField(*otherField); - fFieldList.AddItem((void *)newField); - HashInsert(newField); - } - } - - return *this; -} - - -status_t -BMessageBody::InitCommon() -{ - fFlattenedSize = -1; - fFieldTableSize = 100; - fFieldTable = new BMessageField *[fFieldTableSize]; - HashClear(); - return B_OK; -} - - -status_t -BMessageBody::GetInfo(type_code typeRequested, int32 which, char **name, - type_code *typeReturned, int32 *count) const -{ - int32 index = 0; - int32 fieldCount = fFieldList.CountItems(); - BMessageField *field = NULL; - bool found = false; - - for (int32 fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { - field = (BMessageField *)fFieldList.ItemAt(fieldIndex); - - if (typeRequested == B_ANY_TYPE || field->Type() == typeRequested) { - if (index == which) { - found = true; - break; - } - - index++; - } - } - - // we couldn't find any appropriate data - if (!found) { - if (count) - *count = 0; - - if (index > 0) - return B_BAD_INDEX; - else - return B_BAD_TYPE; - } - - // ToDo: BC Break - // Change 'name' parameter to const char * - - if (name) - *name = const_cast(field->Name()); - - if (typeReturned) - *typeReturned = field->Type(); - - if (count) - *count = field->CountItems(); - - return B_OK; -} - - -status_t -BMessageBody::GetInfo(const char *name, type_code *typeFound, - int32 *countFound) const -{ - status_t error = B_OK; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (typeFound) - *typeFound = field->Type(); - - if (countFound) - *countFound = field->CountItems(); - } else { - if (countFound) - *countFound = 0; - } - - return error; -} - - -status_t -BMessageBody::GetInfo(const char *name, type_code *typeFound, bool *fixedSize) const -{ - status_t error = B_OK; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (typeFound) - *typeFound = field->Type(); - - if (fixedSize) - *fixedSize = field->IsFixedSize(); - } - - return error; -} - - -int32 -BMessageBody::CountNames(type_code type) const -{ - if (type == B_ANY_TYPE) - return fFieldList.CountItems(); - - int32 count = 0; - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - if (field->Type() == type) - count++; - } - - return count; -} - - -bool -BMessageBody::IsEmpty() const -{ - return fFieldList.CountItems() == 0; -} - - -void -BMessageBody::PrintToStream() const -{ - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - field->PrintToStream(); - printf("\n"); - } -} - - -status_t -BMessageBody::Rename(const char *oldName, const char *newName) -{ - status_t error = B_OK; - BMessageField *field = FindData(oldName, B_ANY_TYPE, error); - - if (!field) - return B_NAME_NOT_FOUND; - - field->SetName(newName); - HashInsert(HashRemove(oldName)); - fFlattenedSize = -1; - return B_OK; -} - - -ssize_t -BMessageBody::FlattenedSize() const -{ - if (fFlattenedSize > 0) - return fFlattenedSize; - - ssize_t size = 1; // for MSG_LAST_ENTRY - - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - - uint8 flags = field->Flags(); - size += sizeof(flags) + sizeof(type_code); - - // count information - if (!(flags & MSG_FLAG_SINGLE_ITEM)) { - if (flags & MSG_FLAG_MINI_DATA) - size += sizeof(uint8); - else - size += sizeof(int32); - } - - // total size - if (flags & MSG_FLAG_MINI_DATA) - size += sizeof(uint8); - else - size += sizeof(size_t); - - // name length byte and name length - size += 1 + field->NameLength(); - - size += field->TotalSize(); - } - - // cache the value for next time. - // changing the body will reset this. - fFlattenedSize = size; - return size; -} - - -status_t -BMessageBody::Flatten(BDataIO *stream) const -{ - for (int32 index = 0; index < fFieldList.CountItems(); index++) - ((BMessageField *)fFieldList.ItemAt(index))->Flatten(stream); - - uint8 lastEntry = 0; - size_t error = stream->Write(&lastEntry, sizeof(lastEntry)); - - if (error > B_OK) - return B_OK; - else if (error == 0) - return B_ERROR; - - return error; -} - - -status_t -BMessageBody::Unflatten(BDataIO *stream) -{ - if (!IsEmpty()) - MakeEmpty(); - - BMessageField *newField = NULL; - try { - TReadHelper reader(stream); - - uint8 flags; - reader(flags); - - while (flags != MSG_LAST_ENTRY) { - newField = new BMessageField(flags, stream); - fFieldList.AddItem(newField); - HashInsert(newField); - reader(flags); - } - } catch (status_t &error) { - delete newField; - return error; - } - - return B_OK; -} - - -status_t -BMessageBody::AddData(const char *name, type_code type, size_t length, - void **buffer, bool fixedSize, int32 count) -{ - status_t error = B_OK; - BMessageField *newField = AddField(name, type, error); - - if (error < B_OK) - return error; - - if (fixedSize) { - error = newField->SetFixedSize(length, count); - if (error < B_OK) - return error; - } - - *buffer = newField->AddItem(length); - fFlattenedSize = -1; - return error; -} - - -BMessageField * -BMessageBody::AddField(const char *name, type_code type, status_t &error) -{ - BMessageField *foundField = FindData(name, type, error); - - if (foundField) { - error = B_OK; - return foundField; - } - - if (!foundField && error == B_NAME_NOT_FOUND) { - // add a new field if it's not yet present - BMessageField *newField = new BMessageField(name, type); - fFieldList.AddItem(newField); - HashInsert(newField); - error = B_OK; - return newField; - } - - return NULL; -} - - -status_t -BMessageBody::ReplaceData(const char *name, type_code type, int32 index, - size_t length, void **buffer) -{ - if (type == B_ANY_TYPE) - return B_BAD_VALUE; - - status_t error = B_OK; - BMessageField *field = FindData(name, type, error); - - if (error < B_OK) - return error; - - if (!field) - return B_ERROR; - - *buffer = field->ReplaceItem(index, length); - fFlattenedSize = -1; - return error; -} - - -status_t -BMessageBody::RemoveData(const char *name, int32 index) -{ - if (index < 0) - return B_BAD_VALUE; - - status_t error = B_OK; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (index < field->CountItems()) { - field->RemoveItem(index); - fFlattenedSize = -1; - - if (field->CountItems() == 0) - RemoveName(name); - } else - error = B_BAD_INDEX; - } - - return error; -} - - -status_t -BMessageBody::RemoveName(const char *name) -{ - status_t error = B_OK; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - fFieldList.RemoveItem(field); - fFlattenedSize = -1; - HashRemove(name); - delete field; - } - - return error; -} - - -status_t -BMessageBody::MakeEmpty() -{ - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - delete field; - } - - fFieldList.MakeEmpty(); - fFlattenedSize = -1; - HashClear(); - return B_OK; -} - - -bool -BMessageBody::HasData(const char *name, type_code type, int32 n) const -{ - if (!name || n < 0) - return false; - - status_t error; - BMessageField *field = FindData(name, type, error); - - if (!field) - return false; - - if (n >= field->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 error = B_OK; - *data = NULL; - - BMessageField *field = FindData(name, type, error); - if (error >= B_OK) { - if (index >= field->CountItems()) - return B_BAD_INDEX; - - *data = field->BufferAt(index, numBytes); - } - - return error; -} - - -BMessageField * -BMessageBody::FindData(const char *name, type_code type, status_t &error) const -{ - if (!name) { - error = B_BAD_VALUE; - return NULL; - } - - BMessageField *field = HashLookup(name); - if (field) { - if (type != B_ANY_TYPE && field->Type() != type) { - error = B_BAD_TYPE; - return NULL; - } - - error = B_OK; - return field; - } - - error = B_NAME_NOT_FOUND; - return NULL; -} - - -void -BMessageBody::HashInsert(BMessageField *field) -{ - uint32 index = HashString(field->Name()) % fFieldTableSize; - field->SetNext(fFieldTable[index]); - fFieldTable[index] = field; -} - - -BMessageField * -BMessageBody::HashLookup(const char *name) const -{ - uint32 index = HashString(name) % fFieldTableSize; - BMessageField *result = fFieldTable[index]; - - while (result) { - if (strcmp(result->Name(), name) == 0) - return result; - - result = result->Next(); - } - - return NULL; -} - - -BMessageField * -BMessageBody::HashRemove(const char *name) -{ - uint32 index = HashString(name) % fFieldTableSize; - BMessageField *result = fFieldTable[index]; - BMessageField *last = NULL; - - while (result) { - if (strcmp(result->Name(), name) == 0) { - if (last) - last->SetNext(result->Next()); - else - fFieldTable[index] = result->Next(); - - return result; - } - - last = result; - result = result->Next(); - } - - return NULL; -} - - -void -BMessageBody::HashClear() -{ - memset(fFieldTable, 0, fFieldTableSize * sizeof(BMessageField *)); -} - - -uint32 -BMessageBody::HashString(const char *string) const -{ - char ch; - uint32 result = 0; - - while ((ch = *string++) != 0) { - result = (result << 7) ^ (result >> 24); - result ^= ch; - } - - result ^= result << 12; - return result; -} - -} // namespace BPrivate diff --git a/src/kits/app/MessageBody3.cpp b/src/kits/app/MessageBody3.cpp deleted file mode 100644 index 3d4d23f7d4..0000000000 --- a/src/kits/app/MessageBody3.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -/* BMessageBody handles data storage and retrieval for BMessage. */ - -#include -#include -#include -#include -#include "MessageBody3.h" -#include "MessageField3.h" -#include "MessageUtils3.h" - -namespace BPrivate { - -void -dump_raw(uint8 *data, int32 length) -{ - int32 index = 0; - while (index < length) { - for (int32 line = 0; line < 40 && index < length; line++, index++) - printf("%02x ", data[index]); - printf("\n"); - } -} - - -BMessageBody::BMessageBody() -{ - InitCommon(); -} - - -BMessageBody::BMessageBody(const BMessageBody &other) -{ - InitCommon(); - *this = other; -} - - -BMessageBody::~BMessageBody() -{ - MakeEmpty(); - delete fFieldTable; -} - - -BMessageBody & -BMessageBody::operator=(const BMessageBody &other) -{ - if (this != &other) { - MakeEmpty(); - BMemoryIO memoryIO(other.fFlatBuffer, other.fFlatLength); - Unflatten(&memoryIO, other.fFlatLength); - } - - return *this; -} - - -status_t -BMessageBody::InitCommon() -{ - // use an avarage field size for each block - fBlockSize = sizeof(FieldHeader) + 50; - fFlatBuffer = (uint8 *)malloc(fBlockSize); - fFlatAllocated = fBlockSize; - fFlatLength = 0; - - // init hash table - fFieldTableSize = 100; - fFieldTable = new BMessageField *[fFieldTableSize]; - HashClear(); - return B_OK; -} - - -status_t -BMessageBody::GetInfo(type_code typeRequested, int32 which, char **name, - type_code *typeReturned, int32 *count) const -{ - int32 index = 0; - int32 fieldCount = fFieldList.CountItems(); - BMessageField *field = NULL; - bool found = false; - - for (int32 fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) { - field = (BMessageField *)fFieldList.ItemAt(fieldIndex); - - if (typeRequested == B_ANY_TYPE || field->Type() == typeRequested) { - if (index == which) { - found = true; - break; - } - - index++; - } - } - - // we couldn't find any appropriate data - if (!found) { - if (count) - *count = 0; - - if (index > 0) - return B_BAD_INDEX; - else - return B_BAD_TYPE; - } - - // ToDo: BC Break - // Change 'name' parameter to const char * - if (name) - *name = const_cast(field->Name()); - - if (typeReturned) - *typeReturned = field->Type(); - - if (count) - *count = field->CountItems(); - - return B_OK; -} - - -status_t -BMessageBody::GetInfo(const char *name, type_code *typeFound, - int32 *countFound) const -{ - status_t error = B_ERROR; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (typeFound) - *typeFound = field->Type(); - - if (countFound) - *countFound = field->CountItems(); - } else { - if (countFound) - *countFound = 0; - } - - return error; -} - - -status_t -BMessageBody::GetInfo(const char *name, type_code *typeFound, bool *fixedSize) const -{ - status_t error = B_ERROR; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (typeFound) - *typeFound = field->Type(); - - if (fixedSize) - *fixedSize = field->FixedSize(); - } - - return error; -} - - -int32 -BMessageBody::CountNames(type_code type) const -{ - if (type == B_ANY_TYPE) - return fFieldList.CountItems(); - - int32 count = 0; - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - if (field->Type() == type) - count++; - } - - return count; -} - - -bool -BMessageBody::IsEmpty() const -{ - return fFieldList.CountItems() == 0; -} - - -void -BMessageBody::PrintToStream() const -{ - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - field->PrintToStream(); - printf("\n"); - } -} - - -status_t -BMessageBody::Rename(const char *oldName, const char *newName) -{ - status_t error = B_ERROR; - BMessageField *field = FindData(oldName, B_ANY_TYPE, error); - - if (!field) - return error; - - field->SetName(newName); - HashInsert(HashRemove(oldName)); - return B_OK; -} - - -ssize_t -BMessageBody::FlattenedSize() const -{ - // one more for the last entry flag - return fFlatLength + 1; -} - - -status_t -BMessageBody::Flatten(BDataIO *stream) const -{ - stream->Write(fFlatBuffer, fFlatLength); - - uint8 lastField = MSG_LAST_ENTRY; - status_t error = stream->Write(&lastField, sizeof(lastField)); - - if (error < B_OK) - return error; - if (error == 0) - return B_ERROR; - - return B_OK; -} - - -status_t -BMessageBody::Unflatten(BDataIO *stream, int32 length) -{ - if (length <= 0) - return B_OK; - - FlatResize(length); - status_t error = stream->Read(fFlatBuffer, length); - - if (error < B_OK) - return B_ERROR; - - int32 offset = 0; - uint8 *location = fFlatBuffer; - while (offset < error && *location & MSG_FLAG_VALID) { - BMessageField *field = new BMessageField(this); - int32 fieldLength = field->Unflatten(offset); - - if (fieldLength <= 0) { - field->MakeEmpty(); - delete field; - MakeEmpty(); - return B_ERROR; - } - - location += fieldLength; - offset += fieldLength; - - fFieldList.AddItem(field); - HashInsert(field); - } - - // set the buffer to the actual size - FlatResize(offset); - return B_OK; -} - - -status_t -BMessageBody::AddData(const char *name, type_code type, const void *item, - ssize_t length, bool fixedSize) -{ - status_t error = B_ERROR; - BMessageField *field = AddData(name, type, error); - - if (!field) - return error; - - if (fixedSize) { - error = field->SetFixedSize(length); - if (error != B_OK) - return error; - } - - field->AddItem(item, length); - return B_OK; -} - - -status_t -BMessageBody::AddData(const char *name, type_code type, void **buffer, - ssize_t length) -{ - status_t error = B_ERROR; - BMessageField *field = AddData(name, type, error); - - if (!field) - return error; - - *buffer = field->AddItem(length); - return B_OK; -} - - -BMessageField * -BMessageBody::AddData(const char *name, type_code type, status_t &error) -{ - if (type == B_ANY_TYPE) { - error = B_BAD_VALUE; - return NULL; - } - - BMessageField *foundField = FindData(name, type, error); - - if (error < B_OK) { - if (error == B_NAME_NOT_FOUND) { - // reset the error - we will create the field - error = 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 NULL; - } - } - - if (foundField) - return foundField; - - // add a new field if it's not yet present - BMessageField *newField = new BMessageField(this, fFlatLength, name, type); - - fFieldList.AddItem(newField); - HashInsert(newField); - - return newField; -} - - -status_t -BMessageBody::ReplaceData(const char *name, type_code type, int32 index, - const void *item, ssize_t length) -{ - if (type == B_ANY_TYPE) - return B_BAD_VALUE; - - status_t error = B_ERROR; - BMessageField *field = FindData(name, type, error); - - if (!field) - return error; - - if (field->FixedSize()) { - ssize_t itemSize = 0; - void *item = field->ItemAt(0, &itemSize); - - if (item && itemSize != length) - return B_BAD_VALUE; - } - - field->ReplaceItem(index, item, length); - return B_OK; -} - - -status_t -BMessageBody::ReplaceData(const char *name, type_code type, int32 index, - void **buffer, ssize_t length) -{ - if (type == B_ANY_TYPE) - return B_BAD_VALUE; - - status_t error = B_ERROR; - BMessageField *field = FindData(name, type, error); - - if (!field) - return error; - - *buffer = field->ReplaceItem(index, length); - return B_OK; -} - - -status_t -BMessageBody::RemoveData(const char *name, int32 index) -{ - if (index < 0) - return B_BAD_VALUE; - - status_t error = B_ERROR; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (field) { - if (index < field->CountItems()) { - if (field->CountItems() == 1) - RemoveName(name); - else - field->RemoveItem(index); - } else - error = B_BAD_INDEX; - } - - return error; -} - - -status_t -BMessageBody::RemoveName(const char *name) -{ - status_t error = B_ERROR; - BMessageField *field = FindData(name, B_ANY_TYPE, error); - - if (!field) - return error; - - fFieldList.RemoveItem(field); - HashRemove(name); - field->MakeEmpty(); - field->RemoveSelf(); - delete field; - - return B_OK; -} - - -status_t -BMessageBody::MakeEmpty() -{ - for (int32 index = 0; index < fFieldList.CountItems(); index++) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - field->MakeEmpty(); - delete field; - } - - fFieldList.MakeEmpty(); - - free(fFlatBuffer); - fFlatBuffer = NULL; - fFlatLength = 0; - fFlatAllocated = 0; - - HashClear(); - return B_OK; -} - - -bool -BMessageBody::HasData(const char *name, type_code type, int32 index) const -{ - if (!name || index < 0) - return false; - - status_t error = B_ERROR; - BMessageField *field = FindData(name, type, error); - - if (!field) - return false; - - if (index >= field->CountItems()) - return false; - - return true; -} - - -status_t -BMessageBody::FindData(const char *name, type_code type, int32 index, - const void **data, ssize_t *numBytes) const -{ - if (!data) - return B_BAD_VALUE; - - status_t error = B_ERROR; - *data = NULL; - - BMessageField *field = FindData(name, type, error); - if (error >= B_OK) { - if (index >= field->CountItems()) - return B_BAD_INDEX; - - *data = field->ItemAt(index, numBytes); - } - - return error; -} - - -BMessageField * -BMessageBody::FindData(const char *name, type_code type, status_t &error) const -{ - if (!name) { - error = B_BAD_VALUE; - return NULL; - } - - BMessageField *field = HashLookup(name); - - if (field) { - if (type != B_ANY_TYPE && field->Type() != type) { - error = B_BAD_TYPE; - return NULL; - } - - error = B_OK; - return field; - } - - error = B_NAME_NOT_FOUND; - return NULL; -} - - -void -BMessageBody::FlatResize(int32 newSize) -{ - int32 newLength = (newSize + fBlockSize - 1) / fBlockSize * fBlockSize; - if (newLength != fFlatAllocated) { - fFlatBuffer = (uint8 *)realloc(fFlatBuffer, newLength); - if (newLength > fFlatAllocated) - memset(fFlatBuffer + fFlatAllocated, 0, newLength - fFlatAllocated); - fFlatAllocated = newLength; - } - - fFlatLength = newSize; -} - - -uint8 * -BMessageBody::FlatInsert(int32 offset, ssize_t oldLength, ssize_t newLength) -{ - if (oldLength == newLength) - return FlatBuffer() + offset; - - ssize_t change = newLength - oldLength; - ssize_t bufferLength = fFlatLength; - - if (change > 0) { - FlatResize(bufferLength + change); - - // usual case for adds - if (offset == bufferLength) - return FlatBuffer() + offset; - } - - ssize_t length = bufferLength - offset - oldLength; - if (length > 0) { - uint8 *location = FlatBuffer() + offset; - memmove(location + newLength, location + oldLength, length); - } - - if (change < 0) - FlatResize(bufferLength + change); - - for (int32 index = fFieldList.CountItems() - 1; index >= 0; index--) { - BMessageField *field = (BMessageField *)fFieldList.ItemAt(index); - if (field->Offset() <= offset) - break; - - field->SetOffset(field->Offset() + change); - } - - return FlatBuffer() + offset; -} - - -void -BMessageBody::HashInsert(BMessageField *field) -{ - uint32 index = HashString(field->Name()) % fFieldTableSize; - field->SetNext(fFieldTable[index]); - fFieldTable[index] = field; -} - - -BMessageField * -BMessageBody::HashLookup(const char *name) const -{ - uint32 index = HashString(name) % fFieldTableSize; - BMessageField *result = fFieldTable[index]; - - while (result) { - if (strcmp(result->Name(), name) == 0) - return result; - - result = result->Next(); - } - - return NULL; -} - - -BMessageField * -BMessageBody::HashRemove(const char *name) -{ - uint32 index = HashString(name) % fFieldTableSize; - BMessageField *result = fFieldTable[index]; - BMessageField *last = NULL; - - while (result) { - if (strcmp(result->Name(), name) == 0) { - if (last) - last->SetNext(result->Next()); - else - fFieldTable[index] = result->Next(); - - return result; - } - - last = result; - result = result->Next(); - } - - return NULL; -} - - -void -BMessageBody::HashClear() -{ - memset(fFieldTable, 0, fFieldTableSize * sizeof(BMessageField *)); -} - - -uint32 -BMessageBody::HashString(const char *string) const -{ - char ch; - uint32 result = 0; - - while ((ch = *string++) != 0) { - result = (result << 7) ^ (result >> 24); - result ^= ch; - } - - result ^= result << 12; - return result; -} - -} // namespace BPrivate diff --git a/src/kits/app/MessageField2.cpp b/src/kits/app/MessageField2.cpp deleted file mode 100644 index c3b6a609e8..0000000000 --- a/src/kits/app/MessageField2.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -#include -#include -#include -#include "MessageField2.h" -#include "MessageUtils2.h" - -namespace BPrivate { - -inline int32 -round_to_8(int32 length) -{ - // already includes the + 4 for size_t length field - return (length + 11) & ~7; -} - - -BMessageField::BMessageField() - : fItemSize(0), - fOffsets(NULL), - fNext(NULL) -{ - ResetHeader("", 0); -} - - -BMessageField::BMessageField(const char *name, type_code type) - : fItemSize(0), - fOffsets(NULL), - fNext(NULL) -{ - ResetHeader(name, type); -} - - -BMessageField::BMessageField(uint8 flags, BDataIO *stream) - : fItemSize(0), - fOffsets(NULL), - fNext(NULL) -{ - Unflatten(flags, stream); -} - - -BMessageField::BMessageField(const BMessageField &other) - : fItemSize(0), - fOffsets(NULL), - fNext(NULL) -{ - *this = other; -} - - -BMessageField::~BMessageField() -{ - MakeEmpty(); -} - - -BMessageField & -BMessageField::operator=(const BMessageField &other) -{ - if (this != &other) { - MakeEmpty(); - fNext = NULL; - - memcpy(&fHeader, &other.fHeader, sizeof(FieldHeader)); - - fFlatBuffer.Write(other.fFlatBuffer.Buffer(), other.fFlatBuffer.BufferLength()); - - if (other.fOffsets) { - int32 count = other.fOffsets->CountItems(); - fOffsets = new BList(count); - - for (int32 index = 0; index < count; index++) - fOffsets->AddItem(other.fOffsets->ItemAt(index)); - } else { - fItemSize = other.fItemSize; - } - } - - return *this; -} - - -void -BMessageField::Flatten(BDataIO *stream) -{ - // write flat header including name - stream->Write(&fHeader, sizeof(fHeader) - sizeof(fHeader.name) + fHeader.nameLength); - - // write flat data - stream->Write(fFlatBuffer.Buffer(), fHeader.dataSize); -} - - -void -BMessageField::Unflatten(uint8 flags, BDataIO *stream) -{ - TReadHelper reader(stream); - - // read the header - if (flags == MSG_FLAG_VALID - || flags == MSG_FLAG_VALID | MSG_FLAG_FIXED_SIZE) { - // we can read the header as flat data - fHeader.flags = flags; - stream->Read(&fHeader.type, sizeof(fHeader) - sizeof(fHeader.flags) - sizeof(fHeader.name)); - stream->Read(&fHeader.name, fHeader.nameLength); - fItemSize = fHeader.dataSize / fHeader.count; - } else { - // we have to disassemble the header - type_code type; - reader(type); - ResetHeader("", type); - - if (flags & MSG_FLAG_SINGLE_ITEM) { - fHeader.count = 1; - - if (flags & MSG_FLAG_MINI_DATA) { - uint8 littleData; - reader(littleData); - fHeader.dataSize = littleData; - } else - reader(fHeader.dataSize); - } else { - if (flags & MSG_FLAG_MINI_DATA) { - uint8 littleData; - reader(littleData); - fHeader.count = littleData; - - reader(littleData); - fHeader.dataSize = littleData; - } else { - reader(fHeader.count); - reader(fHeader.dataSize); - } - } - - reader(fHeader.nameLength); - reader(fHeader.name, fHeader.nameLength); - } - - // now read the data - fFlatBuffer.SetSize(fHeader.dataSize); - stream->Read((void *)fFlatBuffer.Buffer(), fHeader.dataSize); - - // ToDo: enable swapping - // swap the data if necessary - if (false) { - // is the data fixed size? - if (flags & MSG_FLAG_FIXED_SIZE) { - // make sure to swap the data - status_t status = swap_data(fHeader.type, - (void *)fFlatBuffer.Buffer(), fHeader.dataSize, B_SWAP_ALWAYS); - if (status < B_OK) - throw status; - } else if (fHeader.type == B_REF_TYPE) { - // apparently, entry_refs are the only variable-length data - // explicitely swapped -- the dev_t and ino_t specifically - // ToDo: this looks broken - byte_swap(*(entry_ref *)fFlatBuffer.Buffer()); - } - } -} - - -void -BMessageField::ResetHeader(const char *name, type_code type) -{ - memset(&fHeader, 0, sizeof(fHeader)); - fHeader.flags |= MSG_FLAG_VALID; - fHeader.type = type; - SetName(name); -} - - -void -BMessageField::MakeEmpty() -{ - fFlatBuffer.SetSize(0); - - if (fOffsets) - fOffsets->MakeEmpty(); - - fHeader.dataSize = 0; - fHeader.count = 0; -} - - -status_t -BMessageField::SetFixedSize(int32 itemSize, int32 /*count*/) -{ - // ToDo: use count here to preallocate the buffer - if (fHeader.count > 0 && itemSize != fItemSize) { - debugger("not allowed\n"); - return B_BAD_VALUE; - } - - fItemSize = itemSize; - fHeader.flags |= MSG_FLAG_FIXED_SIZE; - return B_OK; -} - - -void -BMessageField::SetName(const char *name) -{ - fHeader.nameLength = min_c(strlen(name), 254); - memcpy(fHeader.name, name, fHeader.nameLength); -} - - -void * -BMessageField::AddItem(size_t length) -{ - fHeader.count++; - - int32 offset = fFlatBuffer.BufferLength(); - if (fHeader.flags & MSG_FLAG_FIXED_SIZE) { - fHeader.dataSize += length; - fFlatBuffer.SetSize(offset + length); - return (char *)fFlatBuffer.Buffer() + offset; - } - - if (!fOffsets) - fOffsets = new BList(); - - fOffsets->AddItem((void *)offset); - - size_t newLength = round_to_8(length); - fHeader.dataSize += newLength; - FlatResize(offset, 0, newLength); - fFlatBuffer.WriteAt(offset, &length, sizeof(length)); - return (char *)fFlatBuffer.Buffer() + offset + sizeof(newLength); -} - - -void * -BMessageField::ReplaceItem(int32 index, size_t newLength) -{ - if (fHeader.flags & MSG_FLAG_FIXED_SIZE) - return (char *)fFlatBuffer.Buffer() + (index * fItemSize); - - int32 offset = (int32)fOffsets->ItemAt(index); - - size_t oldLength; - fFlatBuffer.ReadAt(offset, &oldLength, sizeof(oldLength)); - fFlatBuffer.WriteAt(offset, &newLength, sizeof(newLength)); - - oldLength = round_to_8(oldLength); - newLength = round_to_8(newLength); - - if (oldLength == newLength) - return (char *)fFlatBuffer.Buffer() + offset + sizeof(newLength); - - FlatResize(offset, oldLength, newLength); - fHeader.dataSize += newLength - oldLength; - - return (char *)fFlatBuffer.Buffer() + offset + sizeof(newLength); -} - - -void -BMessageField::RemoveItem(int32 index) -{ - fHeader.count--; - - if (fHeader.flags & MSG_FLAG_FIXED_SIZE) { - FlatResize(index * fItemSize, fItemSize, 0); - fHeader.dataSize -= fItemSize; - return; - } - - size_t oldLength; - int32 offset = (int32)fOffsets->ItemAt(index); - fFlatBuffer.ReadAt(offset, &oldLength, sizeof(oldLength)); - oldLength = round_to_8(oldLength); - - FlatResize(offset, oldLength, 0); - fHeader.dataSize -= oldLength; -} - - -const void * -BMessageField::BufferAt(int32 index, ssize_t *size) const -{ - if (fHeader.flags & MSG_FLAG_FIXED_SIZE) { - if (size) - *size = fItemSize; - - return (char *)fFlatBuffer.Buffer() + (index * fItemSize); - } - - int32 offset = (int32)fOffsets->ItemAt(index); - if (size) - fFlatBuffer.ReadAt(offset, size, sizeof(ssize_t)); - - return (char *)fFlatBuffer.Buffer() + offset + sizeof(ssize_t); -} - - -void -BMessageField::PrintToStream() const -{ - // ToDo: implement -} - - -void -BMessageField::FlatResize(int32 offset, size_t oldLength, size_t newLength) -{ - ssize_t change = newLength - oldLength; - ssize_t bufferLength = fFlatBuffer.BufferLength(); - - if (change > 0) - fFlatBuffer.SetSize(bufferLength + change); - - if (offset == bufferLength) { - // the easy case for adds - return; - } - - ssize_t length = bufferLength - offset - oldLength; - if (length > 0) { - uint8 *location = (uint8 *)fFlatBuffer.Buffer() + offset; - memmove(location + newLength, location + oldLength, length); - } - - if (change < 0) - fFlatBuffer.SetSize(bufferLength + change); - - for (int32 index = fOffsets->CountItems() - 1; index >= 0; index--) { - int32 oldOffset = (int32)fOffsets->ItemAt(index); - if (oldOffset <= offset) - break; - - fOffsets->ReplaceItem(index, (void *)(offset + change)); - } -} - -} // namespace BPrivate diff --git a/src/kits/app/MessageField3.cpp b/src/kits/app/MessageField3.cpp deleted file mode 100644 index 209ec0ec6a..0000000000 --- a/src/kits/app/MessageField3.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright 2005, Haiku. - * Distributed under the terms of the MIT License. - * - * Authors: - * Michael Lotz - */ - -#include -#include -#include -#include "MessageBody3.h" -#include "MessageField3.h" - -namespace BPrivate { - -#define DATA_OFFSET (fOffset + fDataOffset) - -inline int32 -round_to_8(int32 length) -{ - // already includes the + 4 for size_t length field - return (length + 11) & ~7; -} - - -BMessageField::BMessageField(BMessageBody *parent, int32 offset, - const char *name, type_code type) - : fParent(parent), - fOffset(offset), - fDataOffset(0), - fFixedSize(false), - fItemSize(0), - fItemInfos(5), - fNext(NULL) -{ - // insert space needed for the header - fParent->FlatInsert(fOffset, 0, sizeof(FieldHeader)); - - // fill the header - FieldHeader *header = Header(); - header->type = type; - header->flags = MSG_FLAG_VALID; - header->count = 0; - header->dataSize = 0; - header->nameLength = 0; - - SetName(name); -} - - -BMessageField::BMessageField(BMessageBody *parent) - : fParent(parent), - fOffset(0), - fDataOffset(0), - fFixedSize(false), - fItemSize(0), - fItemInfos(5), - fNext(NULL) -{ -} - - -int32 -BMessageField::Unflatten(int32 _offset) -{ - fOffset = _offset; - - // field is already present, just tap into it - FieldHeader *header = Header(); - fDataOffset = sizeof(FieldHeader) + header->nameLength; - fFixedSize = header->flags & MSG_FLAG_FIXED_SIZE; - - if (fFixedSize) { - if (header->count > 0) - fItemSize = header->dataSize / header->count; - return fDataOffset + header->count * fItemSize; - } - - // create the item info list - int32 offset = 0; - uint8 *location = fParent->FlatBuffer() + DATA_OFFSET; - for (int32 index = 0; index < header->count; index++) { - ItemInfo *info = new ItemInfo(offset); - info->length = *(size_t *)location; - info->paddedLength = round_to_8(info->length); - fItemInfos.AddItem(info); - - offset += info->paddedLength; - location += info->paddedLength; - } - - return fDataOffset + offset; -} - - -void -BMessageField::SetName(const char *newName) -{ - int32 newLength = min_c(strlen(newName), B_FIELD_NAME_LENGTH - 1) + 1; - char *buffer = (char *)fParent->FlatInsert(fOffset + sizeof(FieldHeader), - Header()->nameLength, newLength); - - strncpy(buffer, newName, newLength - 1); - buffer[newLength - 1] = 0; - - Header()->nameLength = newLength; - fDataOffset = sizeof(FieldHeader) + newLength; -} - - -const char * -BMessageField::Name() const -{ - return (const char *)(fParent->FlatBuffer() + fOffset + sizeof(FieldHeader)); -} - - -status_t -BMessageField::SetFixedSize(int32 itemSize) -{ - if (fItemInfos.CountItems() > 0 - && (fItemSize > 0 && fItemSize != itemSize)) - return B_BAD_VALUE; - - fItemSize = itemSize; - Header()->flags |= MSG_FLAG_FIXED_SIZE; - fFixedSize = true; - return B_OK; -} - - -void -BMessageField::AddItem(const void *item, ssize_t length) -{ - memcpy(AddItem(length), item, length); -} - - -uint8 * -BMessageField::AddItem(ssize_t length) -{ - FieldHeader *header = Header(); - - if (fFixedSize) { - int32 offset = DATA_OFFSET + (header->count * fItemSize); - header->dataSize += fItemSize; - header->count++; - return fParent->FlatInsert(offset, 0, fItemSize); - } - - int32 newOffset = 0; - if (header->count > 0) { - ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(header->count - 1); - newOffset = info->offset + info->paddedLength; - } - - ItemInfo *newInfo = new ItemInfo(newOffset, length); - newInfo->paddedLength = round_to_8(length); - - fItemInfos.AddItem(newInfo); - header->dataSize += newInfo->paddedLength; - header->count++; - - uint8 *result = fParent->FlatInsert(DATA_OFFSET + newInfo->offset, 0, newInfo->paddedLength); - *(int32 *)result = length; - return result + sizeof(int32); -} - - -void -BMessageField::ReplaceItem(int32 index, const void *newItem, ssize_t length) -{ - memcpy(ReplaceItem(index, length), newItem, length); -} - - -uint8 * -BMessageField::ReplaceItem(int32 index, ssize_t length) -{ - if (fFixedSize) - return fParent->FlatBuffer() + DATA_OFFSET + (index * fItemSize); - - ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(index); - int32 newLength = round_to_8(length); - - if (info->paddedLength == newLength) { - uint8 *result = fParent->FlatBuffer() + DATA_OFFSET + info->offset; - info->length = length; - *(int32 *)result = length; - return result + sizeof(int32); - } - - FieldHeader *header = Header(); - int32 change = newLength - info->paddedLength; - for (int32 i = index + 1; i < header->count; i++) - ((ItemInfo *)fItemInfos.ItemAt(i))->offset += change; - header->dataSize += change; - - int32 oldLength = info->paddedLength; - info->length = length; - info->paddedLength = newLength; - - uint8 *result = fParent->FlatInsert(DATA_OFFSET + info->offset, oldLength, newLength); - *(int32 *)result = length; - return result + sizeof(int32); -} - - -void * -BMessageField::ItemAt(int32 index, ssize_t *size) -{ - if (fFixedSize) { - if (size) - *size = fItemSize; - - return fParent->FlatBuffer() + DATA_OFFSET + (index * fItemSize); - } - - ItemInfo *info = (ItemInfo *)fItemInfos.ItemAt(index); - - if (size) - *size = info->length; - - return fParent->FlatBuffer() + DATA_OFFSET + info->offset + sizeof(int32); -} - - -void -BMessageField::RemoveItem(int32 index) -{ - FieldHeader *header = Header(); - - if (fFixedSize) { - header->count--; - header->dataSize -= fItemSize; - fParent->FlatInsert(DATA_OFFSET + (index * fItemSize), fItemSize, 0); - return; - } - - ItemInfo *info = (ItemInfo *)fItemInfos.RemoveItem(index); - - for (int32 i = index; i < header->count; i++) - ((ItemInfo *)fItemInfos.ItemAt(i))->offset -= info->paddedLength; - - header->count--; - header->dataSize -= info->paddedLength; - fParent->FlatInsert(DATA_OFFSET + info->offset, info->paddedLength, 0); - delete info; -} - - -void -BMessageField::PrintToStream() const -{ - FieldHeader *header = Header(); - printf("\tname: \"%s\"; items: %ld; dataSize: %ld; flags: %02x; offset: %ld", Name(), header->count, header->dataSize, header->flags, fOffset); - // ToDo: implement for real -} - - -void -BMessageField::MakeEmpty() -{ - for (int32 index = 0; index < fItemInfos.CountItems(); index++) - delete (ItemInfo *)fItemInfos.ItemAt(index); - - fItemInfos.MakeEmpty(); -} - - -void -BMessageField::RemoveSelf() -{ - // remove ourself from the flat buffer - int32 dataSize = Header()->dataSize; - fParent->FlatInsert(fOffset, fDataOffset + dataSize, 0); - fOffset = 0; -} - -} // namespace BPrivate