* Ported over a simplified version (no message sending) of the current BMessage implementation to the build libbe

* Also ported over the new MessageAdapter class
* Removed old BMessage implementation prototypes that apparently were left in the private folder

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21515 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2007-06-27 20:33:51 +00:00
parent 5dc45eb4fe
commit da0f338e87
21 changed files with 2852 additions and 5337 deletions

View File

@ -1,76 +1,33 @@
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: Message.h
// Author(s): Erik Jaesler (erik@cgsoftware.com)
// DarkWyrm <bpmagic@columbus.rr.com>
// 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.
//------------------------------------------------------------------------------
/*
* Copyright 2005-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#ifndef _MESSAGE_H
#define _MESSAGE_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <BeBuild.h>
#include <OS.h>
#include <Rect.h>
#include <DataIO.h>
#include <Flattenable.h>
#include <OS.h>
#include <Rect.h>
#include <AppDefs.h> /* For convenience */
#include <TypeConstants.h> /* For convenience */
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
class BBlockCache;
class BMessenger;
class BHandler;
class BString;
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 ---------------------------------------
// Name lengths and Scripting specifiers
#define B_FIELD_NAME_LENGTH 255
#define B_PROPERTY_NAME_LENGTH 255
enum
{
enum {
B_NO_SPECIFIER = 0,
B_DIRECT_SPECIFIER = 1,
B_INDEX_SPECIFIER,
@ -81,359 +38,245 @@ enum
B_ID_SPECIFIER,
B_SPECIFIERS_END = 128
// app-defined specifiers start at B_SPECIFIERS_END+1
// app-defined specifiers start at B_SPECIFIERS_END + 1
};
namespace BPrivate {
class BMessageBody;
}
class BMessage {
public:
uint32 what;
// BMessage class --------------------------------------------------------------
class BMessage
{
public:
uint32 what;
BMessage();
BMessage(uint32 what);
BMessage(const BMessage &other);
virtual ~BMessage();
BMessage();
BMessage(uint32 what);
BMessage(const BMessage &a_message);
virtual ~BMessage();
BMessage &operator=(const BMessage &other);
BMessage &operator=(const BMessage &msg);
// Statistics and misc info
status_t GetInfo(type_code typeRequested, int32 index,
char **nameFound, 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;
// Statistics and misc info
status_t GetInfo(type_code typeRequested, int32 which, char **name,
type_code *typeReturned, int32 *count = NULL) const;
int32 CountNames(type_code type) const;
bool IsEmpty() const;
bool IsSystem() const;
bool IsReply() const;
void PrintToStream() 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;
status_t Rename(const char *oldEntry, const char *newEntry);
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;
BMessenger ReturnAddress() const;
// Delivery info
bool WasDelivered() const;
bool IsSourceWaiting() const;
BMessenger ReturnAddress() const;
const BMessage *Previous() const;
bool WasDropped() const;
BPoint DropPoint(BPoint *offset = NULL) const;
bool WasDropped() const;
BPoint DropPoint(BPoint *offset = NULL) const;
// 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);
// 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 *flatBuffer);
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);
// 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 *what = NULL,
const char **property = NULL) const;
bool HasSpecifiers() const;
status_t PopSpecifier();
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 aRect);
status_t AddPoint(const char *name, BPoint aPoint);
status_t AddString(const char *name, const char *aString);
status_t AddString(const char *name, const BString &aString);
status_t AddInt8(const char *name, int8 value);
status_t AddInt16(const char *name, int16 value);
status_t AddInt32(const char *name, int32 value);
status_t AddInt64(const char *name, int64 value);
status_t AddBool(const char *name, bool aBoolean);
status_t AddFloat(const char *name, float aFloat);
status_t AddDouble(const char *name, double aDouble);
status_t AddPointer(const char *name, const void *aPointer);
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 *message);
status_t AddFlat(const char *name, BFlattenable *object,
int32 count = 1);
status_t AddData(const char *name, type_code type,
const void *data, ssize_t numBytes,
bool isFixedSize = true, int32 count = 1);
// 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();
// 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,
// 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 *point) const;
status_t FindPoint(const char *name, int32 index, BPoint *point) const;
status_t FindString(const char *name, const char **string) const;
status_t FindString(const char *name, int32 index, const char **string) const;
status_t FindString(const char *name, BString *string) const;
status_t FindString(const char *name, int32 index, BString *string) const;
status_t FindInt8(const char *name, int8 *value) const;
status_t FindInt8(const char *name, int32 index, int8 *value) const;
status_t FindInt16(const char *name, int16 *value) const;
status_t FindInt16(const char *name, int32 index, int16 *value) const;
status_t FindInt32(const char *name, int32 *value) const;
status_t FindInt32(const char *name, int32 index, int32 *value) const;
status_t FindInt64(const char *name, int64 *value) const;
status_t FindInt64(const char *name, int32 index, int64 *value) 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 *value) const;
status_t FindFloat(const char *name, int32 index, float *value) const;
status_t FindDouble(const char *name, double *value) const;
status_t FindDouble(const char *name, int32 index, double *value) const;
status_t FindPointer(const char *name, void **pointer) const;
status_t FindPointer(const char *name, int32 index, void **pointer) const;
status_t FindMessenger(const char *name, BMessenger *messenger) const;
status_t FindMessenger(const char *name, int32 index, BMessenger *messenger) 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 *message) const;
status_t FindMessage(const char *name, int32 index, BMessage *message) const;
status_t FindFlat(const char *name, BFlattenable *object) const;
status_t FindFlat(const char *name, int32 index, BFlattenable *object) 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,
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);
// Replacing data
status_t ReplaceRect(const char *name, BRect aRect);
status_t ReplaceRect(const char *name, int32 index, BRect aRect);
status_t ReplacePoint(const char *name, BPoint aPoint);
status_t ReplacePoint(const char *name, int32 index, BPoint aPoint);
status_t ReplaceString(const char *name, const char *aString);
status_t ReplaceString(const char *name, int32 index, const char *aString);
status_t ReplaceString(const char *name, const BString &aString);
status_t ReplaceString(const char *name, int32 index, const BString &aString);
status_t ReplaceInt8(const char *name, int8 value);
status_t ReplaceInt8(const char *name, int32 index, int8 value);
status_t ReplaceInt16(const char *name, int16 value);
status_t ReplaceInt16(const char *name, int32 index, int16 value);
status_t ReplaceInt32(const char *name, int32 value);
status_t ReplaceInt32(const char *name, int32 index, int32 value);
status_t ReplaceInt64(const char *name, int64 value);
status_t ReplaceInt64(const char *name, int32 index, int64 value);
status_t ReplaceBool(const char *name, bool aBoolean);
status_t ReplaceBool(const char *name, int32 index, bool aBoolean);
status_t ReplaceFloat(const char *name, float aFloat);
status_t ReplaceFloat(const char *name, int32 index, float aFloat);
status_t ReplaceDouble(const char *name, double aDouble);
status_t ReplaceDouble(const char *name, int32 index, double aDouble);
status_t ReplacePointer(const char *name, const void *pointer);
status_t ReplacePointer(const char *name,int32 index,const void *pointer);
status_t ReplaceMessenger(const char *name, BMessenger messenger);
status_t ReplaceMessenger(const char *name, int32 index, BMessenger messenger);
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 *message);
status_t ReplaceMessage(const char *name, int32 index, const BMessage *message);
status_t ReplaceFlat(const char *name, BFlattenable *object);
status_t ReplaceFlat(const char *name, int32 index, BFlattenable *object);
status_t ReplaceData(const char *name, type_code type,
const void *data, ssize_t numBytes);
status_t ReplaceData(const char *name, type_code type, int32 index,
const void *data, ssize_t numBytes);
void *operator new(size_t size);
void *operator new(size_t, void* p);
void operator delete(void *ptr, size_t size);
void *operator new(size_t size);
void *operator new(size_t, void *pointer);
void operator delete(void *pointer, 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;
// 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 n, 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;
struct message_header;
struct field_header;
private:
class Header;
private:
friend class Private;
friend class BMessageQueue;
friend class BMessageQueue;
friend class BMessenger;
friend class BApplication;
friend class Header;
friend class Private;
status_t _InitCommon();
status_t _InitHeader();
status_t _Clear();
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 *);
status_t _ResizeData(int32 offset, int32 change);
// deprecated
BMessage(BMessage *a_message);
virtual void _ReservedMessage1();
virtual void _ReservedMessage2();
virtual void _ReservedMessage3();
uint32 _HashName(const char* name) const;
status_t _FindField(const char* name, type_code type,
field_header** _result) const;
status_t _AddField(const char* name, type_code type,
bool isFixedSize, field_header** _result);
status_t _RemoveField(field_header* field);
void init_data();
status_t flatten_target_info(BDataIO *stream,
ssize_t size,
uchar flags) const;
status_t real_flatten(char *result,
ssize_t size) const;
status_t real_flatten(BDataIO *stream) const;
char *stack_flatten(char *stack_ptr,
ssize_t stack_size,
bool incl_reply,
ssize_t *size = NULL) const;
ssize_t _NativeFlattenedSize() const;
status_t _NativeFlatten(char *buffer, ssize_t size) const;
status_t _NativeFlatten(BDataIO *stream, ssize_t *size = NULL) const;
void _PrintToStream(const char* indent) const;
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;
private:
message_header* fHeader;
field_header* fFields;
uint8* fData;
area_id fClonedArea;
static void _StaticInit();
static void _StaticCleanup();
static void _StaticCacheCleanup();
mutable BMessage* fOriginal;
static BBlockCache *sMsgCache;
BMessage* fQueueLink;
// fQueueLink is used by BMessageQueue to build a linked list
struct dyn_array {
int32 fLogicalBytes;
int32 fPhysicalBytes;
int32 fChunkSize;
int32 fCount;
int32 fEntryHdrSize;
};
// deprecated
BMessage(BMessage *message);
struct entry_hdr : public dyn_array {
entry_hdr *fNext;
uint32 fType;
uchar fNameLength;
char fName[1];
};
static void _StaticCacheCleanup();
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;
static BBlockCache* sMsgCache;
};
//------------------------------------------------------------------------------
#endif // _MESSAGE_H
/*
* $Log $
*
* $Id $
*
*/

