1 /* 2 * Copyright 2005-2010, 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 status_t 172 FlattenToArea(message_header **header) const 173 { 174 return fMessage->_FlattenToArea(header); 175 } 176 177 status_t 178 SendMessage(port_id port, team_id portOwner, int32 token, 179 bigtime_t timeout, bool replyRequired, BMessenger &replyTo) const 180 { 181 return fMessage->_SendMessage(port, portOwner, token, 182 timeout, replyRequired, replyTo); 183 } 184 185 status_t 186 SendMessage(port_id port, team_id portOwner, int32 token, 187 BMessage *reply, bigtime_t sendTimeout, 188 bigtime_t replyTimeout) const 189 { 190 return fMessage->_SendMessage(port, portOwner, token, 191 reply, sendTimeout, replyTimeout); 192 } 193 194 void* 195 ArchivingPointer() 196 { 197 return fMessage->fArchivingPointer; 198 } 199 200 void 201 SetArchivingPointer(void* pointer) 202 { 203 fMessage->fArchivingPointer = pointer; 204 } 205 206 // static methods 207 208 static status_t 209 SendFlattenedMessage(void *data, int32 size, port_id port, 210 int32 token, bigtime_t timeout) 211 { 212 return BMessage::_SendFlattenedMessage(data, size, 213 port, token, timeout); 214 } 215 216 static void 217 StaticInit() 218 { 219 BMessage::_StaticInit(); 220 } 221 222 static void 223 StaticReInitForkedChild() 224 { 225 BMessage::_StaticReInitForkedChild(); 226 } 227 228 static void 229 StaticCleanup() 230 { 231 BMessage::_StaticCleanup(); 232 } 233 234 static void 235 StaticCacheCleanup() 236 { 237 BMessage::_StaticCacheCleanup(); 238 } 239 240 private: 241 BMessage* fMessage; 242 }; 243 244 #endif // _MESSAGE_PRIVATE_H_ 245