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