1 /* 2 * Copyright 2005-2009, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 */ 8 #ifndef _MESSAGE_PRIVATE_H_ 9 #define _MESSAGE_PRIVATE_H_ 10 11 #include <Message.h> 12 #include <Messenger.h> 13 #include <MessengerPrivate.h> 14 #include <TokenSpace.h> 15 16 17 #define MESSAGE_BODY_HASH_TABLE_SIZE 5 18 #define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10 19 #define MAX_FIELD_PREALLOCATION 50 20 21 22 static const int32 kPortMessageCode = 'pjpp'; 23 24 25 enum { 26 MESSAGE_FLAG_VALID = 0x0001, 27 MESSAGE_FLAG_REPLY_REQUIRED = 0x0002, 28 MESSAGE_FLAG_REPLY_DONE = 0x0004, 29 MESSAGE_FLAG_IS_REPLY = 0x0008, 30 MESSAGE_FLAG_WAS_DELIVERED = 0x0010, 31 MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020, 32 MESSAGE_FLAG_WAS_DROPPED = 0x0040, 33 MESSAGE_FLAG_PASS_BY_AREA = 0x0080 34 }; 35 36 37 enum { 38 FIELD_FLAG_VALID = 0x0001, 39 FIELD_FLAG_FIXED_SIZE = 0x0002, 40 }; 41 42 43 struct BMessage::field_header { 44 uint16 flags; 45 uint16 name_length; 46 type_code type; 47 uint32 count; 48 uint32 data_size; 49 uint32 offset; 50 int32 next_field; 51 } _PACKED; 52 53 54 struct BMessage::message_header { 55 uint32 format; 56 uint32 what; 57 uint32 flags; 58 59 int32 target; 60 int32 current_specifier; 61 area_id message_area; 62 63 // reply info 64 port_id reply_port; 65 int32 reply_target; 66 team_id reply_team; 67 68 // body info 69 uint32 data_size; 70 uint32 field_count; 71 uint32 hash_table_size; 72 int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE]; 73 74 /* The hash table does contain indexes into the field list and 75 not direct offsets to the fields. This has the advantage 76 of not needing to update offsets in two locations. 77 The hash table must be reevaluated when we remove a field 78 though. 79 */ 80 } _PACKED; 81 82 83 class BMessage::Private { 84 public: 85 Private(BMessage *msg) 86 : 87 fMessage(msg) 88 { 89 } 90 91 Private(BMessage &msg) 92 : 93 fMessage(&msg) 94 { 95 } 96 97 void 98 SetTarget(int32 token) 99 { 100 fMessage->fHeader->target = token; 101 } 102 103 void 104 SetReply(BMessenger messenger) 105 { 106 BMessenger::Private messengerPrivate(messenger); 107 fMessage->fHeader->reply_port = messengerPrivate.Port(); 108 fMessage->fHeader->reply_target = messengerPrivate.Token(); 109 fMessage->fHeader->reply_team = messengerPrivate.Team(); 110 } 111 112 void 113 SetReply(team_id team, port_id port, int32 target) 114 { 115 fMessage->fHeader->reply_port = port; 116 fMessage->fHeader->reply_target = target; 117 fMessage->fHeader->reply_team = team; 118 } 119 120 int32 121 GetTarget() 122 { 123 return fMessage->fHeader->target; 124 } 125 126 bool 127 UsePreferredTarget() 128 { 129 return fMessage->fHeader->target == B_PREFERRED_TOKEN; 130 } 131 132 void 133 SetWasDropped(bool wasDropped) 134 { 135 if (wasDropped) 136 fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED; 137 else 138 fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED; 139 } 140 141 status_t 142 Clear() 143 { 144 return fMessage->_Clear(); 145 } 146 147 status_t 148 InitHeader() 149 { 150 return fMessage->_InitHeader(); 151 } 152 153 BMessage::message_header* 154 GetMessageHeader() 155 { 156 return fMessage->fHeader; 157 } 158 159 BMessage::field_header* 160 GetMessageFields() 161 { 162 return fMessage->fFields; 163 } 164 165 uint8* 166 GetMessageData() 167 { 168 return fMessage->fData; 169 } 170 171 private: 172 BMessage* fMessage; 173 }; 174 175 #endif // _MESSAGE_PRIVATE_H_ 176