Class
MemoryBlock
Description
A MemoryBlock object allocates a sequence of bytes in memory and manipulates those bytes directly. A MemoryBlock can be passed in place of a Ptr when used in a Declare call.
Properties
Name |
Type |
Read-Only |
Shared |
---|---|---|---|
Methods
Name |
Parameters |
Returns |
Shared |
---|---|---|---|
offset As Integer |
|||
offset As Integer |
|||
level As CompressionLevels = MemoryBlock.CompressionLevels.Normal |
MemoryBlock |
||
bytes As Integer |
|||
data As String |
|||
source As MemoryBlock, offset As Integer, length As Integer, Optional targetOffset As Integer = 0 |
|||
offset As Integer |
|||
offset As Integer |
|||
MemoryBlock |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
bytes As Integer |
MemoryBlock |
||
offset As Integer |
|||
offset As Integer |
MemoryBlock |
||
MemoryBlock |
|||
value As MemoryBlock |
MemoryBlock |
||
value As MemoryBlock |
|||
value As Ptr |
|||
value As String |
|||
offset As Integer |
|||
offset As Integer |
MemoryBlock |
||
bytes As Integer |
MemoryBlock |
||
offset As Integer |
|||
offset As Integer, length As Integer, encoding As TextEncoding = Nil |
|||
offset As Integer, length As Integer, Assigns value As String |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
offset As Integer |
|||
Enumerations
MemoryBlock.CompressionLevels
CompressionLevels
Specifies the type amount of compression to be used based upon the speed of the compression. This is used with the Compress method.
Enum
Description
Normal
A medium level of compression which is also the default.
None
No compression is applied.
Fast
A small amount of compression but also the fastest as a result.
Best
The most compression possible which also takes the longest.
Constants
The following class constant is returned by Size when the size of the MemoryBlock cannot be determined.
Class Constant
Description
SizeUnknown
The size of the MemoryBlock cannot be determined.
Property descriptions
MemoryBlock.LittleEndian
LittleEndian As Boolean
Sets the endianness of a MemoryBlock. The default is the endianness of the platform on which the code is being compiled.
All current CPU targets (x86-32, x86-64, ARM-32, ARM-64) default to LittleEndian = True.
Var mb1 As New MemoryBlock(2) ' currently Little Endian = True on all platforms mb1.Int8Value(0) = 1 mb1.Int8Value(1) = 2 Var firstUInt16 As Int16 firstUInt16 = mb1.UInt16Value(0) ' firstUInt16 = (256 * 2) + (1 * 1) = 513 mb1.LittleEndian = False Var secondUInt16 As Int16 secondUInt16 = mb1.UInt16Value(0) ' secondUInt16 = (256 * 1) + (1 * 2) = 258
MemoryBlock.Size
Size As Integer
The size of the MemoryBlock in bytes.
If you assign a value to this property, the MemoryBlock is resized, retaining as much of the existing data as possible.
MemoryBlock has a class constant, SizeUnknown (Integer), whose value is -1. Size returns SizeUnknown when the MemoryBlock is of unknown size. You can get this condition with Declare statements. Also, Ptr returns a MemoryBlock with an unspecified, so it sets Size to -1; however, the MemoryBlock can still be used to access the data that is stored in the MemoryBlock.
Method descriptions
MemoryBlock.BooleanValue
BooleanValue(offset As Integer) As Boolean
BooleanValue(offset As Integer, Assigns value As Boolean)
Gets and sets boolean (True/False) values.
0 is False while any non-zero value is True. offset is in bytes from the beginning of the MemoryBlock.
This example sets a byte in the MemoryBlock and then reads it.
Var mm As New MemoryBlock(4) mm.BooleanValue(0) = True If mm.BooleanValue(0) Then MessageBox("True") End If
MemoryBlock.Byte
Byte(offset As Integer) As Integer
Byte(offset As Integer, Assigns value As Integer)
Gets or sets the passed byte value. Returns an integer. offset is in bytes from the beginning of the MemoryBlock.
The following code stores character byte values in a MemoryBlock and displays it as a String:
Var m As New MemoryBlock(12) m.Byte(0) = 72 m.Byte(1) = 101 m.Byte(2) = 108 m.Byte(3) = 108 m.Byte(4) = 111 m.Byte(5) = 32 m.Byte(6) = 87 m.Byte(7) = 111 m.Byte(8) = 114 m.Byte(9) = 108 m.Byte(10) = 100 m.Byte(11) = 33 Var hello As String = m.StringValue(0, m.Size) ' Hello World!
MemoryBlock.ColorValue
ColorValue(offset As Integer, bits As Integer) As Color
ColorValue(offset As Integer, bits As Integer, Assigns value As Color)
Gets or sets a Color in one of three formats, selected by bits.
bits can take on the following values:
Value
Description
32
32-bit color (high byte unused)
24
24-bit color
16
16-bit color (5 bits per color, high bit unused)
Returns a Color. offset is in bytes from the beginning of the MemoryBlock.
This example stores a color in a MemoryBlock and then accesses it.
Var c As Color Var m As New MemoryBlock(4) m.ColorValue(0, 32) = &c43A245 c = m.ColorValue(0, 32)
MemoryBlock.Compress
Compress(level As CompressionLevels = MemoryBlock.CompressionLevels.Normal) As MemoryBlock
Returns a compressed copy of the MemoryBock at the compression level passed.
MemoryBlock.Constructor
Constructor(bytes as Integer)
Note
Constructors are special methods called when you create an object with the New keyword and pass in the parameters above.
Creates a new MemoryBlock with the size specified in bytes.
For 32-bit apps, you can request a maximum of about 2 to 3 GB depending on the OS. Generally Windows is closer to 2GB and macOS/Linux are closer to 3GB. There is no practical limit for 64-bit apps.
The following example reads a real number into a memory block and then displays it:
Var m As New MemoryBlock(4) Var d As Single m.SingleValue(0) = 123.456 d = m.SingleValue(0) MessageBox(d.ToString)The following example stores a string in a MemoryBlock and displays it:
Var m As New MemoryBlock(13) m.Byte(0) = 12 m.Byte(1) = 72 m.Byte(2) = 101 m.Byte(3) = 108 m.Byte(4) = 108 m.Byte(5) = 111 m.Byte(6) = 32 m.Byte(7) = 87 m.Byte(8) = 111 m.Byte(9) = 114 m.Byte(10) = 108 m.Byte(11) = 100 m.Byte(12) = 33 MessageBox(m.PString(0))
MemoryBlock.Constructor
Constructor(data as String)
Creates a MemoryBlock from the data passed.
Important
This signature is supported for Android only.
MemoryBlock.CopyBytes
CopyBytes(source As MemoryBlock, offset As Integer, length As Integer, Optional targetOffset As Integer = 0)
Copies length bytes from the source MemoryBlock starting at offset to targetOffset.
MemoryBlock.CString
CString(offset As Integer) As String
CString(offset As Integer, Assigns value As String)
Returns a String. offset is in bytes from the beginning of the MemoryBlock.
A CString is a sequence of non-zero bytes followed by a terminating Chr(0) that marks the end of the CString. MemoryBlock.CString returns a String consisting of the non-zero bytes beginning at offset and ending before the terminating 0 byte.
When setting MemoryBlock.CString, one extra byte of space is needed for the CString terminator. Thus, for example, when setting the CString property of a MemoryBlock to a 15-byte string, 16 bytes of the MemoryBlock are actually set.
Var m As New MemoryBlock(16) m.CString(0) = "Ecce quam bonum"This example shows how to add the terminating null if the string doesn't already have it. It uses the string that was constructed in the Byte example.
Var m As New MemoryBlock(14) m.Byte(0) = 12 ' length byte for a PString m.Byte(1) = 72 m.Byte(2) = 101 m.Byte(3) = 108 m.Byte(4) = 108 m.Byte(5) = 111 m.Byte(6) = 32 m.Byte(7) = 87 m.Byte(8) = 111 m.Byte(9) = 114 m.Byte(10) = 108 m.Byte(11) = 100 m.Byte(12) = 33 MessageBox(m.PString(0)) ' To read the string using CString, set the terminating byte before the call. m.Byte(13) = 0 MessageBox(m.CString(1)) ' Skip first value which is the length for the String
MemoryBlock.CurrencyValue
CurrencyValue(offset As Integer) As Currency
CurrencyValue(offset As Integer, Assigns value As Currency)
MemoryBlock.Decompress
Decompress As MemoryBlock
Returns a copy of the MemoryBlock with no compression applied.
MemoryBlock.DoubleValue
DoubleValue(offset As Integer) As Double
DoubleValue(offset As Integer, Assigns value As Double)
Gets or sets a Double value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a double value and then accesses it.
Var d As Double Var m As New MemoryBlock(8) m.DoubleValue(0) = 3.14159265358979323846264338327950 d = m.DoubleValue(0)
MemoryBlock.Int16Value
Int16Value(offset As Integer) As Int16
Int16Value(offset As Integer, Assigns value As Int16)
MemoryBlock.Int32Value
Int32Value(offset As Integer) As Int32
Int32Value(offset As Integer, Assigns value As Int32)
Gets or sets an Int32 value. offset is in bytes from the beginning of the MemoryBlock.
This example sets a 32-bit integer and then accesses it.
Var i As Int32 Var m As New MemoryBlock(4) m.Int32value(0) = 256495 i = m.Int32Value(0)
MemoryBlock.Int64Value
Int64Value(offset As Integer) As Int64
Int64Value(offset As Integer, Assigns value As Int64)
Gets or sets an Int64 value. offset is in bytes from the beginning of the MemoryBlock.
This example sets a 64-bit integer and then accesses it.
Var i As Int64 Var m As New MemoryBlock(8) m.Int64value(0) = 256495900 i = m.Int64Value(0)
MemoryBlock.Int8Value
Int8Value(offset As Integer) As Int8
Int8Value(offset As Integer, Assigns value As Int8)
Gets or sets an Int8 value. offset is in bytes from the beginning of the MemoryBlock.
MemoryBlock.LeftB
LeftB(bytes As Integer) As MemoryBlock
Returns a new MemoryBlock of the specified size using the same endianness as the source MemoryBlock.
This example uses LeftB to set the value of a new MemoryBlock.
Var m As New MemoryBlock(8) m.Int64value(0) = 256495900 Var n As New MemoryBlock(8) n = m.LeftB(8)
MemoryBlock.Long
Long(offset As Integer) As Integer
Long(offset As Integer, Assigns value As Integer)
Gets or sets an Integer, four bytes in length. offset is in bytes from the beginning of the MemoryBlock.
Equivalent to Int32Value, which you should use instead.
MemoryBlock.MidB
MidB(offset As Integer) As MemoryBlock
MidB(offset As Integer, length As Integer) As MemoryBlock
Returns a new MemoryBlock of the specified size using the same endianness as the source MemoryBlock. Offset is in bytes from the beginning of the MemoryBlock.
This example extracts two bytes from a MemoryBlock.
Var m As New MemoryBlock(12) . . Var n As New MemoryBlock(4) n = m.MidB(1, 2)
MemoryBlock.Operator_Add
Operator_Add(value As MemoryBlock) As MemoryBlock
MemoryBlock.Operator_Compare
Operator_Compare(value As MemoryBlock) As Integer
Defines the following comparison operators for the MemoryBlock class: =, <, >, <=, >=, <>. It compares the passed MemoryBlock to the Self instance.
Operator_Compare returns an integer whose meaning is as follows: < 0 means that Self is less than the passed parameter, 0 means that Self is equal to the passed parameter, and > 0 means that Self is greater than the passed parameter.
MemoryBlock.Operator_Convert
Operator_Convert As Ptr
Converts a MemoryBlock to a Ptr.
Operator_Convert As String
Converts a MemoryBlock to a String.
Operator_Convert(value As Ptr)
Converts a Ptr to a MemoryBlock.
Important
This method is not supported for Android.
Operator_Convert(value As String)
Converts a String to a MemoryBlock.
MemoryBlock.PString
PString(offset As Integer) As String
PString(offset As Integer, Assigns value As String)
Gets or sets a String, up to 255 characters. The first byte is the length of the string. offset is in bytes from the beginning of the MemoryBlock.
Important
This method is not supported for Android.
The following example stores a string in a MemoryBlock and displays it:
Var m As New MemoryBlock(13) m.Byte(0) = 12 m.Byte(1) = 72 m.Byte(2) = 101 m.Byte(3) = 108 m.Byte(4) = 108 m.Byte(5) = 111 m.Byte(6) = 32 m.Byte(7) = 87 m.Byte(8) = 111 m.Byte(9) = 114 m.Byte(10) = 108 m.Byte(11) = 100 m.Byte(12) = 33 MessageBox(m.PString(0))
MemoryBlock.Ptr
Ptr(offset As Integer) As MemoryBlock
Ptr(offset As Integer, Assigns value As MemoryBlock)
Gets or sets a MemoryBlock at the specified offset. offset is in bytes from the beginning of the MemoryBlock.
If the MemoryBlock's size is not known, then the MemoryBlock this returns will also have an unknown (-1) size, although it can still be used to access its data.
MemoryBlocks automatically convert to Ptr.
Important
This method is not supported for Android.
This code converts a MemoryBlock to a Ptr:
Var p As Ptr = mbThis code retrieves another MemoryBlock (within the original MemoryBlock) at the specified offset and converts it to a Ptr:
Var p As Ptr = mb.Ptr(n)This example stores a Ptr to a MemoryBlock property. If the MemoryBlock property goes out of scope, the Ptr will be invalid when retrieved.
MBProperty = New MemoryBlock(8) MBProperty.StringValue(0, 8) = "a string" Var mb As New MemoryBlock(8) Var p As Ptr = MBProperty mb.Ptr(0) = pBecause of implicit conversion between a Ptr and MemoryBlock, this can be shortened.
Var mb As New MemoryBlock(4) mb.Ptr(0) = MBPropertyThis code will retrieve the MemoryBlock later.
Var mb1 As MemoryBlock = mb.Ptr(0) ' Size will be unknown (-1) Var s As String = mb1.StringValue(0, 8)This code will store a Ptr to two methods.
Var mb As New MemoryBlock(8) mb.Ptr(0) = AddressOf someMethod mb.Ptr(4) = AddressOf someOtherMethod
MemoryBlock.RightB
RightB(bytes As Integer) As MemoryBlock
Returns a new MemoryBlock of the specified size using the same endianness as the source MemoryBlock.
This example uses RightB to set the value of a new MemoryBlock.
Var m As New MemoryBlock(8) m.Int64value(0) = 256495900 Var n As New MemoryBlock(8) n = m.RightB(8)
MemoryBlock.SingleValue
SingleValue(offset As Integer) As Double
SingleValue(offset As Integer, Assigns value As Double)
Gets or sets a 4-byte representation of a single-precision floating number as a Double. offset is in bytes from the beginning of the MemoryBlock.
The following example sets a value in a MemoryBlock using Single and then gets it.
Var d As Double Var m As New MemoryBlock(8) m.SingleValue(0) = 256 d = m.SingleValue(0)
MemoryBlock.StringValue
StringValue(offset As Integer, length As Integer, encoding As TextEncoding = Nil) As String
StringValue(offset As Integer, length As Integer, Assigns value As String)
Gets or sets a String of arbitrary size; it may contain nulls, and is not prefixed with a length byte.
When setting, if length is greater than the length of the string, it is padded with zeros. offset is in bytes from the beginning of the MemoryBlock.
This example sets a string and then reads it back.
Var s As String Var m As New MemoryBlock(8) m.StringValue(0, 2) = "Ha" s = m.StringValue(0, 2)
MemoryBlock.UInt16Value
UInt16Value(offset As Integer) As UInt16
UInt16Value(offset As Integer, Assigns value As UInt16)
MemoryBlock.UInt32Value
UInt32Value(offset As Integer) As UInt32
UInt32Value(offset As Integer, Assigns value As UInt32)
MemoryBlock.UInt64Value
UInt64Value(offset As Integer) As UInt64
UInt64Value(offset As Integer, Assigns value As UInt64)
MemoryBlock.UInt8Value
UInt8Value(offset As Integer) As UInt8
UInt8Value(offset As Integer, Assigns value As UInt8)
MemoryBlock.WString
WString(offset As Integer) As String
WString(offset As Integer, Assigns value As String)
Allows you to get or set null-terminated WStrings (UTF-16 strings) in a MemoryBlock. offset is in bytes from the beginning of the MemoryBlock. The String returned by MemoryBlock.WString has encoding UTF-16.
Important
This method is not supported for Android.
Notes
MemoryBlocks can be used whenever you need a container for any arbitrary binary data.
MemoryBlocks are used when accessing entry points in shared libraries and when making OS calls using the Declare function.
MemoryBlocks supports creating a zero-length MemoryBlock.
For 32-bit apps, you can request a maximum of about 2 to 3 GB depending on the OS. Generally Windows is closer to 2GB and Mac/Linux are closer to 3GB. There is no practical limit for 64-bit apps.
The contents of a MemoryBlock can be viewed in the Debugger.
You can initialize a MemoryBlock from a string without using the constructor and declaring its size. For example, the following initializes a MemoryBlock from a String.
Var s As String = "abcde"
Var mb As MemoryBlock
mb = s
MessageBox(mb.Size.ToString) ' displays 5
You can convert this MemoryBlock back to a String with an assignment statement or a call that accepts a string. This statement converts the MemoryBlock back to a String.
Var a As String
a = mb
You can also pass this MemoryBlock to a function that expects a String. For example:
MessageBox(mb) ' displays "abcde"
OutOfBoundsExceptions with StringValue
Accessing invalid StringValues can raise an OutOfBoundsException.
Accessing a MemoryBlock.StringValue with a size less than 0:
Var mb As New MemoryBlock(0)
Var s As String = mb.StringValue(5, -1) ' OutOfBounds because size < 0
You will also get an OutOfBoundsException if the StringValue length is less than 0.
Sample code
The Faster String Appending with MemoryBlock project (included with Xojo in: Examples/Language/) uses MemoryBlocks to append two strings together as fast as possible. The main window has two TextFields, a Button, and a Label for displaying the result.
The user enters strings into the TextFields and clicks the Button. The Pressed
event for the Button is the following:
Var m As MemBlockString
' create a New memBlockString
m = New MemBlockString
' add the strings into the memBlockString
m.AppendString(TextField1.Text)
m.AppendString(TextField2.Text)
' retreive the string
Label1.Text = m.GetString
The MemBlockString object is a custom class. It has the properties:
The constructor is:
' This is a class to use a memoryBlock as a temporary buffer
' while creating long strings by appending to already existing
' strings. It can be a lot quicker than s = s + "more text" if
' you have very long strings
' This is both the size of the original memoryBlock
' but also how much it increases by each time if needed
BufferSize = 100000 ' bigger than really needed
mb = New MemoryBlock(BufferSize)
TotalLength = BufferSize
The appendString method is called in the DesktopButton's Pressed
event:
Sub AppendString(s As String)
#Pragma DisableBackgroundTasks
Var l As Integer
l = s.Length
mb.StringValue(length, l) = s
length = length + l
Exception
' If we write beyond the end of the memoryBlock we need to replace it with a newer ' bigger one
TotalLength = TotalLength + bufferSize
mb.Size = TotalLength
mb.StringValue(length, l) = s
length = length + l
Finally, the Pressed
event handler calls getString to assign the appended string to the text property of the DesktopLabel.
Sub GetString() As String
#Pragma DisableBackgroundTasks
Return mb.StringValue(0, length)
The following example reads a real number into a memory block and then displays it:
Var m As New MemoryBlock(4)
Var d As Single
m.SingleValue(0) = 123.456
d = m.SingleValue(0)
MessageBox(d.ToString)
The following example stores a string in a MemoryBlock and displays it:
Var m As New MemoryBlock(13)
m.Byte(0) = 12
m.Byte(1) = 72
m.Byte(2) = 101
m.Byte(3) = 108
m.Byte(4) = 108
m.Byte(5) = 111
m.Byte(6) = 32
m.Byte(7) = 87
m.Byte(8) = 111
m.Byte(9) = 114
m.Byte(10) = 108
m.Byte(11) = 100
m.Byte(12) = 33
MessageBox(m.PString(0))
To read the string using CString, add the terminating byte before the call, i.e.,
m.Byte(13) = 0
MessageBox(m.CString(1))
This example backs a BinaryStream with a MemoryBlock that is declared 0-sized:
Var mb As New MemoryBlock(0)
Var bs As New BinaryStream(mb)
bs.WriteInt32(4)
bs.WriteDouble(3.14)
bs.Close
MessageBox(mb.Long(0).ToString)
Compatibility
Project Types |
All |
Operating Systems |
All |
See also
Object parent class; BinaryStream class; Declare statement.