View File

@ -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 <bpmagic@columbus.rr.com>
// 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 <BeBuild.h>
#include <OS.h>
#include <Rect.h>
#include <DataIO.h>
#include <Flattenable.h>
#include <AppDefs.h> /* For convenience */
#include <TypeConstants.h> /* 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

View File

@ -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 <bpmagic@columbus.rr.com>
// 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 <BeBuild.h>
#include <OS.h>
#include <Rect.h>
#include <DataIO.h>
#include <Flattenable.h>
#include <AppDefs.h> /* For convenience */
#include <TypeConstants.h> /* 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

View File

@ -0,0 +1,51 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#ifndef _MESSAGE_ADAPTER_H_
#define _MESSAGE_ADAPTER_H_
#include <Message.h>
// message formats
#define MESSAGE_FORMAT_R5 'FOB1'
#define MESSAGE_FORMAT_R5_SWAPPED '1BOF'
#define MESSAGE_FORMAT_DANO 'FOB2'
#define MESSAGE_FORMAT_DANO_SWAPPED '2BOF'
#define MESSAGE_FORMAT_HAIKU '1FMH'
#define MESSAGE_FORMAT_HAIKU_SWAPPED 'HMF1'
namespace BPrivate {
class MessageAdapter {
public:
static ssize_t FlattenedSize(uint32 format, const BMessage *from);
static status_t Flatten(uint32 format, const BMessage *from,
char *buffer, ssize_t *size);
static status_t Flatten(uint32 format, const BMessage *from,
BDataIO *stream, ssize_t *size);
static status_t Unflatten(uint32 format, BMessage *into,
const char *buffer);
static status_t Unflatten(uint32 format, BMessage *into,
BDataIO *stream);
private:
static ssize_t _R5FlattenedSize(const BMessage *from);
static status_t _FlattenR5Message(uint32 format, const BMessage *from,
char *buffer, ssize_t *size);
static status_t _UnflattenR5Message(uint32 format, BMessage *into,
BDataIO *stream);
static status_t _UnflattenDanoMessage(uint32 format, BMessage *into,
BDataIO *stream);
};
} // namespace BPrivate
#endif // _MESSAGE_ADAPTER_H_

View File

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

View File

@ -1,87 +0,0 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
/* BMessageBody handles data storage and retrieval for BMessage. */
#ifndef _MESSAGE_BODY_H_
#define _MESSAGE_BODY_H_
#include <List.h>
#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_

View File

@ -1,103 +0,0 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
/* BMessageBody handles data storage and retrieval for BMessage. */
#ifndef _MESSAGE_BODY_H_
#define _MESSAGE_BODY_H_
#include <List.h>
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_

View File

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

View File

@ -1,96 +0,0 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
/* BMessageField contains the data for indiviual named fields in BMessageBody */
#ifndef _MESSAGE_FIELD_H_
#define _MESSAGE_FIELD_H_
#include <DataIO.h>
#include <List.h>
#include <SupportDefs.h>
#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_

View File

@ -1,120 +0,0 @@
/*
* Copyright 2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
/* BMessageField contains the data for indiviual named fields in BMessageBody */
#ifndef _MESSAGE_FIELD_H_
#define _MESSAGE_FIELD_H_
#include <List.h>
#include <String.h>
#include <SupportDefs.h>
#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_

View File

