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