Как хранить двоичные данные в строке Lua - PullRequest
1 голос
/ 28 сентября 2010

Мне нужно было создать собственный формат файла со встроенной метаинформацией.Вместо того, чтобы использовать свой собственный формат, я решил просто использовать 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-строке нетривиально .Но это возможно при работе с 3 последовательностями.

  • Длинные строковые литералы не могут иметь встроенную закрывающую длинную скобку (]], ]=] и т. Д.).
    Это довольно очевидно.

  • Длинные строковые литералы формата не могут заканчиваться чем-то вроде ]==, чтобудет соответствовать выбранному закрывающему-длинному брекету .
    Этот более тонкий.К счастью, скрипт не скомпилируется, если все сделано неправильно.

  • Данные не могут встраивать \n или \r.
    Встроенная в Lua's обработка в конце строки все испортила.Эта проблема гораздо более тонкая.Скрипт скомпилируется нормально, но выдает неверные данные.0x13 => 0x10, 0x1013 => 0x10 и т. Д.

Чтобы обойти эти ограничения, я разбил двоичные данные на \r, \n, а затем выбрал длинная скобка , которая работает, наконец, испускает Lua, который объединяет различные части вместе.Я использовал скрипт, который делает это для меня.
input: XXXX\nXX]]XX\r\nXX]]XX]=

texture
{
  --other fields omitted      
  pixels= '' ..
     [[XXXX]] ..
     '\n' ..
     [=[XX]]XX]=] ..
     '\r\n' ..
     [==[XX]]XX]=]==];
}

Ответы [ 2 ]

3 голосов
/ 29 сентября 2010

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>'"

Если вы не используете окна, то это может не вызвать проблем, но могут быть и другие проблемы в текстовом режиме.


Мне удалось выдать ошибку, которую вы получили только путем кодирования нескольких закрывающих скобок:

a=[[
]]] --> a.lua:2: unexpected symbol near ']'

Но это легко исправить следующим образом:

a=[==[
]]==]
1 голос
/ 28 сентября 2010

Двоичные данные должны быть закодированы в печатные символы.Простейшим способом декодирования было бы использование C-подобных escape-последовательностей для всех байтов.Например, шестнадцатеричные байты 13 41 42 1E будут закодированы как '\ 19 \ 65 \ 66 \ 30'.Конечно, тогда закодированные данные в три-четыре раза больше, чем исходный двоичный файл.

В качестве альтернативы, вы можете использовать что-то вроде Base64 , но это должно быть декодировано во время выполнения вместополагаясь на переводчика Lua.Лично я бы, наверное, пошел по маршруту Base64.Существуют Lua примеры кодирования и декодирования Base64 .

Другой вариант - два файла.Используйте четко определенный файл формата изображения (например, TGA ), на который указывает отдельный скрипт Lua с дополнительными метаданными.Если вы не хотите, чтобы два файла перемещались, их можно объединить в архив .

...