User Tools

Site Tools


buffer-type

buffer type

A buffer type is a general memory buffer with a fixed size that must be specified while declared using the dim statement:

dim buffer: byte * 16;

The four buffer types are:

  1. byte (1 byte)
  2. word (2 bytes)
  3. dword (4 bytes)
  4. qword (8 bytes)

The next two declarations both create a memory buffer of 2048 bytes:

dim bdata: byte * 2048;
dim qdata: qword * 256;

assignment

Buffers can be assigned directly through the assignment statement, similar to string assignment, but without the need to convert the data type:

dim name: byte * 32;
dim age: byte * 1;

main do

  name = "John";
  age = 65;

end

Similarly, buffers can be assigned to variables of different data types, such as integer and string directly, without conversion, whereby the “best fit” rule applies:

' SharpBASIC buffer assignment programming example
' ------------------------------------------------
option strict;

incl "lib/sys.sbi";

dim b: byte * 24;
dim s: str;
dim n: uint8;

main do
  ' clear buffer
  clbuf(b);
  ' assign immediate string to buffer
  b = "SharpBASIC is here!";
  ' assign buffer to variable length string
  s = b;
  ' print string
  print(s);
  ' assign buffer to uint8 (size = 1 byte)
  n = b;
  ' print n (n = 83 for ascii 'S')
  print(n);
end
Output:

SharpBASIC is here!

83


But keep in mind that buffers are not strings; they do not have a descriptor, nor are they null-terminated. They are simply a predefined block of memory with a fixed size. But the SharpBASIC compiler does manage memory for buffer types and their memory is deallocated automatically, similar to string data types.

conversion

While buffers can assign or be assigned to directly, there are special functions that make working with buffers easier, such as writing data to and reading from a buffer at a specific offset. See also clbuf, cbuf, pbuf.

Keep in mind that when a buffer is declared, it is not automatically initialized (cleared) and will contain whatever data is present in the assigned memory area. Therefore, it is important to clear/initialize a buffer before using it.

' SharpBASIC convert string to buffer programming example
' -------------------------------------------------------
incl "lib/sys.sbi";

' declare a string and a buffer
dim text: str;
dim buffer: byte * 16;
dim size: uint;

main do

  ' clear buffer
  clbuf(buffer);

  ' define the string
  text = "A new BASIC";
  size = len(text);
  
  ' convert string to buffer, position at offset 5
  buffer = cbuf(text, 5);

  ' buffers can be printed
  print(buffer);
  
  ' get string from buffer
  text = pbuf(buffer, 5, size);
  
  ' clear buffer again
  clbuf(buffer);
  
end
Output (dots indicate spaces):

…..A new BASIC


direct memory access

Buffers can be manipulated directly through memory access using pointers. For instance, the procedure cpmem can be used to copy data to a buffer:

' SharpBASIC copy string to buffer memory programming example
' -----------------------------------------------------------
option strict;

incl "lib/sys.sbi";

dim text_ptr, buffer_ptr: ptr;
dim buffer: byte * 24;
dim text: str * 11;
dim size: uint;

main do
    text = "A new BASIC";
    print(text);
    print(len(text));  ' 11

    ' string descriptor
    text_ptr = aof(text);

    ' size of fixed-length string is in the descriptor
    size = bya(text_ptr + 4);

    ' string address (not descriptor)
    text_ptr = sadd(text);

    ' buffer address
    buffer_ptr = aof(buffer);

    ' copy string to buffer
    cpmem(text_ptr, buffer_ptr, size);

    print(buffer);
    print(len(buffer));  ' 24
end
Output:

A new BASIC

11

A new BASIC

24


Finally, an example of buffer manipulation through pointer arithmetic:

' SharpBASIC pointer arithmetic with buffers programming example
' --------------------------------------------------------------
incl "lib/sys.sbi";

dim bdata   : byte * 26;    ' 26 bytes buffer
dim s       : str * 26;     ' 26 bytes fixed length string
dim i, size : uint8;
dim pb, ps  : ptr;

main do

  ' buffer size
  size = len(bdata);

  ' buffer address
  pb = aof(bdata);

  ' populate buffer
  loop i = 0 do
    while i < size;
    stob(pb + i, 65 + i);
    i:++;
  end

  ' fixed length string address
  ps = sadd(s);

  ' copy buffer to string
  cpmem(pb, ps, size);

  ' print string
  print(s);

end
Output:

ABCDEFGHIJKLMNOPQRSTUVWXYZ


limitations

Function and subroutine parameters cannot be of type buffer, which means that buffers cannot be passed as parameters. A function cannot be of type buffer so buffers cannot be passed as a function result. But buffers can be declared and used inside procedures:

' SharpBASIC buffer subroutine programming example
' ------------------------------------------------
incl "lib/sys.sbi";

decl sub localBuffer();

main do
  call localBuffer;
end

sub localBuffer()
  dim b: byte * 16;
do
  b = "this is a buffer";
  print(b);
end
Output:

this is a buffer


When the procedure ends, buffer types are deallocated automatically.

While buffers cannot be used directly as parameters or function types, they can be encapsulated, for example by using records:

' SharpBASIC record function programming example
' ----------------------------------------------
incl "lib/sys.sbi";

record r_buffer is
  b: byte * 16;
end

decl func thisBuffer(s: str): r_buffer;

dim r: r_buffer;

main do
  r = thisBuffer("this is a buffer");
  print(r.b);
end

func thisBuffer(s: str): r_buffer
  dim r: r_buffer;
do
  r.b = s;
  thisBuffer = r;
end
Output:

this is a buffer

buffer-type.txt · Last modified: 2023/07/10 09:26 by admin