Setting bit in array of byte

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Setting bit in array of byte

Koenraad Lelong-2
Hi,
I have following code (almost literally translated from C) :
//--------------------------------------------------------------------------
// Bit utility to read and write a bit in the buffer 'buf'.
//
// 'op'    - operation (1) to set and (0) to read
// 'state' - set (1) or clear (0) if operation is write (1)
// 'loc'   - bit number location to read or write
// 'buf'   - pointer to array of bytes that contains the bit
//           to read or write
//
// Returns: 1   if operation is set (1)
//          0/1 state of bit number 'loc' if operation is reading
//
type
  PByteArray = ^array of byte;

function bitacc(op, state, loc : byte; buf : PByteArray) : byte;
{C-code : static SMALLINT bitacc(SMALLINT op, SMALLINT state, SMALLINT
loc, uchar *buf)}

var
  nbyt,
  nbit : byte;

begin

nbyt := loc div 8;
nbit := loc mod 8;
if (op = WRITE_FUNCTION) then
  begin
   if state=1 then
    buf^[nbyt] := buf^[nbyt] or ($01 << nbit)
   else
    buf^[nbyt] := buf^[nbyt] and not ($01 << nbit);
   result:=1;
  end
else
  result:=(buf^[nbyt] >> nbit) and $01;
end;

It's called with this code :

bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,@SerialNum[portnum][0]),
(i * 2 + 1), @sendpacket[pos])
{C-code :
bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
  (short)(i * 2 + 1), &sendpacket[pos]);}

Executing the code gives an an access violation exception. What am I
doing wrong ?
I included some debugging code and it seems accessing buf^[nbyt] is the
problem.

TIA
Koenraad Lelong.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Setting bit in array of byte

Michalis Kamburelis
Koenraad Lelong wrote:

> Hi,
> I have following code (almost literally translated from C) :
> //--------------------------------------------------------------------------
>
> // Bit utility to read and write a bit in the buffer 'buf'.
> //
> // 'op'    - operation (1) to set and (0) to read
> // 'state' - set (1) or clear (0) if operation is write (1)
> // 'loc'   - bit number location to read or write
> // 'buf'   - pointer to array of bytes that contains the bit
> //           to read or write
> //
> // Returns: 1   if operation is set (1)
> //          0/1 state of bit number 'loc' if operation is reading
> //
> type
>  PByteArray = ^array of byte;
>

"array of byte" is a dynamic array. It's a pointer, to data and to some
internal fields. "^array of byte" is a pointer to a pointer to data. You
don't want this.

What you probably want is something like

type
    TByteArray = array[0..MaxInt - 1] of Byte;
    PByteArray = ^TByteArray;

Actually this should be already defined somewhere in the RTL (SysUtils
unit, or maybe even in System) so you should just omit declaring
PByteArray type yourself and all should be OK.

> function bitacc(op, state, loc : byte; buf : PByteArray) : byte;
> {C-code : static SMALLINT bitacc(SMALLINT op, SMALLINT state, SMALLINT
> loc, uchar *buf)}
>
> var
>  nbyt,
>  nbit : byte;
>
> begin
>
> nbyt := loc div 8;
> nbit := loc mod 8;
> if (op = WRITE_FUNCTION) then
>  begin
>   if state=1 then
>    buf^[nbyt] := buf^[nbyt] or ($01 << nbit)
>   else
>    buf^[nbyt] := buf^[nbyt] and not ($01 << nbit);
>   result:=1;
>  end
> else
>  result:=(buf^[nbyt] >> nbit) and $01;
> end;
>
> It's called with this code :
>
> bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,@SerialNum[portnum][0]),
> (i * 2 + 1), @sendpacket[pos])
> {C-code :
> bitacc(WRITE_FUNCTION, bitacc(READ_FUNCTION,0,i,&SerialNum[portnum][0]),
>  (short)(i * 2 + 1), &sendpacket[pos]);}
>
> Executing the code gives an an access violation exception. What am I
> doing wrong ?
> I included some debugging code and it seems accessing buf^[nbyt] is the
> problem.
>
> TIA
> Koenraad Lelong.
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Setting bit in array of byte

Koenraad Lelong-3
Michalis Kamburelis wrote:
> Koenraad Lelong wrote:
>
...

> "array of byte" is a dynamic array. It's a pointer, to data and to some
> internal fields. "^array of byte" is a pointer to a pointer to data. You
> don't want this.
>
> What you probably want is something like
>
> type
>    TByteArray = array[0..MaxInt - 1] of Byte;
>    PByteArray = ^TByteArray;
>
> Actually this should be already defined somewhere in the RTL (SysUtils
> unit, or maybe even in System) so you should just omit declaring
> PByteArray type yourself and all should be OK.
>
...
Thanks, that's the solution, it works now. Those types are defined in
sysutils.
Regards,
Koenraad Lelong.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal