Concepts - Binary Strings
Binary Strings
Lua has no separate type for binary data. A string is a sequence of bytes, any value from 0 to 255 can appear in it, including 0, and the same type holds text and raw data.
Which one you have depends on where the string came from and where it is going.
Binary strings come out of net.ReadData, util.Compress, util.Base64Decode, render.Capture, string.dump and File:Read, and go into net.WriteData, util.Decompress, File:Write and sound.Generate. A BLOB column read with sql.QueryTyped is one as well.
Bytes vs. characters
# and string.len count bytes. A character outside ASCII takes more than one, #"\195\188" is 2 for a single letter.
Use utf8.len when you want characters, it also returns false when the string is not valid text.
Strings cannot be changed in place. Build binary data with string.char and read it back with string.byte, both deal in byte values.
Concatenation, string.sub, string.rep and table.concat keep every byte.
For structured data, a File opened in rb or wb mode has typed readers and writers such as File:ReadULong and File:WriteFloat. There is no string.pack in Garry's Mod.
string.byte( str, 1, -1 ) returns one value per byte, and a long string errors with string slice too long. Read it in chunks.Where bytes get lost
- net.WriteString writes a null terminated string, so it stops at the first
0byte and the rest is never sent. Use net.WriteData for anything that might contain a0. - net.WriteData writes no length, so the receiver has to know how many bytes to read. Write the length first with net.WriteUInt, see Net Library Usage. A compressed string that is the whole message can use the message length instead, as shown on net.WriteData.
- print and the console stop at the first
0byte, so a binary string looks shorter than it is. Print#stror a hex dump instead. - util.TableToJSON keeps every byte and util.JSONToTable reads them all back. Bytes above
127are written as they are, so the JSON is invalid UTF-8 and a browser or a web server will read it differently. Encode with util.Base64Encode first when the JSON leaves Lua or the data goes into a DHTML page. Passtrueas the second argument, or the output gets a line break every 76 characters. - Patterns treat
.,%,(,[and the other magic characters specially, and binary data is full of them. Search with string.find andplainset totrue.
Example
A compressed string holds 0 bytes, so it goes over the net as data with its length in front.
Garry's Mod
Rust
Steamworks
Wiki Help