如何在Lua字符串中存储二进制数据

时间:2010-09-28 17:02:01

标签: string lua binary-data

我需要创建一个包含嵌入元信息的自定义文件格式。我没有采用自己的格式,而是决定只使用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]=]==];
}

2 个答案:

答案 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