我需要创建一个包含嵌入元信息的自定义文件格式。我没有采用自己的格式,而是决定只使用Lua。
texture
{
format=GL_LUMINANCE_ALPHA;
type=GL_UNSIGNED_BYTE;
width=256;
height=128;
pixels=[[
<binary-data-here>]];
}
texture
是一个以表为唯一参数的函数。然后,它在表中按名称查找各种参数,并将调用转发到C ++例程。我希望没有什么不同寻常的。
有时,文件无法解析,并出现以下错误:
my_file.lua:8: unexpected symbol near ']'
这里发生了什么事? 有没有更好的方法在Lua中存储二进制数据?
事实证明,存储二进制数据的Lua字符串是non-trivial。但是,当照顾3个序列时,它是可能的。
Long-format-string-literals无法嵌入关闭 - 长括号(]]
,]=]
等。)
这个很明显。
长格式字符串文字不能以]==
之类的内容结尾,这些内容与所选的结束 - 长括号相匹配。
这个更微妙。幸运的是,如果做错了,脚本将无法编译。
数据无法嵌入\n
或\r
Lua的built in line-end processing使这些混乱。这个问题更加微妙。脚本编译正常,但会产生错误的数据。 0x13 =&gt; 0x10,0x1013 =&gt; 0x10等。
为了解决这些限制,我将二进制数据拆分为\r
,\n
,然后选择一个有效的长括号,最后发出连接各种各样的Lua零件回到一起。我使用了一个脚本来为我做这件事
输入:XXXX\nXX]]XX\r\nXX]]XX]=
texture
{
--other fields omitted
pixels= '' ..
[[XXXX]] ..
'\n' ..
[=[XX]]XX]=] ..
'\r\n' ..
[==[XX]]XX]=]==];
}
答案 0 :(得分:3)
Lua能够以长括号格式编码大多数字符,包括空值。但是,Lua以文本模式打开脚本文件,这会导致一些问题。在我的Windows系统上,以下字符存在问题:
Char code(s) Problem -------------- ------------------------------- 13 (CR) Is translated to 10 (LF) 13 10 (CR LF) Is translated to 10 (LF) 26 (EOF) Causes "unfinished long string near '<eof>'"
如果您不使用Windows而不是这些可能不会导致问题,但可能存在基于文本模式的不同问题。
我只能通过编码多个近括号来产生您收到的错误:
a=[[
]]] --> a.lua:2: unexpected symbol near ']'
但是,这可以通过以下方式轻松解决:
a=[==[
]]==]
答案 1 :(得分:1)
二进制数据需要编码为可打印字符。解码目的最简单的方法是对所有字节使用C-like escape sequences。例如,十六进制字节13 41 42 1E
将被编码为'\ 19 \ 65 \ 66 \ 30'。当然,编码数据比源二进制文件大三到四倍。
或者,您可以使用类似Base64的内容,但必须在运行时解码而不是依赖于Lua解释器。就个人而言,我可能会走Base64路线。有Lua examples of Base64 encoding and decoding。
另一种选择是拥有两个文件。使用明确定义的图像格式文件(例如TGA),该文件由单独的Lua脚本与其他元数据指向。如果您不想移动两个文件,则可以将它们合并到archive。