-
Не, ясен пень, нужно сварганить простейший конечный автомат (вернее, трансдюсер), который будет разбивать поступающие на вход байтстринги на более мелкие байтстринги (ленивые, без копирования). А вот как это сделать в реале?
Перейти на стринги, перейти на текст? Важна даже не столько вычислительная сложность. Важно чтобы реализация как можно меньше сношала сборщик мусора.
Обойти — не вариант. Во-первых, такое поведение — MUST. Во-вторых, без реализации такого поведения к чертям полетит вся кошер^W каноничность.
Replies (9)
-
@segfault, Про xml-conduit я в курсе и пользуюсь. Только у Сноймана код какбэ мнэ-э-э ... глубоко специфичный. Ему похуй на спецификацию XML, его парсер без проблем принимает \r и \r\n.
И, как я уже сказал, нормализация EOL до парсинга — MUST в спецификации.
Можно сварганить фильтр на Event'ы, но во-первых, опять встаёт вопрос «Как?»; во-вторых, всё нужно делать по-нормальному, не через жопу. -
@segfault, Да понятно! Весь вопрос как такое сделать!!! Работа идёт с чанками байтстрингов (для простоты будем считать что кодировка однобайтовая). По спеке "\r\n" нужно заменить на "\n". Теперь представь что у тебя \r в конце одного чанка, а \n — в начале другого. Т.е. нужно как-то таскать состояние. А еще нужно чтобы это было красиво, элегантно и без насилия над сборщиком мусора.
Можно вклиниться в преобразование ByteString -> Text на уровне Conduit.Text, но опять хрен его знает как это сделать потому что получившийся нормализованный текст будет, сцуко, КОРОЧЕ. И опять нужно как-то тащить состояние. -
@segfault, leftover мне не поможет, тогда мне придётся заглядывать на шаг вперед, что в данном контексте нахрен не нужно. Можно поступить как Снойман — таскать состояние внутри цикла в кондуите, например как в Data.Conduit.Text.lines... Скорее всего так и придётся сделать.
-
@Macil, go = do (xs,ys) <- span (/= chr (0x0D))
case ys of
"" -> xs
'\r' : '\n' :ys -> xs <> chr (0x0A): go ys
_ -> xs <> go ys
это тебе на строках, чтобы перевести на LBS вместо xs пиши [xs] и потом fromChunks натрави, чтобы перевести на кондуиты просто делай yield вместо возврата xs и не забудь в случае "" попросить ещё входящих данных, так же случай с '\r' разобьётся на 2 в случае пустого и не пустого ys.
/7 · Reply -
@qnikst, github.com вот на машинках, чуть сложнее, чем на строках, в принципе ещё можно сделать аккуратнее, когда на \n не делается отдельный чанк если он является частью следующего чанка, но мне лень, будут бенчмарки, можно поговорить будет