* 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:
parent
5dc45eb4fe
commit
da0f338e87
@ -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 $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -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
|
@ -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
|
51
headers/build/private/app/MessageAdapter.h
Normal file
51
headers/build/private/app/MessageAdapter.h
Normal 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_
|
@ -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 $
|
||||
*
|
||||
*/
|
||||
|
@ -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_
|
@ -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_
|
@ -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 $
|
||||
*
|
||||
*/
|
||||
|
@ -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_
|
@ -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_
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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
|
@ -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
|
@ -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
705
src/build/libbe/app/MessageAdapter.cpp
Normal file
705
src/build/libbe/app/MessageAdapter.cpp
Normal 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
|
@ -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 $
|
||||
*
|
||||
*/
|
||||
|
@ -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 $
|
||||
*
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user