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