1//------------------------------------------------------------------------------
2//	MessageFlattenableItemTest.h
3//
4//------------------------------------------------------------------------------
5
6#ifndef MESSAGEFLATTENABLEITEMTEST_H
7#define MESSAGEFLATTENABLEITEMTEST_H
8
9// Standard Includes -----------------------------------------------------------
10#include <string>
11
12// System Includes -------------------------------------------------------------
13
14// Project Includes ------------------------------------------------------------
15#include <Flattenable.h>
16
17// Local Includes --------------------------------------------------------------
18#include "MessageItemTest.h"
19
20// Local Defines ---------------------------------------------------------------
21#define MY_FLATTENABLE_TYPE	'flat'
22
23// Globals ---------------------------------------------------------------------
24
25class MyFlattenableType : public BFlattenable
26{
27	public:
28		MyFlattenableType() {;}
29		MyFlattenableType(const char* data)
30			:	fData(data)
31		{;}
32
33		bool operator==(const MyFlattenableType& mft) const;
34//			{ return fData == mft.fData; }
35
36		virtual status_t	Flatten(void* buffer, ssize_t numBytes) const;
37		virtual status_t	Unflatten(type_code code, const void* buffer,
38									  ssize_t numBytes);
39		virtual ssize_t		FlattenedSize() const { return fData.length() + 1; }
40		virtual bool		IsFixedSize() const { return false; }
41		virtual type_code	TypeCode() const { return MY_FLATTENABLE_TYPE; }
42
43	private:
44		std::string	fData;
45};
46//------------------------------------------------------------------------------
47bool MyFlattenableType::operator==(const MyFlattenableType& mft) const
48{
49	bool ret = fData == mft.fData;
50	return ret;
51}
52//------------------------------------------------------------------------------
53status_t MyFlattenableType::Flatten(void* buffer, ssize_t numBytes) const
54{
55	if (!buffer)
56	{
57		return B_BAD_VALUE;
58	}
59	if (numBytes != FlattenedSize())
60	{
61		return B_NO_MEMORY;
62	}
63	memcpy(buffer, (const void*)fData.c_str(), fData.length());
64	((char*)buffer)[fData.length()] = '\0';
65	return B_OK;
66}
67//------------------------------------------------------------------------------
68status_t MyFlattenableType::Unflatten(type_code code, const void* buffer,
69									  ssize_t numBytes)
70{
71	if (!buffer)
72	{
73		return B_BAD_VALUE;
74	}
75	if (!AllowsTypeCode(code))
76	{
77		return B_ERROR;
78	}
79	fData.assign((const char*)buffer, numBytes - 1);
80	return B_OK;
81}
82//------------------------------------------------------------------------------
83
84
85struct TFlattenableFuncPolicy
86{
87	static status_t Add(BMessage& msg, const char* name, MyFlattenableType& val)
88		{ return msg.AddFlat(name, &val); }
89	static status_t AddData(BMessage& msg, const char* name, type_code type,
90							MyFlattenableType* data, ssize_t size, bool)
91	{
92		char* buffer = new char[size];
93		status_t err = data->Flatten(buffer, size);
94		if (!err)
95		{
96			err = msg.AddData(name, type, buffer, size, false);
97		}
98		delete[] buffer;
99		return err;
100	}
101	static status_t Find(BMessage& msg, const char* name, int32 index,
102						 MyFlattenableType* val)
103	{
104		return msg.FindFlat(name, index, val);
105	}
106	static status_t ShortFind(BMessage& msg, const char* name, MyFlattenableType* val)
107	{
108		return msg.FindFlat(name, val);
109	}
110	static MyFlattenableType QuickFind(BMessage& msg, const char* name, int32 index)
111	{
112		MyFlattenableType mft;
113		msg.FindFlat(name, index, &mft);
114		return mft;
115	}
116	static bool Has(BMessage& msg, const char* name, int32 index)
117		{ return msg.HasFlat(name, index, &sFlat); }
118	static status_t Replace(BMessage& msg, const char* name, int32 index,
119							MyFlattenableType& val)
120		{ return msg.ReplaceFlat(name, index, &val); }
121	static status_t FindData(BMessage& msg, const char* name, type_code type,
122							 int32 index, const void** data, ssize_t* size)
123	{
124		*data = NULL;
125		char* ptr;
126		status_t err = msg.FindData(name, type, index, (const void**)&ptr, size);
127		if (!err)
128		{
129			err = sFlat.Unflatten(type, ptr, *size);
130			if (!err)
131			{
132				*(MyFlattenableType**)data = &sFlat;
133			}
134		}
135		return err;
136	}
137
138	private:
139		static MyFlattenableType sFlat;
140};
141MyFlattenableType TFlattenableFuncPolicy::sFlat;
142//------------------------------------------------------------------------------
143struct TFlattenableInitPolicy : public ArrayTypeBase<MyFlattenableType>
144{
145	inline static MyFlattenableType Zero()	{ return ""; }
146	inline static MyFlattenableType Test1()	{ return "flat1"; }
147	inline static MyFlattenableType Test2()	{ return "MyFlattenableType"; }
148	inline static size_t SizeOf(const BFlattenable& flat)
149		{ return flat.FlattenedSize(); }
150	inline static ArrayType Array()
151	{
152		ArrayType array;
153		array.push_back(Zero());
154		array.push_back(Test1());
155		array.push_back(Test2());
156		return array;
157	}
158};
159//------------------------------------------------------------------------------
160struct TFlattenableAssertPolicy
161{
162	inline static MyFlattenableType	Zero()				{ return MyFlattenableType(); }
163	inline static MyFlattenableType	Invalid()			{ return MyFlattenableType(); }
164	 static bool		Size(size_t size, MyFlattenableType& flat)
165		;//{ return size == msg.FlattenedSize(); }
166};
167bool TFlattenableAssertPolicy::Size(size_t size, MyFlattenableType& flat)
168{
169	ssize_t flatSize = flat.FlattenedSize();
170	return size == (size_t)flatSize;
171}
172//------------------------------------------------------------------------------
173template<>
174struct TypePolicy<MyFlattenableType>
175{
176	typedef MyFlattenableType* TypePtr;
177	enum { FixedSize = false };
178	inline MyFlattenableType& Dereference(TypePtr p)
179	{
180		return *p;
181	}
182	inline TypePtr AddressOf(MyFlattenableType& t) { return &t; }
183};
184//------------------------------------------------------------------------------
185
186typedef TMessageItemTest
187<
188	MyFlattenableType,
189	MY_FLATTENABLE_TYPE,
190	TFlattenableFuncPolicy,
191	TFlattenableInitPolicy,
192	TFlattenableAssertPolicy
193>
194TMessageFlattenableItemTest;
195
196#endif	// MESSAGEFLATTENABLEITEMTEST_H
197
198/*
199 * $Log $
200 *
201 * $Id  $
202 *
203 */
204
205