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