code_fodder
code_fodder

Reputation: 16341

How can I create and edit an array of binary data ready for serialization over UDP?

I am trying to figure out what storage classes there are that I can use in lua to create and manipulate binary data byte-by-byte.

For example Qt has QByteArray, or c++/c has array of char (or uint8_t). I don't feel that a string is going to work because I need to deal with values such as 0x00 and other non-printable chars. Also I looked into arrays, but they don't appear to have a type and I am not sure how to serialize them.

I am a bit stuck here, I will try to do a code example below:

local socket = require("socket")
-- this does not work, just to show what I am dreaming of doing
--              |len  |type | payload        |
local msgData = {0x05, 0x3A, 0x00, 0xF4, 0x04} 
-- edit part of the payload
msgData[3] = 0x01
-- Send it over UDP
udp:sendto(msgData, "127.0.0.1", 50000);

Then on the other side I want to read that binary data back:

-- This is how I normally read the data, but "data" I guess is just a string, how can I collect the binary data?
data, ip, port = udp:receivefrom()
--data = udp:receive()
if data then
  print("RX UDP: " .. data .. " - from: " .. ip .. ":" .. port)
end

Sorry for the quality of the examples, but I have nothing that works and no real idea how to achieve this yet...

Upvotes: 4

Views: 13816

Answers (1)

Feneric
Feneric

Reputation: 861

Lua strings are designed to hold binary values, and while it's a little awkward manipulating individual characters within a string as binary values can be done in Lua if you remember that Lua strings are immutable and are aware of the ord and char methods. For example:

tst = '012345'
print(tst)
tst = string.char(string.byte(tst, 1) + 1) .. string.sub(tst, 2)
print(tst)

Operating this way you can do any sort of transformation you want on individual characters.

Hope this helps.

additional examples:

-- Create a string from hex values
binstr = string.char(0x41, 0x42, 0x43, 0x00, 0x02, 0x33, 0x48)

-- print out the bytes in decimal
print(string.byte(binstr, 1, string.len(binstr)))

-- print out the hex values
for i = 1, string.len(binstr), 1 do 
   io.write(string.format("%x ", string.byte(binstr, i)))
end
io.write("\n")

--print out the length
print("len = ", string.len(binstr))

Upvotes: 5

Related Questions