@ -1,80 +1,189 @@
//------------------------------------------------------------------------------
// MessagePrivate.h
//
//------------------------------------------------------------------------------
#ifndef MESSAGEPRIVATE_H
#define MESSAGEPRIVATE_H
/*
* Copyright 2005-2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <mmlr@mlotz.ch>
*/
#ifndef _MESSAGE_PRIVATE_H_
#define _MESSAGE_PRIVATE_H_
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <TokenSpace.h>
class BMessage::Private
{
#define MESSAGE_BODY_HASH_TABLE_SIZE 10
#define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10
#define MAX_FIELD_PREALLOCATION 50
#define MAX_ITEM_PREALLOCATION B_PAGE_SIZE
static const int32 kPortMessageCode = 'pjpp';
enum {
MESSAGE_FLAG_VALID = 0x0001,
MESSAGE_FLAG_REPLY_REQUIRED = 0x0002,
MESSAGE_FLAG_REPLY_DONE = 0x0004,
MESSAGE_FLAG_IS_REPLY = 0x0008,
MESSAGE_FLAG_WAS_DELIVERED = 0x0010,
MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020,
MESSAGE_FLAG_WAS_DROPPED = 0x0080,
MESSAGE_FLAG_PASS_BY_AREA = 0x0100
};
enum {
FIELD_FLAG_VALID = 0x0001,
FIELD_FLAG_FIXED_SIZE = 0x0002,
};
struct BMessage::field_header {
uint32 flags;
type_code type;
int32 name_length;
int32 count;
ssize_t data_size;
ssize_t allocated;
int32 offset;
int32 next_field;
};
struct BMessage::message_header {
uint32 format;
uint32 what;
uint32 flags;
ssize_t fields_size;
ssize_t data_size;
ssize_t fields_available;
ssize_t data_available;
uint32 fields_checksum;
uint32 data_checksum;
int32 target;
int32 current_specifier;
area_id shared_area;
// reply info
port_id reply_port;
int32 reply_target;
team_id reply_team;
// body info
int32 field_count;
int32 hash_table_size;
int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE];
/* The hash table does contain indexes into the field list and
not direct offsets to the fields. This has the advantage
of not needing to update offsets in two locations.
The hash table must be reevaluated when we remove a field
though.
*/
};
class BMessage::Private {
public:
Private(BMessage* msg) : fMessage(msg) {;}
Private(BMessage& msg) : fMessage(&msg) {;}
inline void SetTarget(int32 token, bool preferred)
Private(BMessage *msg)
: fMessage(msg)
{
fMessage->fTarget = token;
fMessage->fPreferred = preferred;
}
inline void SetReply(BMessenger messenger)
Private(BMessage &msg)
: fMessage(&msg)
{
BMessenger::Private mp(messenger);
fMessage->fReplyTo.port = mp.Port();
fMessage->fReplyTo.target
= (mp.IsPreferredTarget() ? B_PREFERRED_TOKEN : mp.Token());
fMessage->fReplyTo.team = mp.Team();
fMessage->fReplyTo.preferred = mp.IsPreferredTarget();
}
inline int32 GetTarget()
void
SetTarget(int32 token)
{
return fMessage->fTarget;
fMessage->fHeader->target = token;
}
inline bool UsePreferredTarget()
int32
GetTarget()
{
return fMessage->fPreferred;
return fMessage->fHeader->target;
}
static inline status_t SendFlattenedMessage(void *data, int32 size,
port_id port, int32 token, bool preferred, bigtime_t timeout)
bool
UsePreferredTarget()
{
return BMessage::_SendFlattenedMessage(data, size, port, token,
preferred, timeout);
return fMessage->fHeader->target == B_PREFERRED_TOKEN;
}
static inline void StaticInit()
void
SetWasDropped(bool wasDropped)
{
BMessage::_StaticInit();
if (wasDropped)
fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED;
else
fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED;
}
static inline void StaticCleanup()
status_t
Clear()
{
BMessage::_StaticCleanup();
return fMessage->_Clear();
}
static inline void StaticCacheCleanup()
status_t
InitHeader()
{
return fMessage->_InitHeader();
}
BMessage::message_header*
GetMessageHeader()
{
return fMessage->fHeader;
}
BMessage::field_header*
GetMessageFields()
{
return fMessage->fFields;
}
uint8*
GetMessageData()
{
return fMessage->fData;
}
ssize_t
NativeFlattenedSize() const
{
return fMessage->_NativeFlattenedSize();
}
status_t
NativeFlatten(char *buffer, ssize_t size) const
{
return fMessage->_NativeFlatten(buffer, size);
}
status_t
NativeFlatten(BDataIO *stream, ssize_t *size) const
{
return fMessage->_NativeFlatten(stream, size);
}
// static methods
static void
StaticCacheCleanup()
{
BMessage::_StaticCacheCleanup();
}
private:
BMessage* fMessage;
BMessage* fMessage;
};
#endif // MESSAGEPRIVATE_H
/*
* $Log $
*
* $Id $
*
*/
#endif // _MESSAGE_PRIVATE_H_

View File

@ -1,31 +1,12 @@
//------------------------------------------------------------------------------
// MessageUtils.h
//
//------------------------------------------------------------------------------
#ifndef _MESSAGE_UTILS_H_
#define _MESSAGE_UTILS_H_
#ifndef MESSAGEUTILS_H
#define MESSAGEUTILS_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <ByteOrder.h>
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <SupportDefs.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
uint32 _checksum_(const uchar *buf, int32 size);
namespace BPrivate { // Only putting these here because Be did
@ -33,177 +14,150 @@ 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);
uint32 CalculateChecksum(const uint8 *buffer, int32 size);
} // namespace BPrivate
//------------------------------------------------------------------------------
// _set_message_target_
/*! \brief Sets the target of a message.
\param message The message.
\param token The target handler token.
\param preferred Indicates whether to use the looper's preferred handler.
*/
inline
void
_set_message_target_(BMessage *message, int32 token, bool preferred)
{
message->fTarget = token;
message->fPreferred = preferred;
}
//------------------------------------------------------------------------------
// _set_message_reply_
/*! \brief Sets a message's reply target.
\param message The message.
\param messenger The reply messenger.
*/
inline
void
_set_message_reply_(BMessage *message, BMessenger messenger)
{
BMessenger::Private messengerPrivate(messenger);
message->fReplyTo.port = messengerPrivate.Port();
message->fReplyTo.target = messengerPrivate.Token();
message->fReplyTo.team = messengerPrivate.Team();
message->fReplyTo.preferred = messengerPrivate.IsPreferredTarget();
}
//------------------------------------------------------------------------------
inline int32 _get_message_target_(BMessage *msg)
{
return msg->fTarget;
}
//------------------------------------------------------------------------------
inline bool _use_preferred_target_(BMessage *msg)
{
return msg->fPreferred;
}
//------------------------------------------------------------------------------
inline status_t normalize_err(status_t err)
{
return err >= 0 ? B_OK : err;
}
//------------------------------------------------------------------------------
template<class T>
inline void byte_swap(T& /*data*/)
inline void
byte_swap(T &/*data*/)
{
// Specialize for data types which actually swap
}
//------------------------------------------------------------------------------
inline void write_helper(BDataIO* stream, const void* data, size_t size,
status_t& err)
inline void
write_helper(BDataIO *stream, const void *data, size_t size)
{
err = normalize_err(stream->Write(data, size));
status_t error = stream->Write(data, size);
if (error < B_OK)
throw error;
}
//------------------------------------------------------------------------------
// Will the template madness never cease??
template<class T>
inline status_t write_helper(BDataIO* stream, T& data, status_t& err)
{
return normalize_err(stream->Write((const void*)data, sizeof (T)));
}
//------------------------------------------------------------------------------
class TReadHelper
{
public:
TReadHelper(BDataIO* stream)
: fStream(stream), err(B_OK), fSwap(false)
{
;
}
TReadHelper(BDataIO* stream, bool swap)
: fStream(stream), err(B_OK), fSwap(swap)
{
;
}
template<class T> inline void operator()(T& data)
{
err = normalize_err(fStream->Read((void*)&data, sizeof (T)));
if (err)
throw err;
class TReadHelper {
public:
TReadHelper(BDataIO *stream)
: fStream(stream),
fError(B_OK),
fSwap(false)
{
}
if (IsSwapping())
{
byte_swap(data);
}
}
TReadHelper(BDataIO *stream, bool swap)
: fStream(stream),
fError(B_OK),
fSwap(swap)
{
}
template<class T> inline void operator()(T data, size_t len)
{
err = normalize_err(fStream->Read((void*)data, len));
if (err)
throw err;
}
template<class T>
inline void operator()(T &data)
{
fError = fStream->Read((void *)&data, sizeof(T));
if (fError > B_OK) {
if (IsSwapping())
byte_swap(data);
return;
}
status_t Status() { return err; }
void SetSwap(bool yesNo) { fSwap = yesNo; }
bool IsSwapping() { return fSwap; }
if (fError == 0)
fError = B_ERROR;
throw fError;
}
private:
BDataIO* fStream;
status_t err;
bool fSwap;
template<class T>
inline void operator()(T data, size_t len)
{
fError = fStream->Read((void *)data, len);
if (fError >= B_OK)
return;
throw fError;
}
status_t Status() { return fError >= B_OK ? B_OK : fError; };
void SetSwap(bool yesNo) { fSwap = yesNo; };
bool IsSwapping() { return fSwap; };
private:
BDataIO *fStream;
status_t fError;
bool fSwap;
};
//------------------------------------------------------------------------------
class TChecksumHelper
{
public:
TChecksumHelper(uchar* buffer) : fBuffer(buffer), fBufPtr(buffer) {;}
template<class T> inline void Cache(const T& data)
{
*((T*)fBufPtr) = data;
fBufPtr += sizeof (T);
}
int32 CheckSum();
class TChecksumHelper {
public:
TChecksumHelper(uchar* buffer)
: fBuffer(buffer),
fBufPtr(buffer)
{
}
private:
uchar* fBuffer;
uchar* fBufPtr;
template<class T>
inline void Cache(const T &data)
{
*((T*)fBufPtr) = data;
fBufPtr += sizeof (T);
}
int32 CheckSum();
private:
uchar *fBuffer;
uchar *fBufPtr;
};
//------------------------------------------------------------------------------
template<class T> inline status_t read_helper(BDataIO* stream, T& data)
{
return normalize_err(stream->Read((void*)&data, sizeof (T)));
}
//------------------------------------------------------------------------------
template<> inline void byte_swap(double& data)
template<>
inline void
byte_swap(double &data)
{
data = __swap_double(data);
}
template<> inline void byte_swap(float& data)
template<>
inline void
byte_swap(float &data)
{
data = __swap_float(data);
}
template<> inline void byte_swap(int64& data)
template<>
inline void
byte_swap(int64 &data)
{
data = __swap_int64(data);
}
template<> inline void byte_swap(int32& data)
template<>
inline void
byte_swap(int32 &data)
{
data = __swap_int32(data);
}
template<> inline void byte_swap(int16& data)
template<>
inline void
byte_swap(int16 &data)
{
data = __swap_int16(data);
}
template<> inline void byte_swap(entry_ref& data)
template<>
inline void
byte_swap(entry_ref &data)
{
byte_swap(data.device);
byte_swap(data.directory);
}
//------------------------------------------------------------------------------
#endif // MESSAGEUTILS_H
/*
* $Log $
*
* $Id $
*
*/
#endif // _MESSAGE_UTILS_H_

View File

@ -1,222 +0,0 @@
#ifndef MESSAGEUTILS_H
#define MESSAGEUTILS_H
#include <ByteOrder.h>
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <SupportDefs.h>
uint32 _checksum_(const uchar *buf, int32 size);
namespace BPrivate { // Only putting these here because Be did
status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref);
status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size);
status_t entry_ref_swap(char* buffer, size_t size);
size_t calc_padding(size_t size, size_t boundary);
} // namespace BPrivate
//------------------------------------------------------------------------------
// _set_message_target_
/*! \brief Sets the target of a message.
\param message The message.
\param token The target handler token.
\param preferred Indicates whether to use the looper's preferred handler.
*/
inline void
_set_message_target_(BMessage *message, int32 token, bool preferred)
{
message->fTarget = token;
message->fPreferred = preferred;
}
// _set_message_reply_
/*! \brief Sets a message's reply target.
\param message The message.
\param messenger The reply messenger.
*/
inline void
_set_message_reply_(BMessage *message, BMessenger messenger)
{
BMessenger::Private messengerPrivate(messenger);
message->fReplyTo.port = messengerPrivate.Port();
message->fReplyTo.target = messengerPrivate.Token();
message->fReplyTo.team = messengerPrivate.Team();
message->fReplyTo.preferred = messengerPrivate.IsPreferredTarget();
}
inline int32
_get_message_target_(BMessage *msg)
{
return msg->fTarget;
}
inline bool
_use_preferred_target_(BMessage *msg)
{
return msg->fPreferred;
}
inline status_t
normalize_err(status_t err)
{
return err >= 0 ? B_OK : err;
}
template<class T>
inline void
byte_swap(T &/*data*/)
{
// Specialize for data types which actually swap
}
inline void
write_helper(BDataIO *stream, const void *data, size_t size)
{
status_t error = stream->Write(data, size);
if (error < B_OK)
throw error;
}
class TReadHelper {
public:
TReadHelper(BDataIO *stream)
: fStream(stream),
fError(B_OK),
fSwap(false)
{
}
TReadHelper(BDataIO *stream, bool swap)
: fStream(stream),
fError(B_OK),
fSwap(swap)
{
}
template<class T>
inline void operator()(T &data)
{
fError = fStream->Read((void *)&data, sizeof(T));
if (fError < B_OK)
throw fError;
if (IsSwapping())
byte_swap(data);
}
template<class T>
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<class T>
inline void Cache(const T &data)
{
*((T*)fBufPtr) = data;
fBufPtr += sizeof (T);
}
int32 CheckSum();
private:
uchar *fBuffer;
uchar *fBufPtr;
};
template<class T>
inline status_t
read_helper(BDataIO *stream, T &data)
{
return normalize_err(stream->Read((void *)&data, sizeof(T)));
}
template<>
inline void
byte_swap(double &data)
{
data = __swap_double(data);
}
template<>
inline void
byte_swap(float &data)
{
data = __swap_float(data);
}
template<>
inline void
byte_swap(int64 &data)
{
data = __swap_int64(data);
}
template<>
inline void
byte_swap(int32 &data)
{
data = __swap_int32(data);
}
template<>
inline void
byte_swap(int16 &data)
{
data = __swap_int16(data);
}
template<>
inline void
byte_swap(entry_ref &data)
{
byte_swap(data.device);
byte_swap(data.directory);
}
#endif // MESSAGEUTILS_H

