管道解析器过早中断

Conduit parser is interrupted prematurely

我正在开发一个程序,我需要从 USB 连接解析数据并将其写入循环缓冲区。

我一直 运行 关注的问题是解析器没有使用输入。我是否需要使用另一个运算符将解析器管道连接到 ByteStrings 的流?

如果我删除两个 'filters' dropCdropWhileC,解析器会消耗一些输入但会失败,因为前几块数据是垃圾。

很明显,我对图书馆工作方式的心智模型有问题(我以前从未使用过它)。

我还想知道 conduitParser 是否将空字符串视为 EOF 标记,就像 attoparsec 自己的 parseWith.

-- |
sourcePort :: SerialPort -> Producer IO ByteString
sourcePort port = repeatMC (recv port 16)


-- |
parseSerialStream :: (Vector v (Int, Int)) => RingBuffer v (Int, Int) -> SerialPort -> IO () -- ConduitM a c IO ()
parseSerialStream buffer port = sourcePort port
                             .| dropC 4
                             .| dropWhileC B.null
                             .| conduitParser (parseMeasurement <* endOfLine)
                             $$ mapM_C (\item -> print item >> RB.append (snd item) buffer)

@danidiaz 在评论中解释说 dropC et.al。不要产生任何值,这就是为什么你必须使用 monadic 组合而不是管道 (.|).

任何偶然发现这个问题的人,请参阅this answer了解详情。

此代码按预期工作:

parseSerialStream :: RingBuffer VU.Vector (Int, Int) -> SerialPort -> IO () -- ConduitM a c IO ()
parseSerialStream buffer port = sourcePort port
                             .| (dropC 4
                             >> dropWhileC B.null
                             >> conduitParser (parseMeasurement <* endOfLine))
                             $$ mapM_C (\item -> RB.append (snd item) buffer)

不过我喜欢管道的外观。哦好吧...