The InsertL()
function provides a means of writing data
into a buffer, and expanding it as necessary. When the kind of data to be
inserted cannot be predicted in advance, this is the best technique to use. An
example of this situation would be entering characters into a word processor
document in response to user keystrokes.
In cases where the data to be inserted into a buffer is known in
advance — typically, when restoring from a file or stream
store — it is better to pre-expand the buffer to be able to
contain the data, and then Write()
into the expanded region of the
buffer:
In the following example the buffer is allocated and primed with some
data. Then ExpandL()
is used to insert 16 uninitialised bytes into
the buffer after position 6. The buffer is now 28 bytes long. Then, data is
written into this gap using Write()
, which cannot leave.
//
// Allocate buffer
//
CBufBase* buf=CBufSeg::NewL(4);
CleanupStack::PushL(buf);
//
// Put some text in
//
_LIT8(KHelloWorld,"Hello world!");
buf->InsertL(0,KHelloWorld);
//
// Reserve space for 16 X 8-bit chars
//
buf->ExpandL(6,16); // <- this can fail
writeBuf(buf);
//
// Now insert only 16 characters
//
TText8 c='a'; // character to insert
for (TInt i=0; i<16; i++, c++)
{
buf->Write(i+6, &c, 1); // write a char in - cannot fail
}
writeBuf(buf);
//
// Now adjust size down to 18
//
buf->ResizeL(18);
writeBuf(buf);
//
// Destroy buffer
//
CleanupStack::PopAndDestroy();
There are two advantages to replacing a large number of
InsertL()
s with a single ExpandL()
followed by many
Write()
s:
each InsertL()
may call the allocator to expand the
dynamic buffer, and may cause data beyond the insertion point to be shuffled
up: using a single ExpandL()
results in minimal calls to the
allocator, and only a single shuffle
the Write()
operations cannot leave: therefore, once
a buffer has been successfully expanded to the right size, the writes are
guaranteed to work: this is useful in some circumstances