Android Question What do I not get about an array

Woody

Member
Licensed User
Ok, here goes newbie....

Using the Bluetooth.b4a example I'm able to talk to one of my BT devices. Commands go in, data comes out. That data consists mostly of messages of 7 bytes of sensor data but can also contain 6 bytes (a mac address and then maybe 20 bytes representing ascii characters. So I am trying to separate those from the stream.

From the (reworked) example:

B4X:
Private Sub AStream_NewData (Buffer() As Byte)
   
   Private temp(6) As Byte
   Private i As Int
   Log(Buffer(1))
   Log(conv.hexFromBytes(Buffer))
   
   If Buffer.Length = 7 Then
       'This is a message containing a battery charge value and sensor data
       'I can display these bytes using HexFromBytes
       CallSub2(ChatActivity, "NewMessage", conv.HexFromBytes(Buffer))
   Else
       For i = 0 To 5
           temp(i) = Buffer(i)   
       Next
       'This line displays the mac address of the device
       CallSub2(ChatActivity, "NewMessage", conv.HexFromBytes(temp))       
       'and the next line displays the ascii part of the message (program name and version).
       CallSub2(ChatActivity, "NewMessage", BytesToString(Buffer, 6, Buffer.Length-6, "UTF8"))
   End If
   
End Sub

Above code works. What I do not understand is if I do not initialize the size of the temp var (like temp()) this breaks when I try to fill it with an out-of-bounds exception. But the Buffer() var, which is also not initialized with a size, does not break. What is the difference?

And another thing, how do I get a single Hex byte from the Buffer() array? HexFromBytes(Buffer(1)) does not work.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Above code works. What I do not understand is if I do not initialize the size of the temp var (like temp()) this breaks when I try to fill it with an out-of-bounds exception. But the Buffer() var, which is also not initialized with a size, does not break. What is the difference?

B4X:
Dim temp() As Byte
'is the same as:
Dim temp(0) As Byte
It declares an empty array.

This is not the same as:
B4X:
AStream_NewData (Buffer() As Byte)
We are not creating a new array here. The sub expects an array of bytes as parameter. The array was created somewhere else.

BTW, your code is wrong. You shouldn't assume that the buffer length is 6. Messages can be split or merged. Worth watching this video:

 
Upvote 0

Woody

Member
Licensed User
So if I understand this right, Buffer() is not an array? How come I'm able to do

B4X:
log(Buffer(1))

then? That is addressing the second value in an array?

I do not see Buffer() being created (or used) outside the code snippet above.

Point taken about the buffer length; that would be silly in a real app.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

Woody

Member
Licensed User
Then I'm still confused. Where is Buffer() created, if not inside the

B4X:
Private Sub AStream_NewData (Buffer() As Byte)

line? And why is there a difference in how I can use Buffer() and temp()? AStream_NewData fills the zero sized buffer() without problem, if I try the same with the temp() array I get an out-of-bounds error.

Somewhere I miss an important piece of information :)
 
Upvote 0

Woody

Member
Licensed User
BTW, your code is wrong. You shouldn't assume that the buffer length is 6. Messages can be split or merged. Worth watching this video:

I re-watched this video. In the beginning it tells me that using the Prefix mode makes sure I only get complete messages. So no split or merged messages. In my case I use prefix mode, and messages are least 7 bytes long. So can I assume that the buffer will always be at least 7 bytes or do I still need to take into account that messages could be split or merged?
 
Upvote 0

Woody

Member
Licensed User
The data are NOT created in this sub. You can use the data to know what you got from the Stream.

PLease explain what you mean by this. This might be what I do not get.

What I understand is that the input stream stuffs the data in the Buffer() array. Is that correct?
 
Upvote 0

Woody

Member
Licensed User
:) I'm not trying to be a smart-ass

By 'stuffs' I mean, puts the data it received from the BT link into the Buffer() array. Whenever the NewData event is raised and the sub is executed, I am able to read the data from Buffer(). The packets received are either 7 bytes or 26 bytes, depending on the command I sent to de BT device earlier.

My confusion is that I cannot store any data in temp() for it is 0 length. However, the NewData event can store data in buffer(). They seem to be initialized the same:

B4X:
Private Sub AStream_NewData (Buffer() As Byte)
Private temp() As Byte
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
the sub is executed, I am able to read the data from Buffer().
right
B4X:
Private Sub AStream_NewData (Buffer() As Byte)
temp = Buffer
end sub
NOW you can use Temp.
If you want to ADD Buffer to Temp then you should use the BytesBuilder Class
 
Last edited:
Upvote 0

Woody

Member
Licensed User
Ah, so. It does not solve my initial problem for if I now execute
B4X:
CallSub2(ChatActivity, "NewMessage", conv.HexFromBytes(temp))
it (obviously) prints all of temp() and not only the first 6 bytes, but it does help me in understanding how arrays are used. Apparently zero length arrays can be filled with other arrays of various sizes but not with individual bytes, because you cannot address those bytes in a zero length array.

I want parts of buffer() to end up in other variables like ints so I will look into the ByteBuilder class as you suggested. First need to figure out how to use a class then :)

Thank you for your time and patience!
 
Upvote 0

Similar Threads

Top