View File

@ -1,230 +0,0 @@
#ifndef MESSAGEUTILS_H
#define MESSAGEUTILS_H
#include <ByteOrder.h>
#include <DataIO.h>
#include <Entry.h>
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <SupportDefs.h>
uint32 _checksum_(const uchar *buf, int32 size);
namespace BPrivate { // Only putting these here because Be did
status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref);
status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size);
status_t entry_ref_swap(char* buffer, size_t size);
size_t calc_padding(size_t size, size_t boundary);
} // namespace BPrivate
//------------------------------------------------------------------------------
// _set_message_target_
/*! \brief Sets the target of a message.
\param message The message.
\param token The target handler token.
\param preferred Indicates whether to use the looper's preferred handler.
*/
inline void
_set_message_target_(BMessage *message, int32 token, bool preferred)
{
message->fTarget = token;
message->fPreferred = preferred;
}
// _set_message_reply_
/*! \brief Sets a message's reply target.
\param message The message.
\param messenger The reply messenger.
*/
inline void
_set_message_reply_(BMessage *message, BMessenger messenger)
{
BMessenger::Private messengerPrivate(messenger);
message->fReplyTo.port = messengerPrivate.Port();
message->fReplyTo.target = messengerPrivate.Token();
message->fReplyTo.team = messengerPrivate.Team();
message->fReplyTo.preferred = messengerPrivate.IsPreferredTarget();
}
inline int32
_get_message_target_(BMessage *msg)
{
return msg->fTarget;
}
inline bool
_use_preferred_target_(BMessage *msg)
{
return msg->fPreferred;
}
inline status_t
normalize_err(status_t err)
{
return err >= 0 ? B_OK : err;
}
template<class T>
inline void
byte_swap(T &/*data*/)
{
// Specialize for data types which actually swap
}
inline void
write_helper(BDataIO *stream, const void *data, size_t size)
{
status_t error = stream->Write(data, size);
if (error < B_OK)
throw error;
}
class TReadHelper {
public:
TReadHelper(BDataIO *stream)
: fStream(stream),
fError(B_OK),
fSwap(false)
{
}
TReadHelper(BDataIO *stream, bool swap)
: fStream(stream),
fError(B_OK),
fSwap(swap)
{
}
template<class T>
inline void operator()(T &data)
{
fError = fStream->Read((void *)&data, sizeof(T));
if (fError > B_OK) {
if (IsSwapping())
byte_swap(data);
return;
}
if (fError == 0)
throw B_ERROR;
throw fError;
}
template<class T>
inline void operator()(T data, size_t len)
{
fError = fStream->Read((void *)data, len);
if (fError > B_OK)
return;
if (fError == 0)
throw B_ERROR;
throw fError;
}
status_t Status() { return fError; };
void SetSwap(bool yesNo) { fSwap = yesNo; };
bool IsSwapping() { return fSwap; };
private:
BDataIO *fStream;
status_t fError;
bool fSwap;
};
class TChecksumHelper {
public:
TChecksumHelper(uchar* buffer)
: fBuffer(buffer),
fBufPtr(buffer)
{
}
template<class T>
inline void Cache(const T &data)
{
*((T*)fBufPtr) = data;
fBufPtr += sizeof (T);
}
int32 CheckSum();
private:
uchar *fBuffer;
uchar *fBufPtr;
};
template<class T>
inline status_t
read_helper(BDataIO *stream, T &data)
{
return normalize_err(stream->Read((void *)&data, sizeof(T)));
}
template<>
inline void
byte_swap(double &data)
{
data = __swap_double(data);
}
template<>
inline void
byte_swap(float &data)
{
data = __swap_float(data);
}
template<>
inline void
byte_swap(int64 &data)
{
data = __swap_int64(data);
}
template<>
inline void
byte_swap(int32 &data)
{
data = __swap_int32(data);
}
template<>
inline void
byte_swap(int16 &data)
{
data = __swap_int16(data);
}
template<>
inline void
byte_swap(entry_ref &data)
{
byte_swap(data.device);
byte_swap(data.directory);
}
#endif // MESSAGEUTILS_H

View File

