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