xref: /haiku/docs/user/support/Flattenable.dox (revision 21258e2674226d6aa732321b6f8494841895af5f)
1/*
2 * Copyright 2007-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Niels Sascha Reedijk, niels.reedijk@gmail.com
7 *		John Scipione, jscipione@gmail.com
8 *
9 * Corresponds to:
10 *		headers/os/support/Flattenable.h	rev 39675
11 *		src/kits/support/Flattenable.cpp	rev 12963
12 */
13
14
15/*!
16	\file Flattenable.h
17	\ingroup support
18	\ingroup libbe
19	\brief Provides the BFlattenable interface
20*/
21
22
23/*!
24	\class BFlattenable
25	\ingroup support
26	\ingroup libbe
27	\brief Interface for classes that can flatten and unflatten themselves to
28	       a stream of bytes.
29
30	It is convenient that objects can be stored as a flat stream of bytes. In
31	this way, they can be written to disk, exchanged between applications or send
32	over networks. This ability, known as marshaling in many other programming
33	languages, is not native to C++. The Haiku API has created a universal
34	interface that classes have if they are able to be flattened. This
35	class defines the interface. This class does nothing on its own, and
36	therefore contains pure virtual functions. By inheriting this class and
37	implementing the methods in your own class, you will be able to use your
38	objects as flattenable objects throughout the Haiku API.
39
40	Flattened objects can be used for example when sending messages within an
41	application or between applications. The BMessage class uses the interface
42	to store and transmit custom classes.
43
44	If you want to be able to flatten your objects, you will need to implement
45	various methods. Flatten() and Unflatten() are where the magic happen. These
46	methods handle the actual flattening and unflattening. To identify flattened
47	data in for example BMessage, the object has a type_code. Type codes are
48	four byte long integers. You can choose to flatten to one of the existing
49	types, if you are certain that you are compatible to those, but you'll
50	usually define your own type. Your best option is by using a multicharacter
51	constant, such as 'STRI'. Implement TypeCode() to return the type you
52	support. Implement FlattenedSize() to make sure that other objects can
53	provide the right buffers. Implement IsFixedSize() to return whether your
54	objects always store to a fixed size.
55
56	See the following example:
57\code
58type_code CUSTOM_STRING_TYPE = 'CUST';
59
60class CustomString : public BFlattenable {
61public:
62	char data[100];
63
64	// from BFlattenable
65	bool IsFixedSize() const { return false; };
66	type_code TypeCode() const { return CUSTOM_STRING_TYPE; };
67	ssize_t FlattenedSize() const { return strlen(data); };
68
69	status_t Flatten(void* buffer, ssize_t size) const
70	{
71		if ((strlen(data) + 1) < size)
72			return B_BAD_VALUE;
73
74		memcpy(buffer, data, size);
75
76		return B_OK;
77	};
78
79	status_t Unflatten(type_code code, const void* buffer, ssize_t size)
80	{
81		if (code != CUSTOM_STRING_TYPE)
82			return B_BAD_TYPE;
83
84		if (size > 100)
85			return B_NO_MEMORY;
86
87		memcpy(data, buffer, size);
88
89		return B_OK;
90	};
91};
92\endcode
93
94	Have a look at TypeConstants.h for a list of all the types that the Haiku
95	API defines.
96
97	The Haiku API has a second interface for storing objects, which is with
98	BArchivable. BArchivable is for more complex cases. Instead of one flat
99	datastream, it stores an object in a BMessage. In that way you can reflect
100	internals of a class better. It also provides an interface for instantiating
101	objects, that is, for objects to restore themselves from a BMessage. In
102	essence, BArchivable is more suitable for objects that are alive. In short
103	BFlattenable is for data objects, BArchivable is for 'live' objects.
104
105	Other classes in the API that support flattening and unflattening are for
106	example BMessage, which enables you to conveniently write flattened data
107	to disk. Another example is BPath. Because of that you can store paths and
108	send them over via messages. Throughout the Haiku API you will find classes
109	that provide the flattening interface.
110
111	\since BeOS R3
112*/
113
114
115/*!
116	\fn virtual bool BFlattenable::IsFixedSize() const
117	\brief Pure virtual that should return whether or not flattened objects of
118	       this type always have a fixed size.
119
120	\return Should return whether or not the flattened objects of this type
121	        always have a fixed size.
122
123	\since BeOS R3
124*/
125
126
127/*!
128	\fn virtual type_code BFlattenable::TypeCode() const
129	\brief Pure virtual that returns the type_code this class flattens to.
130
131	\return Either one of the existing typecodes found in TypeConstants.h
132	        if your class actually is compatible to those formats, or a
133	        custom four-byte integer constant if not.
134
135	\since BeOS R3
136*/
137
138
139/*!
140	\fn virtual ssize_t BFlattenable::FlattenedSize() const
141	\brief Pure virtual that should return the size of the flattened object in
142	       bytes.
143
144	\since BeOS R3
145*/
146
147
148/*!
149	\fn virtual status_t BFlattenable::Flatten(void* buffer, ssize_t size) const
150	\brief Pure virtual that should flatten the object into the supplied
151	       \a buffer.
152
153	Please make sure that you check that the supplied buffer is not a \c NULL
154	pointer. Also make sure that the size of the flattened object does isn't
155	larger than the size of the buffer.
156
157	\param buffer The buffer to flatten in.
158	\param size The size of the buffer.
159
160	\retval B_OK The object was flattened.
161	\retval B_NO_MEMORY The buffer was smaller than required.
162	\retval B_BAD_VALUE The buffer was a \c NULL pointer.
163
164	\since BeOS R3
165*/
166
167
168/*!
169	\fn bool BFlattenable::AllowsTypeCode(type_code code) const
170	\brief Get whether or not the supplied type_code is supported.
171
172	This default implementation checks the \a code argument against the type_code
173	returned by TypeCode().
174
175	\param code The type_code constant you want to check for.
176
177	\returns Whether or not the supplied type_code is supported.
178	\retval true The type_code is supported.
179	\retval false The type_code is not supported.
180
181	\since BeOS R3
182*/
183
184
185/*!
186	\fn virtual status_t BFlattenable::Unflatten(type_code code,
187		const void* buffer, ssize_t size)
188	\brief Pure virtual that should unflatten the buffer and put the contents
189	       into the current object.
190
191	Make sure that the supplied buffer is not \c NULL and that you actually
192	support the typecode.
193
194	\param code The type_code this data is.
195	\param buffer The buffer to unflatten the data from.
196	\param size The size of the data.
197
198	\returns A status code.
199	\retval B_OK The object is unflattened.
200	\retval B_BAD_VALUE The \a buffer pointer is \c NULL or the data is invalid.
201	\retval B_BAD_TYPE You don't support data with this \a code.
202
203	\since BeOS R3
204*/
205
206
207/*!
208	\fn virtual BFlattenable::~BFlattenable()
209	\brief Destructor. Does nothing.
210
211	\since Haiku R1
212*/
213