Sunday, June 26, 2005
32. How do I use RBuf? What is it?
From the Symbian OS 8.1a SDK
RBuf16
16-bit resizable buffer descriptor [Jo comments - an equivalent 8-bit version, RBuf8, also exists]
The class provides a buffer that contains, accesses and manipulates TUint16 data. The buffer itself is on the heap, and is managed by the class.
Internally, RBuf16 behaves in one of two ways:
* as a TPtr16 descriptor type, where the buffer just contains data,
* as a pointer to a heap descriptor, an HBufC16* type, where the buffer contains both descriptor information and the data.
Note that the handling of the distinction is hidden from view.
An RBuf16 object can allocate its own buffer. Alternatively, it can take ownership of a pre-existing section of allocated memory, or it can take ownership of a pre-existing heap descriptor. It can also reallocate the buffer to resize it. Regardless of the way in which the buffer has been allocated, the RBuf16 object is responsible for freeing memory when the object itself is closed.
The class is intended for instantiation.
The class is derived from TDes16, which means that data can be both accessed and modified. The base classes provide the functions through which the data is accessed. In addition, an RBuf16 object can be passed to any function that is prototyped to take a TDes16 or a TDesC16 type.
So what does this mean for me?
An RBuf object is rather like an HBufC in that it can be created dynamically by specifying the maximum length required. However, it also benefits from being modifiable, since it derives from TDes16. This means that you don’t have to create a TPtr around the data in order to modify it, which makes it preferable to HBufC when you know you need to dynamically allocate a descriptor, and later modify it.
You don’t need to worry too much about how it’s represented internally – either as a TPtr or HBufC. In fact, all you need to know is how to create and destroy an RBuf, because calling the other descriptor operations on it should be second nature, given that you have access to all the base class methods of TDes16 and TDes16C.
But you must remember that, although RBuf manages the descriptor buffer by freeing it when you call Close(), it doesn’t manage the size of the buffer and reallocate it when you need more memory for any particular operation.
So, for example, if you call Append() on a RBuf object for which there is insufficient memory available, a panic will occur – the RBuf object will not automatically reallocate the buffer. This should be clear from the fact that the base class methods are non-leaving, that is, there is no scope for the reallocation to fail in the event of low memory.
So you still need to manage the memory for descriptor operations that may need to extend the descriptor.
The RBuf class was first introduced in Symbian OS v8.0, but first documented in the 8.1 SDK and is used extensively in software written for devices based on v9.x. The RBuf class is ideal for handling HBufC using a stack-based R class object, and may often be preferable to the contortions required to modify an HBufC.
I've created a short example of how to use the class in 33. Can you give an example of how to use RBuf?
I'd like to acknowledge JP's help and advice with this post.
RBuf16
16-bit resizable buffer descriptor [Jo comments - an equivalent 8-bit version, RBuf8, also exists]
The class provides a buffer that contains, accesses and manipulates TUint16 data. The buffer itself is on the heap, and is managed by the class.
Internally, RBuf16 behaves in one of two ways:
* as a TPtr16 descriptor type, where the buffer just contains data,
* as a pointer to a heap descriptor, an HBufC16* type, where the buffer contains both descriptor information and the data.
Note that the handling of the distinction is hidden from view.
An RBuf16 object can allocate its own buffer. Alternatively, it can take ownership of a pre-existing section of allocated memory, or it can take ownership of a pre-existing heap descriptor. It can also reallocate the buffer to resize it. Regardless of the way in which the buffer has been allocated, the RBuf16 object is responsible for freeing memory when the object itself is closed.
The class is intended for instantiation.
The class is derived from TDes16, which means that data can be both accessed and modified. The base classes provide the functions through which the data is accessed. In addition, an RBuf16 object can be passed to any function that is prototyped to take a TDes16 or a TDesC16 type.
So what does this mean for me?
An RBuf object is rather like an HBufC in that it can be created dynamically by specifying the maximum length required. However, it also benefits from being modifiable, since it derives from TDes16. This means that you don’t have to create a TPtr around the data in order to modify it, which makes it preferable to HBufC when you know you need to dynamically allocate a descriptor, and later modify it.
You don’t need to worry too much about how it’s represented internally – either as a TPtr or HBufC. In fact, all you need to know is how to create and destroy an RBuf, because calling the other descriptor operations on it should be second nature, given that you have access to all the base class methods of TDes16 and TDes16C.
But you must remember that, although RBuf manages the descriptor buffer by freeing it when you call Close(), it doesn’t manage the size of the buffer and reallocate it when you need more memory for any particular operation.
So, for example, if you call Append() on a RBuf object for which there is insufficient memory available, a panic will occur – the RBuf object will not automatically reallocate the buffer. This should be clear from the fact that the base class methods are non-leaving, that is, there is no scope for the reallocation to fail in the event of low memory.
So you still need to manage the memory for descriptor operations that may need to extend the descriptor.
The RBuf class was first introduced in Symbian OS v8.0, but first documented in the 8.1 SDK and is used extensively in software written for devices based on v9.x. The RBuf class is ideal for handling HBufC using a stack-based R class object, and may often be preferable to the contortions required to modify an HBufC.
I've created a short example of how to use the class in 33. Can you give an example of how to use RBuf?
I'd like to acknowledge JP's help and advice with this post.