1 /* 2 * Copyright 2005-2015, 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 12 #include <Message.h> 13 #include <Messenger.h> 14 #include <MessengerPrivate.h> 15 #include <TokenSpace.h> 16 17 18 #define MESSAGE_BODY_HASH_TABLE_SIZE 5 19 #define MAX_DATA_PREALLOCATION B_PAGE_SIZE * 10 20 #define MAX_FIELD_PREALLOCATION 50 21 22 23 static const int32 kPortMessageCode = 'pjpp'; 24 25 26 enum { 27 MESSAGE_FLAG_VALID = 0x0001, 28 MESSAGE_FLAG_REPLY_REQUIRED = 0x0002, 29 MESSAGE_FLAG_REPLY_DONE = 0x0004, 30 MESSAGE_FLAG_IS_REPLY = 0x0008, 31 MESSAGE_FLAG_WAS_DELIVERED = 0x0010, 32 MESSAGE_FLAG_HAS_SPECIFIERS = 0x0020, 33 MESSAGE_FLAG_WAS_DROPPED = 0x0040, 34 MESSAGE_FLAG_PASS_BY_AREA = 0x0080, 35 MESSAGE_FLAG_REPLY_AS_KMESSAGE = 0x0100 36 }; 37 38 39 enum { 40 FIELD_FLAG_VALID = 0x0001, 41 FIELD_FLAG_FIXED_SIZE = 0x0002, 42 }; 43 44 45 struct BMessage::field_header { 46 uint16 flags; 47 uint16 name_length; 48 type_code type; 49 uint32 count; 50 uint32 data_size; 51 uint32 offset; 52 int32 next_field; 53 } _PACKED; 54 55 56 struct BMessage::message_header { 57 uint32 format; 58 uint32 what; 59 uint32 flags; 60 61 int32 target; 62 int32 current_specifier; 63 area_id message_area; 64 65 // reply info 66 port_id reply_port; 67 int32 reply_target; 68 team_id reply_team; 69 70 // body info 71 uint32 data_size; 72 uint32 field_count; 73 uint32 hash_table_size; 74 int32 hash_table[MESSAGE_BODY_HASH_TABLE_SIZE]; 75 76 /* The hash table does contain indexes into the field list and 77 not direct offsets to the fields. This has the advantage 78 of not needing to update offsets in two locations. 79 The hash table must be reevaluated when we remove a field 80 though. 81 */ 82 } _PACKED; 83 84 85 class BMessage::Private { 86 public: 87 Private(BMessage *msg) 88 : 89 fMessage(msg) 90 { 91 } 92 93 Private(BMessage &msg) 94 : 95 fMessage(&msg) 96 { 97 } 98 99 void 100 SetTarget(int32 token) 101 { 102 fMessage->fHeader->target = token; 103 } 104 105 void 106 SetReply(BMessenger messenger) 107 { 108 BMessenger::Private messengerPrivate(messenger); 109 fMessage->fHeader->reply_port = messengerPrivate.Port(); 110 fMessage->fHeader->reply_target = messengerPrivate.Token(); 111 fMessage->fHeader->reply_team = messengerPrivate.Team(); 112 } 113 114 void 115 SetReply(team_id team, port_id port, int32 target) 116 { 117 fMessage->fHeader->reply_port = port; 118 fMessage->fHeader->reply_target = target; 119 fMessage->fHeader->reply_team = team; 120 } 121 122 int32 123 GetTarget() 124 { 125 return fMessage->fHeader->target; 126 } 127 128 bool 129 UsePreferredTarget() 130 { 131 return fMessage->fHeader->target == B_PREFERRED_TOKEN; 132 } 133 134 void 135 SetWasDropped(bool wasDropped) 136 { 137 if (wasDropped) 138 fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED; 139 else 140 fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED; 141 } 142 143 status_t 144 Clear() 145 { 146 return fMessage->_Clear(); 147 } 148 149 status_t 150 InitHeader() 151 { 152 return fMessage->_InitHeader(); 153 } 154 155 BMessage::message_header* 156 GetMessageHeader() 157 { 158 return fMessage->fHeader; 159 } 160 161 BMessage::field_header* 162 GetMessageFields() 163 { 164 return fMessage->fFields; 165 } 166 167 uint8* 168 GetMessageData() 169 { 170 return fMessage->fData; 171 } 172 173 status_t 174 FlattenToArea(message_header **header) const 175 { 176 return fMessage->_FlattenToArea(header); 177 } 178 179 status_t 180 SendMessage(port_id port, team_id portOwner, int32 token, 181 bigtime_t timeout, bool replyRequired, BMessenger &replyTo) const 182 { 183 return fMessage->_SendMessage(port, portOwner, token, 184 timeout, replyRequired, replyTo); 185 } 186 187 status_t 188 SendMessage(port_id port, team_id portOwner, int32 token, 189 BMessage *reply, bigtime_t sendTimeout, 190 bigtime_t replyTimeout) const 191 { 192 return fMessage->_SendMessage(port, portOwner, token, 193 reply, sendTimeout, replyTimeout); 194 } 195 196 void* 197 ArchivingPointer() 198 { 199 return fMessage->fArchivingPointer; 200 } 201 202 void 203 SetArchivingPointer(void* pointer) 204 { 205 fMessage->fArchivingPointer = pointer; 206 } 207 208 // static methods 209 210 static status_t 211 SendFlattenedMessage(void *data, int32 size, port_id port, 212 int32 token, bigtime_t timeout) 213 { 214 return BMessage::_SendFlattenedMessage(data, size, 215 port, token, timeout); 216 } 217 218 static void 219 StaticInit() 220 { 221 BMessage::_StaticInit(); 222 } 223 224 static void 225 StaticReInitForkedChild() 226 { 227 BMessage::_StaticReInitForkedChild(); 228 } 229 230 static void 231 StaticCleanup() 232 { 233 BMessage::_StaticCleanup(); 234 } 235 236 static void 237 StaticCacheCleanup() 238 { 239 BMessage::_StaticCacheCleanup(); 240 } 241 242 private: 243 BMessage* fMessage; 244 }; 245 246 #endif // _MESSAGE_PRIVATE_H_ 247