1//------------------------------------------------------------------------------
2//	MessageMessageItemTest.h
3//
4//------------------------------------------------------------------------------
5
6#ifndef MESSAGEMESSAGEITEMTEST_H
7#define MESSAGEMESSAGEITEMTEST_H
8
9// Standard Includes -----------------------------------------------------------
10
11// System Includes -------------------------------------------------------------
12#include <Debug.h>
13
14// Project Includes ------------------------------------------------------------
15
16// Local Includes --------------------------------------------------------------
17#include "MessageItemTest.h"
18
19// Local Defines ---------------------------------------------------------------
20
21// Globals ---------------------------------------------------------------------
22
23//------------------------------------------------------------------------------
24struct TMessageFuncPolicy
25{
26	static status_t Add(BMessage& msg, const char* name, BMessage& val);
27	static status_t AddData(BMessage& msg, const char* name, type_code type,
28							BMessage* data, ssize_t size, bool);
29	static status_t Find(BMessage& msg, const char* name, int32 index,
30						 BMessage* val);
31	static status_t ShortFind(BMessage& msg, const char* name, BMessage* val);
32	static BMessage QuickFind(BMessage& msg, const char* name, int32 index);
33	static bool Has(BMessage& msg, const char* name, int32 index);
34	static status_t Replace(BMessage& msg, const char* name, int32 index,
35							BMessage& val);
36	static status_t FindData(BMessage& msg, const char* name, type_code type,
37							 int32 index, const void** data, ssize_t* size);
38
39	private:
40		static BMessage sMsg;
41};
42BMessage TMessageFuncPolicy::sMsg;
43//------------------------------------------------------------------------------
44status_t TMessageFuncPolicy::Add(BMessage& msg, const char* name,
45								 BMessage& val)
46{
47	return msg.AddMessage(name, &val);
48}
49//------------------------------------------------------------------------------
50status_t TMessageFuncPolicy::AddData(BMessage& msg, const char* name,
51									 type_code type, BMessage* data,
52									 ssize_t size, bool)
53{
54	char* buf = new char[size];
55	status_t err = data->Flatten(buf, size);
56	if (!err)
57	{
58		err = msg.AddData(name, type, buf, size, false);
59	}
60	delete[] buf;
61	return err;
62}
63//------------------------------------------------------------------------------
64inline status_t TMessageFuncPolicy::Find(BMessage& msg, const char* name,
65										 int32 index, BMessage* val)
66{
67	return msg.FindMessage(name, index, val);
68}
69//------------------------------------------------------------------------------
70inline status_t TMessageFuncPolicy::ShortFind(BMessage& msg, const char* name,
71											  BMessage* val)
72{
73	return msg.FindMessage(name, val);
74}
75//------------------------------------------------------------------------------
76BMessage TMessageFuncPolicy::QuickFind(BMessage& msg, const char* name,
77											  int32 index)
78{
79	BMessage val;
80	msg.FindMessage(name, index, &val);
81	return val;
82}
83//------------------------------------------------------------------------------
84inline bool TMessageFuncPolicy::Has(BMessage& msg, const char* name,
85									int32 index)
86{
87	return msg.HasMessage(name, index);
88}
89//------------------------------------------------------------------------------
90inline status_t TMessageFuncPolicy::Replace(BMessage& msg, const char* name,
91											int32 index, BMessage& val)
92{
93	return msg.ReplaceMessage(name, index, &val);
94}
95//------------------------------------------------------------------------------
96inline status_t TMessageFuncPolicy::FindData(BMessage& msg, const char* name,
97											 type_code type, int32 index,
98											 const void** data, ssize_t* size)
99{
100	*data = NULL;
101	char* ptr;
102	status_t err = msg.FindData(name, type, index, (const void**)&ptr, size);
103	if (!err)
104	{
105		err = sMsg.Unflatten(ptr);
106		if (!err)
107		{
108			*(BMessage**)data = &sMsg;
109		}
110	}
111	return err;
112//	return (msg.*FindDataFunc)(name, type, index, data, size);
113}
114//------------------------------------------------------------------------------
115
116
117//------------------------------------------------------------------------------
118template<>
119struct ArrayTypeBase<BMessage>
120{
121	class ArrayType
122	{
123		public:
124			ArrayType() : array(NULL), size(0) {;}
125			ArrayType(const ArrayType& rhs) : array(NULL), size(0)
126				{ *this = rhs; }
127			ArrayType(BMessage* data, uint32 len) : array(NULL), size(0)
128				{ Assign(data, len); }
129			~ArrayType() { if (array) delete[] array; }
130
131			ArrayType& operator=(const ArrayType& rhs)
132			{
133				if (this != &rhs)
134					Assign(rhs.array, rhs.size);
135				return *this;
136			};
137
138			uint32 Size() { return size; }
139			BMessage& operator[](int index)
140			{
141				// We're just gonna let a segfault happen
142				return array[index];
143			}
144
145		private:
146			void Assign(BMessage* data, uint32 len)
147			{
148				size = len;
149
150				if (array)
151					delete[] array;
152				array = new BMessage[Size()];
153				for (uint32 i = 0; i < Size(); ++i)
154					array[i] = data[i];
155			}
156			BMessage*	array;
157			uint32		size;
158	};
159
160	typedef uint32 SizeType;
161	static SizeType Size(ArrayType& array) { return array.Size(); }
162};
163//------------------------------------------------------------------------------
164struct TMessageInitPolicy : public ArrayTypeBase<BMessage>
165{
166	inline static BMessage Zero()	{ return BMessage(); }
167	static BMessage Test1()
168	{
169		BMessage msg('1234');
170		msg.AddInt32("int32", 1234);
171		return msg;
172	}
173	static BMessage Test2()
174	{
175		BMessage msg('5678');
176		msg.AddString("string", "5678");
177		return msg;
178	}
179	static size_t SizeOf(const BMessage& data)
180	{
181		return data.FlattenedSize();
182	}
183	inline static ArrayType Array()
184	{
185		BMessage array[3];
186		array[0] = Zero();
187		array[1] = Test1();
188		array[2] = Test2();
189		return ArrayType(array, 3);
190	}
191};
192//------------------------------------------------------------------------------
193struct TMessageAssertPolicy
194{
195	inline static BMessage	Zero()				{ return BMessage(); }
196	inline static BMessage	Invalid()			{ return BMessage(); }
197	 static bool		Size(size_t size, BMessage& msg)
198		;//{ return size == msg.FlattenedSize(); }
199};
200bool TMessageAssertPolicy::Size(size_t size, BMessage& msg)
201{
202	ssize_t msgSize = msg.FlattenedSize();
203	return size == (size_t)msgSize;
204}
205//------------------------------------------------------------------------------
206template<>
207struct TMessageItemComparePolicy<BMessage>
208{
209	inline static bool Compare(const BMessage& lhs, const BMessage& rhs)
210		{ return lhs.what == rhs.what; }
211};
212//------------------------------------------------------------------------------
213typedef TMessageItemTest
214<
215	BMessage,
216	B_MESSAGE_TYPE,
217	TMessageFuncPolicy,
218	TMessageInitPolicy,
219	TMessageAssertPolicy
220>
221TMessageMessageItemTest;
222//------------------------------------------------------------------------------
223
224#endif	// MESSAGEMESSAGEITEMTEST_H
225
226/*
227 * $Log $
228 *
229 * $Id  $
230 *
231 */
232
233