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 |
|||
MemoryBlock |
|||
value As MemoryBlock |
MemoryBlock |
||
Offset As Integer |
|||
Offset As Integer |
|||
Bytes As Integer |
MemoryBlock |
||
Offset As Integer |
|||
Offset As Integer, Length As Integer, Optional Encoding As TextEncoding = Nil |
|||
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
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
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
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
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
Gets or sets a Currency value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a Currency value and then accesses it.
Var c As Currency
Var m As New MemoryBlock(8)
m.CurrencyValue(0) = 34.54
c = m.CurrencyValue(0)
MemoryBlock.Decompress
Decompress As MemoryBlock
Returns a copy of the MemoryBlock with no compression applied.
MemoryBlock.DoubleValue
DoubleValue(Offset As Integer) 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
Gets or sets an Int16 value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets an Int16 value and then accesses it.
Var i As Int16
Var m As New MemoryBlock(2)
m.Int16value(0) = 34
i = m.Int16Value(0)
MemoryBlock.Int32Value
Int32Value(Offset As Integer) 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
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
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
Returns 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, [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
Overloads the + operator for the MemoryBlock class, providing a way to add the passed MemoryBlock to the Self instance. Returns the result as a MemoryBlock.
MemoryBlock.Operator_Compare
Operator_Compare 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.
MemoryBlock.PString
PString(Offset As Integer) As String
Returns 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
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 = mb
This 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) = p
Because of implicit conversion between a Ptr and MemoryBlock, this can be shortened.
Var mb As New MemoryBlock(4)
mb.Ptr(0) = MBProperty
This 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
Returns 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, Optional Encoding As TextEncoding = Nil) As String
Gets and 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
Gets or sets a UInt16 value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a UInt16 in a MemoryBlock and accesses it.
Var i As UInt16
Var m As New MemoryBlock(8)
m.UInt16Value(0) = 15
i = m.UInt16Value(0)
MemoryBlock.UInt32Value
UInt32Value(Offset As Integer) As UInt32
Gets or sets a UInt32 value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a UInt32 value in a MemoryBlock and then accesses it.
Var i As UInt32
Var m As New MemoryBlock(4)
m.UInt32Value(0) = 48000
i = m.UInt32Value(0)
MemoryBlock.UInt64Value
UInt64Value(Offset As Integer) As UInt64
Gets or sets a UInt64 value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a UInt64 in a MemoryBlock and then accesses it.
Var i As UInt64
Var m As New MemoryBlock(8)
m.UInt64Value(0) = 48000
i = m.UInt64Value(0)
MemoryBlock.UInt8Value
UInt8Value(Offset As Integer) As UInt8
Gets or sets a UInt8 value. Offset is in bytes from the beginning of the MemoryBlock.
This example sets a UInt8 to a MemoryBlock and then accesses it.
Var i As UInt8
Var m As New MemoryBlock(1)
m.UInt8Value(0) = 6
i = m.UInt8Value(0)
MemoryBlock.WString
WString(Offset As Integer) As String
Allows you to get and 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. Examples include:
Accessing a MemoryBlock StringValue with a size of 0:
Var mb As New MemoryBlock(0)
Var s As String = mb.StringValue(0, 0) ' OutOfBounds because size = 0
Accessing a MemoryBlockStringValue 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
All project types on all supported operating systems.
See also
Object parent class; BinaryStream class; Declare statement.