[Lazarus] Copy buffer of PWord to TMemoryStream

Sven Barth pascaldragon at googlemail.com
Sun Mar 24 19:46:09 CET 2013


On 24.03.2013 19:30, Leonardo M. Ramé wrote:
> On 2013-03-24 19:21:49 +0100, Sven Barth wrote:
>> On 24.03.2013 19:19, Joao Morais wrote:
>>> 2013/3/24 Leonardo M. Ramé <l.rame at griensu.com>:
>>>> Hi, I'm copying a buffer of PWord to a TMemoryStream using this code:
>>>>
>>>> lTmpBuff := lBuffer;
>>>> I := 0;
>>>> while I < lBufSize do
>>>> begin
>>>>    lStream.Write(lTmpBuff^, SizeOf(PWord));
>>>>    inc(lTmpBuff, 1);
>>>>    inc(I, 1);
>>>
>>> What about:
>>>
>>>     inc(lTmpBuff, SizeOf(PWord));
>>>     inc(I, SizeOf(PWord));
>>
>> If lTmpBuff is declared as PWord then "Inc" already increases in
>> multiplies of "SizeOf(PWord)".
>> Regarding lBufSize it will be important to know whether the C code
>> returns the size in elements or in byte.
>>
>
> Heres the interface of the library:
>
> myfunction(void * &buffer, unsigned long& bufSize)
> {
>      bufsize = interdata->getcount() * sizeof(uint16);

So bufsize contains the amount of Bytes.

>      buffer = new uint16[bufSize];

Ehm... shouldn't this be "new uint16[interdata->getcount()]"? Because 
currently if your "getcount()" function returns e.g. 42 you will 
allocate an array containing 84 elements...

>      // interdata is an object containing image data
>      memcpy((void *)buffer, interdata->getData(), interdata->getCount());
> }

So assuming that lBuffer is passed as the buffer argument and lBufSize 
as the bufSize one then your old code is wrong.

It should look like this:

=== code begin ===

I := 0;
while I < lBufSize do begin
   lStream.Write(lTmpBuffer^, SizeOf(Word)); // do you really have 
"SizeOf(PWord)" there?
   Inc(lTmpBuff); // move pointer by one element
   Inc(I, SizeOf(Word)); // we need to increase I by the element size
end;

=== code end ===

An alternative would be:

=== code begin ===

for I := 0 to lBufSize div SizeOf(Word) do
   lStream.Write(lBuffer[I], SizeOf(Word));

=== code end ===

And to finally write all data at once:

=== code begin ===

lStream.Write(lBuffer^, lBufSize); // as lBufSize is the byte size, this 
is correct without further multiplication

=== code end ===

Now if your C function is written correctly, all three should give you 
the same result.

Regards,
Sven




More information about the Lazarus mailing list