1 /* 2 * Copyright 2001-2005, Haiku Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Erik Jaesler (erik@cgsoftware.com) 7 * DarkWyrm <bpmagic@columbus.rr.com> 8 */ 9 #ifndef _MESSAGE_H 10 #define _MESSAGE_H 11 12 #include <DataIO.h> 13 #include <Flattenable.h> 14 #include <Messenger.h> 15 #include <OS.h> 16 #include <Rect.h> 17 18 // for convenience 19 #include <AppDefs.h> 20 #include <TypeConstants.h> 21 22 23 class BBlockCache; 24 class BMessenger; 25 class BHandler; 26 class BString; 27 struct entry_ref; 28 29 // Private or reserved --------------------------------------------------------- 30 extern "C" void _msg_cache_cleanup_(); 31 extern "C" int _init_message_(); 32 extern "C" int _delete_message_(); 33 34 35 // Name lengths and Scripting specifiers --------------------------------------- 36 #define B_FIELD_NAME_LENGTH 255 37 #define B_PROPERTY_NAME_LENGTH 255 38 39 enum { 40 B_NO_SPECIFIER = 0, 41 B_DIRECT_SPECIFIER, 42 B_INDEX_SPECIFIER, 43 B_REVERSE_INDEX_SPECIFIER, 44 B_RANGE_SPECIFIER, 45 B_REVERSE_RANGE_SPECIFIER, 46 B_NAME_SPECIFIER, 47 B_ID_SPECIFIER, 48 49 B_SPECIFIERS_END = 128 50 // app-defined specifiers start at B_SPECIFIERS_END+1 51 }; 52 53 namespace BPrivate { 54 class BMessageBody; 55 } 56 57 // BMessage class -------------------------------------------------------------- 58 class BMessage { 59 public: 60 uint32 what; 61 62 BMessage(); 63 BMessage(uint32 what); 64 BMessage(const BMessage &a_message); 65 virtual ~BMessage(); 66 67 BMessage &operator=(const BMessage &msg); 68 69 // Statistics and misc info 70 status_t GetInfo(type_code typeRequested, int32 which, char **name, 71 type_code *typeReturned, int32 *count = NULL) const; 72 73 status_t GetInfo(const char *name, type_code *type, int32 *c = 0) const; 74 status_t GetInfo(const char *name, type_code *type, bool *fixed_size) const; 75 76 int32 CountNames(type_code type) const; 77 bool IsEmpty() const; 78 bool IsSystem() const; 79 bool IsReply() const; 80 void PrintToStream() const; 81 82 status_t Rename(const char *old_entry, const char *new_entry); 83 84 // Delivery info 85 bool WasDelivered() const; 86 bool IsSourceWaiting() const; 87 bool IsSourceRemote() const; 88 BMessenger ReturnAddress() const; 89 const BMessage *Previous() const; 90 bool WasDropped() const; 91 BPoint DropPoint(BPoint *offset = NULL) const; 92 93 // Replying 94 status_t SendReply(uint32 command, BHandler *reply_to = NULL); 95 status_t SendReply(BMessage *the_reply, BHandler *reply_to = NULL, 96 bigtime_t timeout = B_INFINITE_TIMEOUT); 97 status_t SendReply(BMessage *the_reply, BMessenger reply_to, 98 bigtime_t timeout = B_INFINITE_TIMEOUT); 99 100 status_t SendReply(uint32 command, BMessage *reply_to_reply); 101 status_t SendReply(BMessage *the_reply, BMessage *reply_to_reply, 102 bigtime_t send_timeout = B_INFINITE_TIMEOUT, 103 bigtime_t reply_timeout = B_INFINITE_TIMEOUT); 104 105 // Flattening data 106 ssize_t FlattenedSize() const; 107 status_t Flatten(char *buffer, ssize_t size) const; 108 status_t Flatten(BDataIO *stream, ssize_t *size = NULL) const; 109 status_t Unflatten(const char *flat_buffer); 110 status_t Unflatten(BDataIO *stream); 111 112 113 // Specifiers (scripting) 114 status_t AddSpecifier(const char *property); 115 status_t AddSpecifier(const char *property, int32 index); 116 status_t AddSpecifier(const char *property, int32 index, int32 range); 117 status_t AddSpecifier(const char *property, const char *name); 118 status_t AddSpecifier(const BMessage *specifier); 119 120 status_t SetCurrentSpecifier(int32 index); 121 status_t GetCurrentSpecifier(int32 *index, BMessage *specifier = NULL, 122 int32 *form = NULL, const char **property = NULL) const; 123 bool HasSpecifiers() const; 124 status_t PopSpecifier(); 125 126 // Adding data 127 status_t AddRect(const char *name, BRect a_rect); 128 status_t AddPoint(const char *name, BPoint a_point); 129 status_t AddString(const char *name, const char *a_string); 130 status_t AddString(const char *name, const BString& a_string); 131 status_t AddInt8(const char *name, int8 val); 132 status_t AddInt16(const char *name, int16 val); 133 status_t AddInt32(const char *name, int32 val); 134 status_t AddInt64(const char *name, int64 val); 135 status_t AddBool(const char *name, bool a_boolean); 136 status_t AddFloat(const char *name, float a_float); 137 status_t AddDouble(const char *name, double a_double); 138 status_t AddPointer(const char *name, const void *ptr); 139 status_t AddMessenger(const char *name, BMessenger messenger); 140 status_t AddRef(const char *name, const entry_ref *ref); 141 status_t AddMessage(const char *name, const BMessage *msg); 142 status_t AddFlat(const char *name, BFlattenable *obj, int32 count = 1); 143 status_t AddData(const char *name, type_code type, const void *data, 144 ssize_t numBytes, bool is_fixed_size = true, int32 count = 1); 145 146 // Removing data 147 status_t RemoveData(const char *name, int32 index = 0); 148 status_t RemoveName(const char *name); 149 status_t MakeEmpty(); 150 151 // Finding data 152 status_t FindRect(const char *name, BRect *rect) const; 153 status_t FindRect(const char *name, int32 index, BRect *rect) const; 154 status_t FindPoint(const char *name, BPoint *pt) const; 155 status_t FindPoint(const char *name, int32 index, BPoint *pt) const; 156 status_t FindString(const char *name, const char **str) const; 157 status_t FindString(const char *name, int32 index, const char **str) const; 158 status_t FindString(const char *name, BString *str) const; 159 status_t FindString(const char *name, int32 index, BString *str) const; 160 status_t FindInt8(const char *name, int8 *value) const; 161 status_t FindInt8(const char *name, int32 index, int8 *val) const; 162 status_t FindInt16(const char *name, int16 *value) const; 163 status_t FindInt16(const char *name, int32 index, int16 *val) const; 164 status_t FindInt32(const char *name, int32 *value) const; 165 status_t FindInt32(const char *name, int32 index, int32 *val) const; 166 status_t FindInt64(const char *name, int64 *value) const; 167 status_t FindInt64(const char *name, int32 index, int64 *val) const; 168 status_t FindBool(const char *name, bool *value) const; 169 status_t FindBool(const char *name, int32 index, bool *value) const; 170 status_t FindFloat(const char *name, float *f) const; 171 status_t FindFloat(const char *name, int32 index, float *f) const; 172 status_t FindDouble(const char *name, double *d) const; 173 status_t FindDouble(const char *name, int32 index, double *d) const; 174 status_t FindPointer(const char *name, void **ptr) const; 175 status_t FindPointer(const char *name, int32 index, void **ptr) const; 176 status_t FindMessenger(const char *name, BMessenger *m) const; 177 status_t FindMessenger(const char *name, int32 index, BMessenger *m) const; 178 status_t FindRef(const char *name, entry_ref *ref) const; 179 status_t FindRef(const char *name, int32 index, entry_ref *ref) const; 180 status_t FindMessage(const char *name, BMessage *msg) const; 181 status_t FindMessage(const char *name, int32 index, BMessage *msg) const; 182 status_t FindFlat(const char *name, BFlattenable *obj) const; 183 status_t FindFlat(const char *name, int32 index, BFlattenable *obj) const; 184 status_t FindData(const char *name, type_code type, 185 const void **data, ssize_t *numBytes) const; 186 status_t FindData(const char *name, type_code type, int32 index, 187 const void **data, ssize_t *numBytes) const; 188 189 // Replacing data 190 status_t ReplaceRect(const char *name, BRect a_rect); 191 status_t ReplaceRect(const char *name, int32 index, BRect a_rect); 192 status_t ReplacePoint(const char *name, BPoint a_point); 193 status_t ReplacePoint(const char *name, int32 index, BPoint a_point); 194 status_t ReplaceString(const char *name, const char *string); 195 status_t ReplaceString(const char *name, int32 index, const char *string); 196 status_t ReplaceString(const char *name, const BString& string); 197 status_t ReplaceString(const char *name, int32 index, const BString& string); 198 status_t ReplaceInt8(const char *name, int8 val); 199 status_t ReplaceInt8(const char *name, int32 index, int8 val); 200 status_t ReplaceInt16(const char *name, int16 val); 201 status_t ReplaceInt16(const char *name, int32 index, int16 val); 202 status_t ReplaceInt32(const char *name, int32 val); 203 status_t ReplaceInt32(const char *name, int32 index, int32 val); 204 status_t ReplaceInt64(const char *name, int64 val); 205 status_t ReplaceInt64(const char *name, int32 index, int64 val); 206 status_t ReplaceBool(const char *name, bool a_bool); 207 status_t ReplaceBool(const char *name, int32 index, bool a_bool); 208 status_t ReplaceFloat(const char *name, float a_float); 209 status_t ReplaceFloat(const char *name, int32 index, float a_float); 210 status_t ReplaceDouble(const char *name, double a_double); 211 status_t ReplaceDouble(const char *name, int32 index, double a_double); 212 status_t ReplacePointer(const char *name, const void *ptr); 213 status_t ReplacePointer(const char *name,int32 index,const void *ptr); 214 status_t ReplaceMessenger(const char *name, BMessenger messenger); 215 status_t ReplaceMessenger(const char *name, int32 index, BMessenger msngr); 216 status_t ReplaceRef( const char *name,const entry_ref *ref); 217 status_t ReplaceRef( const char *name, int32 index, const entry_ref *ref); 218 status_t ReplaceMessage(const char *name, const BMessage *msg); 219 status_t ReplaceMessage(const char *name, int32 index, const BMessage *msg); 220 status_t ReplaceFlat(const char *name, BFlattenable *obj); 221 status_t ReplaceFlat(const char *name, int32 index, BFlattenable *obj); 222 status_t ReplaceData(const char *name, type_code type, 223 const void *data, ssize_t data_size); 224 status_t ReplaceData(const char *name, type_code type, int32 index, 225 const void *data, ssize_t data_size); 226 227 void *operator new(size_t size); 228 void *operator new(size_t, void* p); 229 void operator delete(void *ptr, size_t size); 230 231 // Private, reserved, or obsolete ---------------------------------------------- 232 bool HasRect(const char *, int32 n = 0) const; 233 bool HasPoint(const char *, int32 n = 0) const; 234 bool HasString(const char *, int32 n = 0) const; 235 bool HasInt8(const char *, int32 n = 0) const; 236 bool HasInt16(const char *, int32 n = 0) const; 237 bool HasInt32(const char *, int32 n = 0) const; 238 bool HasInt64(const char *, int32 n = 0) const; 239 bool HasBool(const char *, int32 n = 0) const; 240 bool HasFloat(const char *, int32 n = 0) const; 241 bool HasDouble(const char *, int32 n = 0) const; 242 bool HasPointer(const char *, int32 n = 0) const; 243 bool HasMessenger(const char *, int32 n = 0) const; 244 bool HasRef(const char *, int32 n = 0) const; 245 bool HasMessage(const char *, int32 n = 0) const; 246 bool HasFlat(const char *, const BFlattenable *) const; 247 bool HasFlat(const char *,int32 ,const BFlattenable *) const; 248 bool HasData(const char *, type_code , int32 n = 0) const; 249 BRect FindRect(const char *, int32 n = 0) const; 250 BPoint FindPoint(const char *, int32 n = 0) const; 251 const char *FindString(const char *, int32 n = 0) const; 252 int8 FindInt8(const char *, int32 n = 0) const; 253 int16 FindInt16(const char *, int32 n = 0) const; 254 int32 FindInt32(const char *, int32 n = 0) const; 255 int64 FindInt64(const char *, int32 n = 0) const; 256 bool FindBool(const char *, int32 n = 0) const; 257 float FindFloat(const char *, int32 n = 0) const; 258 double FindDouble(const char *, int32 n = 0) const; 259 260 class Private; 261 262 private: 263 class Header; 264 265 friend class BMessageQueue; 266 friend class BMessenger; 267 friend class BApplication; 268 friend class Header; 269 friend class Private; 270 271 friend inline void _set_message_target_(BMessage *, int32, bool); 272 friend inline void _set_message_reply_(BMessage *, BMessenger); 273 friend inline int32 _get_message_target_(BMessage *); 274 friend inline bool _use_preferred_target_(BMessage *); 275 276 // deprecated 277 BMessage(BMessage *a_message); 278 279 virtual void _ReservedMessage1(); 280 virtual void _ReservedMessage2(); 281 virtual void _ReservedMessage3(); 282 283 void init_data(); 284 status_t flatten_target_info(BDataIO *stream, 285 ssize_t size, 286 uchar flags) const; 287 status_t real_flatten(char *result, 288 ssize_t size) const; 289 status_t real_flatten(BDataIO *stream) const; 290 char *stack_flatten(char *stack_ptr, 291 ssize_t stack_size, 292 bool incl_reply, 293 ssize_t *size = NULL) const; 294 295 status_t _UnflattenKMessage(const char *buffer); 296 297 ssize_t calc_size(uchar flags) const; 298 ssize_t calc_hdr_size(uchar flags) const; 299 status_t nfind_data( const char *name, 300 type_code type, 301 int32 index, 302 const void **data, 303 ssize_t *data_size) const; 304 status_t copy_data( const char *name, 305 type_code type, 306 int32 index, 307 void *data, 308 ssize_t data_size) const; 309 310 status_t _send_(port_id port, 311 int32 token, 312 bool preferred, 313 bigtime_t timeout, 314 bool reply_required, 315 BMessenger &reply_to) const; 316 status_t send_message(port_id port, 317 team_id port_owner, 318 int32 token, 319 bool preferred, 320 BMessage *reply, 321 bigtime_t send_timeout, 322 bigtime_t reply_timeout) const; 323 static status_t _SendFlattenedMessage(void *data, int32 size, 324 port_id port, int32 token, bool preferred, 325 bigtime_t timeout); 326 327 static void _StaticInit(); 328 static void _StaticCleanup(); 329 static void _StaticCacheCleanup(); 330 331 enum { sNumReplyPorts = 3 }; 332 static port_id sReplyPorts[sNumReplyPorts]; 333 static long sReplyPortInUse[sNumReplyPorts]; 334 static int32 sGetCachedReplyPort(); 335 336 static BBlockCache *sMsgCache; 337 338 struct dyn_array { 339 int32 fLogicalBytes; 340 int32 fPhysicalBytes; 341 int32 fChunkSize; 342 int32 fCount; 343 int32 fEntryHdrSize; 344 }; 345 346 struct entry_hdr : public dyn_array { 347 entry_hdr *fNext; 348 uint32 fType; 349 uchar fNameLength; 350 char fName[1]; 351 }; 352 353 struct var_chunk { 354 int32 fDataSize; 355 char fData[1]; 356 }; 357 358 entry_hdr *entry_find(const char *name, uint32 type,status_t *result=NULL) const; 359 void entry_remove(entry_hdr *entry); 360 361 void *da_create(int32 header_size, int32 chunk_size, 362 bool fixed, int32 nchunks); 363 status_t da_add_data(dyn_array **da, const void *data, int32 size); 364 void *da_find_data(dyn_array *da, int32 index, 365 int32 *size = NULL) const; 366 status_t da_delete_data(dyn_array **pda, int32 index); 367 status_t da_replace_data(dyn_array **pda, int32 index, 368 const void *data, int32 dsize); 369 int32 da_calc_size(int32 hdr_size, int32 chunksize, 370 bool is_fixed, int32 nchunks) const; 371 void *da_grow(dyn_array **pda, int32 increase); 372 void da_dump(dyn_array *da); 373 374 int32 da_chunk_hdr_size() const 375 { return sizeof(int32); } 376 int32 da_chunk_size(var_chunk *v) const 377 { return (v->fDataSize + da_chunk_hdr_size() + 7) & ~7; } 378 var_chunk *da_first_chunk(dyn_array *da) const 379 { return (var_chunk *) da_start_of_data(da); } 380 var_chunk *da_next_chunk(var_chunk *v) const 381 { return (var_chunk *) (((char*) v) + da_chunk_size(v)); } 382 var_chunk *da_chunk_ptr(void *data) const 383 { return (var_chunk*) (((char *) data) - da_chunk_hdr_size()); } 384 385 int32 da_pad_8(int32 val) const 386 { return (val + 7) & ~7; } 387 int32 da_total_size(dyn_array *da) const 388 { return (int32)sizeof(dyn_array) + da->fEntryHdrSize + 389 da->fPhysicalBytes; } 390 int32 da_total_logical_size(dyn_array *da) const 391 { return (int32)sizeof(dyn_array) + da->fEntryHdrSize + 392 da->fLogicalBytes; } 393 char *da_start_of_data(dyn_array *da) const 394 { return ((char *) da) + (sizeof(dyn_array) + 395 da->fEntryHdrSize); } 396 bool da_is_mini_data(dyn_array *da) const 397 { return ((da->fLogicalBytes <= (int32) UCHAR_MAX) && 398 (da->fCount <= (int32) UCHAR_MAX));} 399 void da_swap_var_sized(dyn_array *da); 400 void da_swap_fixed_sized(dyn_array *da); 401 402 BMessage *fQueueLink; 403 int32 fTarget; 404 BMessage *fOriginal; 405 uint32 fChangeCount; 406 int32 fCurSpecifier; 407 uint32 fPtrOffset; 408 409 // ejaesler: Stealing one for my whacky BMessageBody l33tness 410 uint32 _reserved[2]; 411 BPrivate::BMessageBody* fBody; 412 413 BMessage::entry_hdr *fEntries; 414 415 struct reply_to_info { 416 port_id port; 417 int32 target; 418 team_id team; 419 bool preferred; 420 } fReplyTo; 421 422 bool fPreferred; 423 bool fReplyRequired; 424 bool fReplyDone; 425 bool fIsReply; 426 bool fWasDelivered; 427 bool fReadOnly; 428 bool fHasSpecifiers; 429 }; 430 431 #endif // _MESSAGE_H 432