@ -9,8 +9,7 @@ BuildPlatformMergeObjectPIC <libbe_build>app_kit.o :
Application.cpp
AppMisc.cpp
Message.cpp
MessageBody.cpp
MessageField.cpp
MessageAdapter.cpp
Messenger.cpp
MessageUtils.cpp
TypeConstants.cpp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,705 @@
/*
* Copyright 2005-2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
* Michael Lotz <mmlr@mlotz.ch>
*/
#include <MessageAdapter.h>
#include <MessagePrivate.h>
#include <MessageUtils.h>
namespace BPrivate {
#define R5_MESSAGE_FLAG_VALID 0x01
#define R5_MESSAGE_FLAG_INCLUDE_TARGET 0x02
#define R5_MESSAGE_FLAG_INCLUDE_REPLY 0x04
#define R5_MESSAGE_FLAG_SCRIPT_MESSAGE 0x08
#define R5_FIELD_FLAG_VALID 0x01
#define R5_FIELD_FLAG_MINI_DATA 0x02
#define R5_FIELD_FLAG_FIXED_SIZE 0x04
#define R5_FIELD_FLAG_SINGLE_ITEM 0x08
enum {
SECTION_MESSAGE_HEADER = 'FOB2',
SECTION_OFFSET_TABLE = 'STof',
SECTION_TARGET_INFORMATION = 'ENwh',
SECTION_SINGLE_ITEM_DATA = 'SGDa',
SECTION_FIXED_SIZE_ARRAY_DATA = 'FADa',
SECTION_VARIABLE_SIZE_ARRAY_DATA = 'VADa',
SECTION_SORTED_INDEX_TABLE = 'DXIn',
SECTION_END_OF_DATA = 'DDEn'
};
struct r5_message_header {
uint32 magic;
uint32 checksum;
ssize_t flattened_size;
int32 what;
uint8 flags;
} _PACKED;
struct dano_section_header {
uint32 code;
ssize_t size;
uint8 data[0];
} _PACKED;
struct dano_message_header {
int32 what;
int32 padding;
} _PACKED;
typedef struct offset_table_s {
int32 indexTable;
int32 endOfData;
int64 padding;
} OffsetTable;
struct dano_single_item {
type_code type;
ssize_t item_size;
uint8 name_length;
char name[0];
} _PACKED;
struct dano_fixed_size_array {
type_code type;
ssize_t size_per_item;
uint8 name_length;
char name[0];
} _PACKED;
struct dano_variable_size_array {
type_code type;
int32 padding;
uint8 name_length;
char name[0];
} _PACKED;
inline int32
pad_to_8(int32 value)
{
return (value + 7) & ~7;
}
ssize_t
MessageAdapter::FlattenedSize(uint32 format, const BMessage *from)
{
switch (format) {
case MESSAGE_FORMAT_R5:
case MESSAGE_FORMAT_R5_SWAPPED:
return _R5FlattenedSize(from);
}
return -1;
}
status_t
MessageAdapter::Flatten(uint32 format, const BMessage *from, char *buffer,
ssize_t *size)
{
switch (format) {
case MESSAGE_FORMAT_R5:
case MESSAGE_FORMAT_R5_SWAPPED:
return _FlattenR5Message(format, from, buffer, size);
}
return B_ERROR;
}
status_t
MessageAdapter::Flatten(uint32 format, const BMessage *from, BDataIO *stream,
ssize_t *size)
{
switch (format) {
case MESSAGE_FORMAT_R5:
case MESSAGE_FORMAT_R5_SWAPPED:
{
ssize_t flattenedSize = _R5FlattenedSize(from);
char *buffer = (char *)malloc(flattenedSize);
if (!buffer)
return B_NO_MEMORY;
status_t result = _FlattenR5Message(format, from, buffer,
&flattenedSize);
if (result < B_OK) {
free(buffer);
return result;
}
ssize_t written = stream->Write(buffer, flattenedSize);
if (written != flattenedSize) {
free(buffer);
return (written >= 0 ? B_ERROR : written);
}
if (size)
*size = flattenedSize;
free(buffer);
return B_OK;
}
}
return B_ERROR;
}
status_t
MessageAdapter::Unflatten(uint32 format, BMessage *into, const char *buffer)
{
try {
switch (format) {
case MESSAGE_FORMAT_R5:
case MESSAGE_FORMAT_R5_SWAPPED:
{
r5_message_header *header = (r5_message_header *)buffer;
BMemoryIO stream(buffer + sizeof(uint32),
header->flattened_size - sizeof(uint32));
return _UnflattenR5Message(format, into, &stream);
}
case MESSAGE_FORMAT_DANO:
case MESSAGE_FORMAT_DANO_SWAPPED:
{
dano_section_header *header = (dano_section_header *)buffer;
ssize_t size = header->size;
if (header->code == MESSAGE_FORMAT_DANO_SWAPPED)
size = __swap_int32(size);
BMemoryIO stream(buffer + sizeof(uint32), size - sizeof(uint32));
return _UnflattenDanoMessage(format, into, &stream);
}
}
} catch (status_t error) {
into->MakeEmpty();
return error;
}
return B_NOT_A_MESSAGE;
}
status_t
MessageAdapter::Unflatten(uint32 format, BMessage *into, BDataIO *stream)
{
try {
switch (format) {
case MESSAGE_FORMAT_R5:
case MESSAGE_FORMAT_R5_SWAPPED:
return _UnflattenR5Message(format, into, stream);
case MESSAGE_FORMAT_DANO:
case MESSAGE_FORMAT_DANO_SWAPPED:
return _UnflattenDanoMessage(format, into, stream);
}
} catch (status_t error) {
into->MakeEmpty();
return error;
}
return B_NOT_A_MESSAGE;
}
ssize_t
MessageAdapter::_R5FlattenedSize(const BMessage *from)
{
BMessage::Private messagePrivate((BMessage *)from);
BMessage::message_header* header = messagePrivate.GetMessageHeader();
// header size (variable, depending on the flags)
ssize_t flattenedSize = sizeof(r5_message_header);
if (header->target != B_NULL_TOKEN)
flattenedSize += sizeof(int32);
if (header->reply_port >= 0 && header->reply_target != B_NULL_TOKEN
&& header->reply_team >= 0) {
// reply info + big flags
flattenedSize += sizeof(port_id) + sizeof(int32) + sizeof(team_id) + 4;
}
// field size
uint8 *data = messagePrivate.GetMessageData();
BMessage::field_header *field = messagePrivate.GetMessageFields();
for (int32 i = 0; i < header->field_count; i++, field++) {
// flags and type
flattenedSize += 1 + sizeof(type_code);
#if 0
bool miniData = field->dataSize <= 255 && field->count <= 255;
#else
// ToDo: we don't know the R5 dataSize yet (padding)
bool miniData = false;
#endif
// item count
if (field->count > 1)
flattenedSize += (miniData ? sizeof(uint8) : sizeof(uint32));
// data size
flattenedSize += (miniData ? sizeof(uint8) : sizeof(size_t));
// name length and name
flattenedSize += 1 + min_c(field->name_length - 1, 255);
// data
if (field->flags & FIELD_FLAG_FIXED_SIZE)
flattenedSize += field->data_size;
else {
uint8 *source = data + field->offset + field->name_length;
for (int32 i = 0; i < field->count; i++) {
ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
flattenedSize += pad_to_8(itemSize);
source += itemSize;
}
}
}
// pseudo field with flags 0
return flattenedSize + 1;
}
status_t
MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
char *buffer, ssize_t *size)
{
BMessage::Private messagePrivate((BMessage *)from);
BMessage::message_header *header = messagePrivate.GetMessageHeader();
uint8 *data = messagePrivate.GetMessageData();
r5_message_header *r5header = (r5_message_header *)buffer;
uint8 *pointer = (uint8 *)buffer + sizeof(r5_message_header);
r5header->magic = MESSAGE_FORMAT_R5;
r5header->what = from->what;
r5header->checksum = 0;
uint8 flags = R5_MESSAGE_FLAG_VALID;
if (header->target != B_NULL_TOKEN) {
*(int32 *)pointer = header->target;
pointer += sizeof(int32);
flags |= R5_MESSAGE_FLAG_INCLUDE_TARGET;
}
if (header->reply_port >= 0 && header->reply_target != B_NULL_TOKEN
&& header->reply_team >= 0) {
// reply info
*(port_id *)pointer = header->reply_port;
pointer += sizeof(port_id);
*(int32 *)pointer = header->reply_target;
pointer += sizeof(int32);
*(team_id *)pointer = header->reply_team;
pointer += sizeof(team_id);
// big flags
*pointer = (header->reply_target == B_PREFERRED_TOKEN ? 1 : 0);
pointer++;
*pointer = (header->flags & MESSAGE_FLAG_REPLY_REQUIRED ? 1 : 0);
pointer++;
*pointer = (header->flags & MESSAGE_FLAG_REPLY_DONE ? 1 : 0);
pointer++;
*pointer = (header->flags & MESSAGE_FLAG_IS_REPLY ? 1 : 0);
pointer++;
flags |= R5_MESSAGE_FLAG_INCLUDE_REPLY;
}
if (header->flags & MESSAGE_FLAG_HAS_SPECIFIERS)
flags |= R5_MESSAGE_FLAG_SCRIPT_MESSAGE;
r5header->flags = flags;
// store the header size - used for the checksum later
ssize_t headerSize = (uint32)pointer - (uint32)buffer;
// collect and add the data
BMessage::field_header *field = messagePrivate.GetMessageFields();
for (int32 i = 0; i < header->field_count; i++, field++) {
flags = R5_FIELD_FLAG_VALID;
if (field->count == 1)
flags |= R5_FIELD_FLAG_SINGLE_ITEM;
// ToDo: we don't really know the data size now (padding missing)
if (field->data_size <= 255 && field->count <= 255)
;//flags |= R5_FIELD_FLAG_MINI_DATA;
if (field->flags & FIELD_FLAG_FIXED_SIZE)
flags |= R5_FIELD_FLAG_FIXED_SIZE;
*pointer = flags;
pointer++;
*(type_code *)pointer = field->type;
pointer += sizeof(type_code);
if (!(flags & R5_FIELD_FLAG_SINGLE_ITEM)) {
if (flags & R5_FIELD_FLAG_MINI_DATA) {
*pointer = (uint8)field->count;
pointer++;
} else {
*(int32 *)pointer = field->count;
pointer += sizeof(int32);
}
}
// we may have to adjust this to account for padding later
uint8 *fieldSize = pointer;
if (flags & R5_FIELD_FLAG_MINI_DATA) {
*pointer = (uint8)field->data_size;
pointer++;
} else {
*(ssize_t *)pointer = field->data_size;
pointer += sizeof(ssize_t);
}
// name
int32 nameLength = min_c(field->name_length - 1, 255);
*pointer = (uint8)nameLength;
pointer++;
strncpy((char *)pointer, (char *)data + field->offset, nameLength);
pointer += nameLength;
// data
uint8 *source = data + field->offset + field->name_length;
if (flags & R5_FIELD_FLAG_FIXED_SIZE) {
memcpy(pointer, source, field->data_size);
pointer += field->data_size;
} else {
uint8 *previous = pointer;
for (int32 i = 0; i < field->count; i++) {
ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
memcpy(pointer, source, itemSize);
pointer += pad_to_8(itemSize);
source += itemSize;
}
// adjust the field size to the padded value
if (flags & R5_FIELD_FLAG_MINI_DATA)
*fieldSize = (uint8)(pointer - previous);
else
*(ssize_t *)fieldSize = (pointer - previous);
}
}
// terminate the fields with a pseudo field with flags 0 (not valid)
*pointer = 0;
pointer++;
// calculate the flattened size from the pointers
r5header->flattened_size = (uint32)pointer - (uint32)buffer;
r5header->checksum = CalculateChecksum((uint8 *)(buffer + 8),
headerSize - 8);
if (size)
*size = r5header->flattened_size;
return B_OK;
}
status_t
MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into,
BDataIO *stream)
{
into->MakeEmpty();
BMessage::Private messagePrivate(into);
BMessage::message_header *header = messagePrivate.GetMessageHeader();
TReadHelper reader(stream);
if (format == MESSAGE_FORMAT_R5_SWAPPED)
reader.SetSwap(true);
// the stream is already advanced by the size of the "format"
r5_message_header r5header;
reader(((uint8 *)&r5header) + sizeof(uint32),
sizeof(r5header) - sizeof(uint32));
header->what = into->what = r5header.what;
if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_TARGET)
reader(header->target);
if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_REPLY) {
// reply info
reader(header->reply_port);
reader(header->reply_target);
reader(header->reply_team);
// big flags
uint8 bigFlag;
reader(bigFlag);
if (bigFlag)
header->reply_target = B_PREFERRED_TOKEN;
reader(bigFlag);
if (bigFlag)
header->flags |= MESSAGE_FLAG_REPLY_REQUIRED;
reader(bigFlag);
if (bigFlag)
header->flags |= MESSAGE_FLAG_REPLY_DONE;
reader(bigFlag);
if (bigFlag)
header->flags |= MESSAGE_FLAG_IS_REPLY;
}
if (r5header.flags & R5_MESSAGE_FLAG_SCRIPT_MESSAGE)
header->flags |= MESSAGE_FLAG_HAS_SPECIFIERS;
uint8 flags;
reader(flags);
while (flags & R5_FIELD_FLAG_VALID) {
bool fixedSize = flags & R5_FIELD_FLAG_FIXED_SIZE;
bool miniData = flags & R5_FIELD_FLAG_MINI_DATA;
bool singleItem = flags & R5_FIELD_FLAG_SINGLE_ITEM;
type_code type;
reader(type);
int32 itemCount;
if (!singleItem) {
if (miniData) {
uint8 miniCount;
reader(miniCount);
itemCount = miniCount;
} else
reader(itemCount);
} else
itemCount = 1;
ssize_t dataSize;
if (miniData) {
uint8 miniSize;
reader(miniSize);
dataSize = miniSize;
} else
reader(dataSize);
if (dataSize <= 0)
return B_ERROR;
// name
uint8 nameLength;
reader(nameLength);
char nameBuffer[256];
reader(nameBuffer, nameLength);
nameBuffer[nameLength] = '\0';
uint8 *buffer = (uint8 *)malloc(dataSize);
uint8 *pointer = buffer;
reader(buffer, dataSize);
status_t result = B_OK;
ssize_t itemSize = 0;
if (fixedSize)
itemSize = dataSize / itemCount;
for (int32 i = 0; i < itemCount; i++) {
if (!fixedSize) {
itemSize = *(ssize_t *)pointer;
pointer += sizeof(ssize_t);
}
result = into->AddData(nameBuffer, type, pointer, itemSize,
fixedSize, itemCount);
if (result < B_OK) {
free(buffer);
return result;
}
if (fixedSize)
pointer += itemSize;
else
pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t);
}
free(buffer);
// flags of next field or termination byte
reader(flags);
}
return B_OK;
}
status_t
MessageAdapter::_UnflattenDanoMessage(uint32 format, BMessage *into,
BDataIO *stream)
{
into->MakeEmpty();
TReadHelper reader(stream);
if (format == MESSAGE_FORMAT_DANO_SWAPPED)
reader.SetSwap(true);
ssize_t size;
reader(size);
dano_message_header header;
reader(header);
into->what = header.what;
size -= sizeof(dano_section_header) + sizeof(dano_message_header);
int32 offset = 0;
while (offset < size) {
dano_section_header sectionHeader;
reader(sectionHeader);
// be safe. this shouldn't be necessary but in some testcases it was.
sectionHeader.size = pad_to_8(sectionHeader.size);
if (offset + sectionHeader.size > size || sectionHeader.size < 0)
return B_BAD_DATA;
ssize_t fieldSize = sectionHeader.size - sizeof(dano_section_header);
uint8 *fieldBuffer = NULL;
if (fieldSize > 0) {
// there may be no data. we shouldn't fail because of that
fieldBuffer = (uint8 *)malloc(fieldSize);
if (fieldBuffer == NULL)
throw (status_t)B_NO_MEMORY;
reader(fieldBuffer, fieldSize);
}
switch (sectionHeader.code) {
case SECTION_OFFSET_TABLE:
case SECTION_TARGET_INFORMATION:
case SECTION_SORTED_INDEX_TABLE:
case SECTION_END_OF_DATA:
// discard
break;
case SECTION_SINGLE_ITEM_DATA: {
dano_single_item *field = (dano_single_item *)fieldBuffer;
int32 dataOffset = sizeof(dano_single_item)
+ field->name_length + 1;
dataOffset = pad_to_8(dataOffset);
if (offset + dataOffset + field->item_size > size)
return B_BAD_DATA;
// support for fixed size is not possible with a single item
bool fixedSize = false;
switch (field->type) {
case B_RECT_TYPE:
case B_POINT_TYPE:
case B_INT8_TYPE:
case B_INT16_TYPE:
case B_INT32_TYPE:
case B_INT64_TYPE:
case B_BOOL_TYPE:
case B_FLOAT_TYPE:
case B_DOUBLE_TYPE:
case B_POINTER_TYPE:
case B_MESSENGER_TYPE:
fixedSize = true;
break;
default:
break;
}
status_t result = into->AddData(field->name, field->type,
fieldBuffer + dataOffset, field->item_size, fixedSize);
if (result < B_OK) {
free(fieldBuffer);
throw result;
}
break;
}
case SECTION_FIXED_SIZE_ARRAY_DATA: {
dano_fixed_size_array *field
= (dano_fixed_size_array *)fieldBuffer;
int32 dataOffset = sizeof(dano_fixed_size_array)
+ field->name_length + 1;
dataOffset = pad_to_8(dataOffset);
int32 count = *(int32 *)(fieldBuffer + dataOffset);
dataOffset += 8; /* count and padding */
if (offset + dataOffset + count * field->size_per_item > size)
return B_BAD_DATA;
status_t result = B_OK;
for (int32 i = 0; i < count; i++) {
result = into->AddData(field->name, field->type,
fieldBuffer + dataOffset, field->size_per_item, true,
count);
if (result < B_OK) {
free(fieldBuffer);
throw result;
}
dataOffset += field->size_per_item;
}
break;
}
case SECTION_VARIABLE_SIZE_ARRAY_DATA: {
dano_variable_size_array *field
= (dano_variable_size_array *)fieldBuffer;
int32 dataOffset = sizeof(dano_variable_size_array)
+ field->name_length + 1;
dataOffset = pad_to_8(dataOffset);
int32 count = *(int32 *)(fieldBuffer + dataOffset);
dataOffset += sizeof(int32);
ssize_t totalSize = *(ssize_t *)(fieldBuffer + dataOffset);
dataOffset += sizeof(ssize_t);
int32 *endPoints = (int32 *)(fieldBuffer + dataOffset
+ totalSize);
status_t result = B_OK;
for (int32 i = 0; i < count; i++) {
int32 itemOffset = (i > 0 ? pad_to_8(endPoints[i - 1]) : 0);
result = into->AddData(field->name, field->type,
fieldBuffer + dataOffset + itemOffset,
endPoints[i] - itemOffset, false, count);
if (result < B_OK) {
free(fieldBuffer);
throw result;
}
}
break;
}
}
free(fieldBuffer);
offset += sectionHeader.size;
}
return B_OK;
}
} // namespace BPrivate

