管道解析器过早中断
Conduit parser is interrupted prematurely
我正在开发一个程序,我需要从 USB 连接解析数据并将其写入循环缓冲区。
我一直 运行 关注的问题是解析器没有使用输入。我是否需要使用另一个运算符将解析器管道连接到 ByteString
s 的流?
如果我删除两个 'filters' dropC
和 dropWhileC
,解析器会消耗一些输入但会失败,因为前几块数据是垃圾。
很明显,我对图书馆工作方式的心智模型有问题(我以前从未使用过它)。
我还想知道 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)
不过我喜欢管道的外观。哦好吧...
我正在开发一个程序,我需要从 USB 连接解析数据并将其写入循环缓冲区。
我一直 运行 关注的问题是解析器没有使用输入。我是否需要使用另一个运算符将解析器管道连接到 ByteString
s 的流?
如果我删除两个 'filters' dropC
和 dropWhileC
,解析器会消耗一些输入但会失败,因为前几块数据是垃圾。
很明显,我对图书馆工作方式的心智模型有问题(我以前从未使用过它)。
我还想知道 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)
不过我喜欢管道的外观。哦好吧...