История изменений
Исправление SZT, (текущая версия) :
Здесь нет возможности чтения из потока + чтения из буфера в памяти - только из буфера в памяти.
Значит надо читать поток в буфер, и потом уже разбирать его
Грузить все сразу в память - это иногда совсем не вариант (например, большие архивы или какой-нибудь 50-гигабайтный образ диска)
Можно использовать отображение файла в память (mmap в *nix, MapViewOfFile в виндах) и тогда никаких проблем. Это уже будет забота ОС с ее механизмом подкачки.
Typecasting в struct - плохая идея, как минимум нужна куча опций упаковки
Тут не происходит прямого typecasting в struct, тут через memcpy в структуру загружается часть входного буфера (кстати этот memcpy вполне можно заменить чем-то другим, например чтением из Unix domain socket и тогда можно читать из некоего потока, а не из буфера в памяти). Если мы по условию не можем опираться на всякие #pragma pack
для «уплотнения» структур, то придется от структур как таковых вообще отказаться, и делать memcpy прямо в тип нужной битности (прямой каст указателя и разыменование с unaligned read это UB)
Самое главное - не получилось как такового API доступа к данным. Скажем, в любой из библиотек, сгенеренных KS сейчас, можно написать что-то типа `gif.block[1234]` и мы получим объект блока по порядковому номеру. Можно написать `gif.global_color_table[42].g` и получить доступ к зеленому компоненту цвета #42 из глобальной таблицы цветов. Здесь же такого нет - доступ к цвету есть только внутри процесса парсинга и только в момент нахождения указателя парсера на нужном цвете.
Ну тут во-первых возникает закономерный вопрос: а насколько сильно подобное API раздует и усложнит итоговый код? Насколько это будет востребовано среди тех, кому нужно будет генерировать код в Си?
Релиз Kaitai Struct v0.4 (комментарий) :
А потом приходят злые эмбеддщики и говорят, что у них 2 килобайта памяти и килобайт 15-20 флешки под код
Вряд ли эмбеддщики будут сильно рады, им не нужно столь раздутое API.
А теперь насчет нужности `gif.block[1234]`. Под block у нас понимается то, что названо тут как Image Descriptor http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html. В Packed Field есть флаг, отвечающий на вопрос, будет или не будет у нас использоваться Local Color Table после Image Descriptor. Если будет, то следующий Image Descriptor будет идти не сразу же после предыдущего, а надо еще пропустить размер этого Local Color Table. Т.е. мы не можем за константное время получить gif.block[1234], необходимо перебирать последовательно все эти gif.block и смотреть, есть или нет там этой Local Color Table после чего делать или не делать нужные отступы под эту таблицу. Ну и потом еще должен идти Image Data, так что для получения следующего блока по-любому придется считать какие-то отступы. Время доступа будет O(n). А если мы знаем, где у нас gif.block[1233] и нам надо получить gif.block[1234] то это решается элементарно, можно сравнить это со связными списками. Притом это API для доступа к произвольному элементу будет скорее всего невостребовано, и лишь займет лишнее место. Если тому же эмбеддщику надо используя микроконтроллер воспроизвести анимированный gif на какой-нибудь экранчик, ему вот эти вот gif.block[1234]
совершенно не нужны, ему будет достаточно последовательного чтения всех этих блоков, что-то типа итератора.
Чтобы угодить эмбеддщикам, неплохо было бы подумать над тем, чтобы генерировать более узкоспециализированные парсеры бинарных форматов.
Во-вторых, судя по статье на хабре https://habrahabr.ru/post/281595/ основная область применения это разбор неких проприетархых форматов, а не создание эффективного кода для разбора структур с цель последующего «боевого» применения. В таком случае не совсем понятно, зачем нужно делать компиляторы для C и C++. Да и компиляторы-то не особо нужны, вполне хватило бы интерпретатора
Исходная версия SZT, :
Здесь нет возможности чтения из потока + чтения из буфера в памяти - только из буфера в памяти.
Значит надо читать поток в буфер, и потом уже разбирать его
Грузить все сразу в память - это иногда совсем не вариант (например, большие архивы или какой-нибудь 50-гигабайтный образ диска)
Можно использовать отображение файла в память (mmap в *nix, MapViewOfFile в виндах) и тогда никаких проблем. Это уже будет забота ОС с ее механизмом подкачки.
Typecasting в struct - плохая идея, как минимум нужна куча опций упаковки
Тут не происходит прямого typecasting в struct, тут через memcpy в структуру загружается часть входного буфера (кстати этот memcpy вполне можно заменить чем-то другим, например чтением из Unix domain socket и тогда можно читать из некоего потока, а не из буфера в памяти). Если мы по условию не можем опираться на всякие #pragma pack
для «уплотнения» структур, то придется от структур как таковых вообще отказаться, и делать memcpy прямо в тип нужной битности (прямой каст указателя и разыменование с unaligned read это UB)
Самое главное - не получилось как такового API доступа к данным. Скажем, в любой из библиотек, сгенеренных KS сейчас, можно написать что-то типа `gif.block[1234]` и мы получим объект блока по порядковому номеру. Можно написать `gif.global_color_table[42].g` и получить доступ к зеленому компоненту цвета #42 из глобальной таблицы цветов. Здесь же такого нет - доступ к цвету есть только внутри процесса парсинга и только в момент нахождения указателя парсера на нужном цвете.
Ну тут во-первых возникает закономерный вопрос: а насколько сильно подобное API раздует и усложнит итоговый код? Насколько это будет востребовано среди тех, кому нужно будет генерировать код в Си?
Релиз Kaitai Struct v0.4 (комментарий) :
А потом приходят злые эмбеддщики и говорят, что у них 2 килобайта памяти и килобайт 15-20 флешки под код
Вряд ли эмбеддщики будут сильно рады, им не нужно столь раздутое API.
А теперь насчет нужности `gif.block[1234]`. Под block у нас понимается то, что названо тут как Image Descriptor http://giflib.sourceforge.net/whatsinagif/bits_and_bytes.html. В Packed Field есть флаг, отвечающий на вопрос, будет или не будет у нас использоваться Local Color Table после Image Descriptor. Если будет, то следующий Image Descriptor будет идти не сразу же после предыдущего, а надо еще пропустить размер этого Local Color Table. Т.е. мы не можем за константное время получить gif.block[1234], необходимо перебирать последовательно все эти gif.block и смотреть, есть или нет там этой Local Color Table после чего делать или не делать нужные отступы. А если мы знаем, где у нас gif.block[1233] и нам надо получить gif.block[1234] то это решается элементарно, можно сравнить это со связными списками. Притом это API для доступа к произвольному элементу будет скорее всего невостребовано, и лишь займет лишнее место. Если тому же эмбеддщику надо используя микроконтроллер воспроизвести анимированный gif на какой-нибудь экранчик, ему вот эти вот gif.block[1234]
совершенно не нужны, ему будет достаточно последовательного чтения всех этих блоков, что-то типа итератора.
Чтобы угодить эмбеддщикам, неплохо было бы подумать над тем, чтобы генерировать более узкоспециализированные парсеры бинарных форматов.
Во-вторых, судя по статье на хабре https://habrahabr.ru/post/281595/ основная область применения это разбор неких проприетархых форматов, а не создание эффективного кода для разбора структур с цель последующего «боевого» применения. В таком случае не совсем понятно, зачем нужно делать компиляторы для C и C++. Да и компиляторы-то не особо нужны, вполне хватило бы интерпретатора