View File

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

View File

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

View File

@ -13,26 +13,26 @@
#include <MessageUtils.h>
namespace BPrivate {
uint32
_checksum_(const uchar* buf, int32 size)
CalculateChecksum(const uint8 *buffer, int32 size)
{
uint32 sum = 0;
uint32 temp = 0;
while (size > 3) {
#if defined(__INTEL__)
sum += B_SWAP_INT32(*(int*)buf);
sum += B_SWAP_INT32(*(int32 *)buffer);
#else
sum += *(int*)buf;
sum += *(int32 *)buffer;
#endif
buf += 4;
buffer += 4;
size -= 4;
}
while (size > 0) {
temp = (temp << 8) + *buf++;
temp = (temp << 8) + *buffer++;
size -= 1;
}
@ -40,43 +40,41 @@ _checksum_(const uchar* buf, int32 size)
}
namespace BPrivate { // Only putting these here because Be did
/* entry_ref support functions */
status_t
entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref)
entry_ref_flatten(char *buffer, size_t *size, const entry_ref *ref)
{
memcpy((void*)buffer, (const void*)&ref->device, sizeof (ref->device));
buffer += sizeof (ref->device);
memcpy((void*)buffer, (const void*)&ref->directory, sizeof (ref->directory));
memcpy((void *)buffer, (const void *)&ref->device, sizeof(ref->device));
buffer += sizeof(ref->device);
memcpy((void *)buffer, (const void *)&ref->directory, sizeof(ref->directory));
buffer += sizeof (ref->directory);
size_t len = 0;
size_t nameLength = 0;
if (ref->name) {
len = strlen(ref->name) + 1; // extra for NULL terminator
memcpy((void*)buffer, (const void*)ref->name, len);
nameLength = strlen(ref->name) + 1;
memcpy((void *)buffer, (const void *)ref->name, nameLength);
}
*size = sizeof (ref->device) + sizeof (ref->directory) + len;
*size = sizeof(ref->device) + sizeof(ref->directory) + nameLength;
return B_OK;
}
status_t
entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size)
entry_ref_unflatten(entry_ref *ref, const char *buffer, size_t size)
{
if (size < (sizeof (ref->device) + sizeof (ref->directory))) {
if (size < sizeof(ref->device) + sizeof(ref->directory)) {
*ref = entry_ref();
return B_BAD_VALUE;
}
memcpy((void*)&ref->device, (const void*)buffer, sizeof (ref->device));
memcpy((void *)&ref->device, (const void *)buffer, sizeof(ref->device));
buffer += sizeof (ref->device);
memcpy((void*)&ref->directory, (const void*)buffer,
sizeof (ref->directory));
buffer += sizeof (ref->directory);
memcpy((void *)&ref->directory, (const void *)buffer, sizeof(ref->directory));
buffer += sizeof(ref->directory);
if (ref->device != -1
&& size > (sizeof (ref->device) + sizeof (ref->directory))) {
if (ref->device != -1 && size > sizeof(ref->device)
+ sizeof(ref->directory)) {
ref->set_name(buffer);
if (ref->name == NULL) {
*ref = entry_ref();
@ -90,41 +88,19 @@ entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size)
status_t
entry_ref_swap(char* buffer, size_t size)
entry_ref_swap(char *buffer, size_t size)
{
if (size < (sizeof (dev_t) + sizeof (ino_t)))
return B_BAD_DATA;
if (size < sizeof(dev_t) + sizeof(ino_t))
return B_BAD_VALUE;
dev_t* dev = (dev_t*)buffer;
dev_t *dev = (dev_t *)buffer;
*dev = B_SWAP_INT32(*dev);
buffer += sizeof (dev_t);
buffer += sizeof(dev_t);
ino_t* ino = (ino_t*)buffer;
ino_t *ino = (ino_t *)buffer;
*ino = B_SWAP_INT64(*ino);
return B_OK;
}
size_t
calc_padding(size_t size, size_t boundary)
{
size_t pad = size % boundary;
if (pad)
pad = boundary - pad;
return pad;
}
} // namespace BPrivate
// #pragma mark -
int32
TChecksumHelper::CheckSum()
{
return _checksum_(fBuffer, fBufPtr - fBuffer);
}
} // namespace BPrivate

View File

@ -41,6 +41,7 @@
#include <LooperList.h>
#include <Message.h>
#include <Messenger.h>
#include <MessengerPrivate.h>
#include <OS.h>
#include <Roster.h>
#include <TokenSpace.h>