vfs: check userland buffers before reading them.
[haiku.git] / docs / user / support / Flattenable.dox
blob34c267e7206696b07759f8ef927c2768d1683ed7
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  */
15 /*!
16         \file Flattenable.h
17         \ingroup support
18         \ingroup libbe
19         \brief Provides the BFlattenable interface
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.
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.
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.
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.
56         See the following example:
57 \code
58 type_code CUSTOM_STRING_TYPE = 'CUST';
60 class CustomString : public BFlattenable {
61 public:
62         char data[100];
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); };
69         status_t Flatten(void* buffer, ssize_t size) const
70         {
71                 if ((strlen(data) + 1) < size)
72                         return B_BAD_VALUE;
74                 memcpy(buffer, data, size);
76                 return B_OK;
77         };
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;
84                 if (size > 100)
85                         return B_NO_MEMORY;
87                 memcpy(data, buffer, size);
89                 return B_OK;
90         };
92 \endcode
94         Have a look at TypeConstants.h for a list of all the types that the Haiku
95         API defines.
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.
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.
111         \since BeOS R3
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.
120         \return Should return whether or not the flattened objects of this type
121                 always have a fixed size.
123         \since BeOS R3
128         \fn virtual type_code BFlattenable::TypeCode() const
129         \brief Pure virtual that returns the type_code this class flattens to.
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.
135         \since BeOS R3
140         \fn virtual ssize_t BFlattenable::FlattenedSize() const
141         \brief Pure virtual that should return the size of the flattened object in
142                bytes.
144         \since BeOS R3
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.
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.
157         \param buffer The buffer to flatten in.
158         \param size The size of the buffer.
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.
164         \since BeOS R3
169         \fn bool BFlattenable::AllowsTypeCode(type_code code) const
170         \brief Get whether or not the supplied type_code is supported.
172         This default implementation checks the \a code argument against the type_code
173         returned by TypeCode().
175         \param code The type_code constant you want to check for.
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.
181         \since BeOS R3
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.
191         Make sure that the supplied buffer is not \c NULL and that you actually
192         support the typecode.
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.
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. 
203         \since BeOS R3
208         \fn virtual BFlattenable::~BFlattenable()
209         \brief Destructor. Does nothing.
211         \since Haiku R1