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