xref: /haiku/src/tests/kits/app/bmessage/MessageFlattenableItemTest.h (revision f2ced752a08ff5d2618826bcd3ae3976c9f3e92e)
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 
25 class 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 //------------------------------------------------------------------------------
47 bool MyFlattenableType::operator==(const MyFlattenableType& mft) const
48 {
49 	bool ret = fData == mft.fData;
50 	return ret;
51 }
52 //------------------------------------------------------------------------------
53 status_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 //------------------------------------------------------------------------------
68 status_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 
85 struct 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 };
141 MyFlattenableType TFlattenableFuncPolicy::sFlat;
142 //------------------------------------------------------------------------------
143 struct 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 //------------------------------------------------------------------------------
160 struct 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 };
167 bool TFlattenableAssertPolicy::Size(size_t size, MyFlattenableType& flat)
168 {
169 	ssize_t flatSize = flat.FlattenedSize();
170 	return size == (size_t)flatSize;
171 }
172 //------------------------------------------------------------------------------
173 template<>
174 struct 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 
186 typedef TMessageItemTest
187 <
188 	MyFlattenableType,
189 	MY_FLATTENABLE_TYPE,
190 	TFlattenableFuncPolicy,
191 	TFlattenableInitPolicy,
192 	TFlattenableAssertPolicy
193 >
194 TMessageFlattenableItemTest;
195 
196 #endif	// MESSAGEFLATTENABLEITEMTEST_H
197 
198 /*
199  * $Log $
200  *
201  * $Id  $
202  *
203  */
204 
205