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