1 /* 2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #ifndef KMESSAGE_H 7 #define KMESSAGE_H 8 9 #include <string.h> 10 11 #include <OS.h> 12 #include <TypeConstants.h> 13 14 class BMessage; 15 16 namespace BPrivate { 17 18 class KMessageField; 19 20 // KMessage 21 class KMessage { 22 public: 23 enum { 24 KMESSAGE_OWNS_BUFFER = 0x01, 25 KMESSAGE_INIT_FROM_BUFFER = 0x02, 26 KMESSAGE_READ_ONLY = 0x04, 27 28 KMESSAGE_FLAG_MASK = 0x07, 29 }; 30 31 KMessage(); 32 KMessage(uint32 what); 33 ~KMessage(); 34 35 status_t SetTo(uint32 what, uint32 flags = 0); 36 status_t SetTo(void *buffer, int32 bufferSize, uint32 what, 37 uint32 flags = 0); 38 status_t SetTo(const void *buffer, int32 bufferSize); 39 void Unset(); 40 41 void SetWhat(uint32 what); 42 uint32 What() const; 43 44 const void *Buffer() const; 45 int32 BufferCapacity() const; 46 int32 ContentSize() const; 47 48 status_t AddField(const char *name, type_code type, int32 elementSize = -1, 49 KMessageField *field = NULL); 50 status_t FindField(const char *name, KMessageField *field) const; 51 status_t FindField(const char *name, type_code type, 52 KMessageField *field) const; 53 status_t GetNextField(KMessageField *field) const; 54 55 status_t AddData(const char *name, type_code type, const void *data, 56 int32 numBytes, bool isFixedSize = true); 57 status_t AddArray(const char *name, type_code type, const void *data, 58 int32 elementSize, int32 elementCount); 59 inline status_t AddBool(const char *name, bool value); 60 inline status_t AddInt8(const char *name, int8 value); 61 inline status_t AddInt16(const char *name, int16 value); 62 inline status_t AddInt32(const char *name, int32 value); 63 inline status_t AddInt64(const char *name, int64 value); 64 inline status_t AddString(const char *name, const char *value); 65 66 status_t FindData(const char *name, type_code type, 67 const void **data, int32 *numBytes) const; 68 status_t FindData(const char *name, type_code type, int32 index, 69 const void **data, int32 *numBytes) const; 70 inline status_t FindBool(const char *name, bool *value) const; 71 inline status_t FindBool(const char *name, int32 index, bool *value) const; 72 inline status_t FindInt8(const char *name, int8 *value) const; 73 inline status_t FindInt8(const char *name, int32 index, int8 *value) const; 74 inline status_t FindInt16(const char *name, int16 *value) const; 75 inline status_t FindInt16(const char *name, int32 index, int16 *value) const; 76 inline status_t FindInt32(const char *name, int32 *value) const; 77 inline status_t FindInt32(const char *name, int32 index, int32 *value) const; 78 inline status_t FindInt64(const char *name, int64 *value) const; 79 inline status_t FindInt64(const char *name, int32 index, int64 *value) const; 80 inline status_t FindString(const char *name, const char **value) const; 81 inline status_t FindString(const char *name, int32 index, 82 const char **value) const; 83 84 // message delivery 85 team_id Sender() const; 86 int32 TargetToken() const; 87 port_id ReplyPort() const; 88 int32 ReplyToken() const; 89 90 status_t SendTo(port_id targetPort, int32 targetToken = -1, 91 port_id replyPort = -1, int32 replyToken = -1, bigtime_t timeout = -1, 92 team_id senderTeam = -1); 93 status_t SendTo(port_id targetPort, int32 targetToken, 94 KMessage* reply, bigtime_t deliveryTimeout = -1, 95 bigtime_t replyTimeout = -1, team_id senderTeam = -1); 96 status_t SendReply(KMessage* message, port_id replyPort = -1, 97 int32 replyToken = -1, bigtime_t timeout = -1, team_id senderTeam = -1); 98 status_t SendReply(KMessage* message, KMessage* reply, 99 bigtime_t deliveryTimeout = -1, bigtime_t replyTimeout = -1, 100 team_id senderTeam = -1); 101 status_t ReceiveFrom(port_id fromPort, bigtime_t timeout = -1); 102 103 private: 104 friend class KMessageField; 105 friend class ::BMessage; // not so nice, but makes things easier 106 107 struct Header { 108 uint32 magic; 109 int32 size; 110 uint32 what; 111 team_id sender; 112 int32 targetToken; 113 port_id replyPort; 114 int32 replyToken; 115 }; 116 117 struct FieldHeader; 118 struct FieldValueHeader; 119 120 Header *_Header() const; 121 int32 _BufferOffsetFor(const void* data) const; 122 FieldHeader *_FirstFieldHeader() const; 123 FieldHeader *_LastFieldHeader() const; 124 FieldHeader *_FieldHeaderForOffset(int32 offset) const; 125 status_t _AddField(const char *name, type_code type, int32 elementSize, 126 KMessageField *field); 127 status_t _AddFieldData(KMessageField *field, const void *data, 128 int32 elementSize, int32 elementCount); 129 130 status_t _InitFromBuffer(); 131 void _InitBuffer(uint32 what); 132 133 void _CheckBuffer(); // debugging only 134 135 status_t _AllocateSpace(int32 size, bool alignAddress, bool alignSize, 136 void **address, int32 *alignedSize); 137 int32 _CapacityFor(int32 size); 138 template<typename T> inline status_t _FindType(const char* name, 139 type_code type, int32 index, T *value) const; 140 141 Header fHeader; // pointed to by fBuffer, if nothing is 142 // allocated 143 void* fBuffer; 144 int32 fBufferCapacity; 145 uint32 fFlags; 146 int32 fLastFieldOffset; 147 148 static const uint32 kMessageHeaderMagic; 149 }; 150 151 // KMessageField 152 class KMessageField { 153 public: 154 KMessageField(); 155 156 void Unset(); 157 158 KMessage *Message() const; 159 160 const char *Name() const; 161 type_code TypeCode() const; 162 bool HasFixedElementSize() const; 163 int32 ElementSize() const; // if HasFixedElementSize() 164 165 status_t AddElement(const void *data, int32 size = -1); 166 status_t AddElements(const void *data, int32 count, int32 elementSize = -1); 167 const void *ElementAt(int32 index, int32 *size = NULL) const; 168 int32 CountElements() const; 169 170 private: 171 void SetTo(KMessage *message, int32 headerOffset); 172 173 KMessage::FieldHeader* _Header() const; 174 175 friend class KMessage; 176 177 KMessage *fMessage; 178 int32 fHeaderOffset; 179 }; 180 181 } // namespace BPrivate 182 183 using BPrivate::KMessage; 184 using BPrivate::KMessageField; 185 186 // #pragma mark - 187 // inline functions 188 189 // AddBool 190 inline 191 status_t 192 KMessage::AddBool(const char *name, bool value) 193 { 194 return AddData(name, B_BOOL_TYPE, &value, sizeof(bool), true); 195 } 196 197 // AddInt8 198 inline 199 status_t 200 KMessage::AddInt8(const char *name, int8 value) 201 { 202 return AddData(name, B_INT8_TYPE, &value, sizeof(int8), true); 203 } 204 205 // AddInt16 206 inline 207 status_t 208 KMessage::AddInt16(const char *name, int16 value) 209 { 210 return AddData(name, B_INT16_TYPE, &value, sizeof(int16), true); 211 } 212 213 // AddInt32 214 inline 215 status_t 216 KMessage::AddInt32(const char *name, int32 value) 217 { 218 return AddData(name, B_INT32_TYPE, &value, sizeof(int32), true); 219 } 220 221 // AddInt64 222 inline 223 status_t 224 KMessage::AddInt64(const char *name, int64 value) 225 { 226 return AddData(name, B_INT64_TYPE, &value, sizeof(int64), true); 227 } 228 229 // AddString 230 inline 231 status_t 232 KMessage::AddString(const char *name, const char *value) 233 { 234 if (!value) 235 return B_BAD_VALUE; 236 return AddData(name, B_STRING_TYPE, value, strlen(value) + 1, false); 237 } 238 239 // #pragma mark - 240 241 // FindBool 242 inline 243 status_t 244 KMessage::FindBool(const char *name, bool *value) const 245 { 246 return FindBool(name, 0, value); 247 } 248 249 // FindBool 250 inline 251 status_t 252 KMessage::FindBool(const char *name, int32 index, bool *value) const 253 { 254 return _FindType(name, B_BOOL_TYPE, index, value); 255 } 256 257 // FindInt8 258 inline 259 status_t 260 KMessage::FindInt8(const char *name, int8 *value) const 261 { 262 return FindInt8(name, 0, value); 263 } 264 265 // FindInt8 266 inline 267 status_t 268 KMessage::FindInt8(const char *name, int32 index, int8 *value) const 269 { 270 return _FindType(name, B_INT8_TYPE, index, value); 271 } 272 273 // FindInt16 274 inline 275 status_t 276 KMessage::FindInt16(const char *name, int16 *value) const 277 { 278 return FindInt16(name, 0, value); 279 } 280 281 // FindInt16 282 inline 283 status_t 284 KMessage::FindInt16(const char *name, int32 index, int16 *value) const 285 { 286 return _FindType(name, B_INT16_TYPE, index, value); 287 } 288 289 // FindInt32 290 inline 291 status_t 292 KMessage::FindInt32(const char *name, int32 *value) const 293 { 294 return FindInt32(name, 0, value); 295 } 296 297 // FindInt32 298 inline 299 status_t 300 KMessage::FindInt32(const char *name, int32 index, int32 *value) const 301 { 302 return _FindType(name, B_INT32_TYPE, index, value); 303 } 304 305 // FindInt64 306 inline 307 status_t 308 KMessage::FindInt64(const char *name, int64 *value) const 309 { 310 return FindInt64(name, 0, value); 311 } 312 313 // FindInt64 314 inline 315 status_t 316 KMessage::FindInt64(const char *name, int32 index, int64 *value) const 317 { 318 return _FindType(name, B_INT64_TYPE, index, value); 319 } 320 321 // FindString 322 inline 323 status_t 324 KMessage::FindString(const char *name, const char **value) const 325 { 326 return FindString(name, 0, value); 327 } 328 329 // FindString 330 inline 331 status_t 332 KMessage::FindString(const char *name, int32 index, const char **value) const 333 { 334 int32 size; 335 return FindData(name, B_STRING_TYPE, index, (const void**)value, &size); 336 } 337 338 #endif // KMESSAGE_H 339