xref: /haiku/headers/private/app/MessageUtils.h (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 //------------------------------------------------------------------------------
2 //	MessageUtils.h
3 //
4 //------------------------------------------------------------------------------
5 
6 #ifndef MESSAGEUTILS_H
7 #define MESSAGEUTILS_H
8 
9 // Standard Includes -----------------------------------------------------------
10 
11 // System Includes -------------------------------------------------------------
12 #include <ByteOrder.h>
13 #include <DataIO.h>
14 #include <Entry.h>
15 #include <Message.h>
16 #include <Messenger.h>
17 #include <MessengerPrivate.h>
18 #include <SupportDefs.h>
19 
20 // Project Includes ------------------------------------------------------------
21 
22 // Local Includes --------------------------------------------------------------
23 
24 // Local Defines ---------------------------------------------------------------
25 
26 // Globals ---------------------------------------------------------------------
27 
28 uint32 _checksum_(const uchar *buf, int32 size);
29 
30 namespace BPrivate {	// Only putting these here because Be did
31 
32 status_t entry_ref_flatten(char* buffer, size_t* size, const entry_ref* ref);
33 status_t entry_ref_unflatten(entry_ref* ref, const char* buffer, size_t size);
34 status_t entry_ref_swap(char* buffer, size_t size);
35 
36 size_t calc_padding(size_t size, size_t boundary);
37 
38 }	// namespace BPrivate
39 
40 //------------------------------------------------------------------------------
41 // _set_message_target_
42 /*!	\brief Sets the target of a message.
43 
44 	\param message The message.
45 	\param token The target handler token.
46 	\param preferred Indicates whether to use the looper's preferred handler.
47 */
48 inline
49 void
50 _set_message_target_(BMessage *message, int32 token, bool preferred)
51 {
52 	message->fTarget = token;
53 	message->fPreferred = preferred;
54 }
55 //------------------------------------------------------------------------------
56 // _set_message_reply_
57 /*!	\brief Sets a message's reply target.
58 
59 	\param message The message.
60 	\param messenger The reply messenger.
61 */
62 inline
63 void
64 _set_message_reply_(BMessage *message, BMessenger messenger)
65 {
66 	BMessenger::Private messengerPrivate(messenger);
67 	message->fReplyTo.port = messengerPrivate.Port();
68 	message->fReplyTo.target = messengerPrivate.Token();
69 	message->fReplyTo.team = messengerPrivate.Team();
70 	message->fReplyTo.preferred = messengerPrivate.IsPreferredTarget();
71 }
72 //------------------------------------------------------------------------------
73 inline int32 _get_message_target_(BMessage *msg)
74 {
75 	return msg->fTarget;
76 }
77 //------------------------------------------------------------------------------
78 inline bool _use_preferred_target_(BMessage *msg)
79 {
80 	return msg->fPreferred;
81 }
82 //------------------------------------------------------------------------------
83 inline status_t normalize_err(status_t err)
84 {
85 	return err >= 0 ? B_OK : err;
86 }
87 //------------------------------------------------------------------------------
88 template<class T>
89 inline void byte_swap(T& /*data*/)
90 {
91 	// Specialize for data types which actually swap
92 }
93 //------------------------------------------------------------------------------
94 inline void write_helper(BDataIO* stream, const void* data, size_t size,
95 						 status_t& err)
96 {
97 	err = normalize_err(stream->Write(data, size));
98 }
99 //------------------------------------------------------------------------------
100 // Will the template madness never cease??
101 template<class T>
102 inline status_t write_helper(BDataIO* stream, T& data, status_t& err)
103 {
104 	return normalize_err(stream->Write((const void*)data, sizeof (T)));
105 }
106 //------------------------------------------------------------------------------
107 class TReadHelper
108 {
109 	public:
110 		TReadHelper(BDataIO* stream)
111 			:	fStream(stream), err(B_OK), fSwap(false)
112 		{
113 			;
114 		}
115 
116 		TReadHelper(BDataIO* stream, bool swap)
117 			:	fStream(stream), err(B_OK), fSwap(swap)
118 		{
119 			;
120 		}
121 
122 		template<class T> inline void operator()(T& data)
123 		{
124 			err = normalize_err(fStream->Read((void*)&data, sizeof (T)));
125 			if (err)
126 				throw err;
127 
128 			if (IsSwapping())
129 			{
130 				byte_swap(data);
131 			}
132 		}
133 
134 		template<class T> inline void operator()(T data, size_t len)
135 		{
136 			err = normalize_err(fStream->Read((void*)data, len));
137 			if (err)
138 				throw err;
139 		}
140 
141 		status_t	Status() { return err; }
142 		void		SetSwap(bool yesNo) { fSwap = yesNo; }
143 		bool		IsSwapping() { return fSwap; }
144 
145 	private:
146 		BDataIO*	fStream;
147 		status_t	err;
148 		bool		fSwap;
149 };
150 //------------------------------------------------------------------------------
151 class TChecksumHelper
152 {
153 	public:
154 		TChecksumHelper(uchar* buffer) : fBuffer(buffer), fBufPtr(buffer) {;}
155 
156 		template<class T> inline void Cache(const T& data)
157 		{
158 			*((T*)fBufPtr) = data;
159 			fBufPtr += sizeof (T);
160 		}
161 
162 		int32    CheckSum();
163 
164 	private:
165 		uchar*		fBuffer;
166 		uchar*		fBufPtr;
167 };
168 //------------------------------------------------------------------------------
169 template<class T> inline status_t read_helper(BDataIO* stream, T& data)
170 {
171 	return normalize_err(stream->Read((void*)&data, sizeof (T)));
172 }
173 //------------------------------------------------------------------------------
174 template<> inline void byte_swap(double& data)
175 {
176 	data = __swap_double(data);
177 }
178 template<> inline void byte_swap(float& data)
179 {
180 	data = __swap_float(data);
181 }
182 template<> inline void byte_swap(int64& data)
183 {
184 	data = __swap_int64(data);
185 }
186 template<> inline void byte_swap(int32& data)
187 {
188 	data = __swap_int32(data);
189 }
190 template<> inline void byte_swap(int16& data)
191 {
192 	data = __swap_int16(data);
193 }
194 template<> inline void byte_swap(entry_ref& data)
195 {
196 	byte_swap(data.device);
197 	byte_swap(data.directory);
198 }
199 //------------------------------------------------------------------------------
200 
201 #endif	// MESSAGEUTILS_H
202 
203 /*
204  * $Log $
205  *
206  * $Id  $
207  *
208  */
209 
210