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 private: 174 BMessage* fMessage; 175 }; 176 177 #endif // _MESSAGE_PRIVATE_H_ 178