我正在开发一个程序,我需要从USB连接中解析数据并将其写入循环缓冲区。
我一直遇到的问题是解析器没有消耗输入。我是否需要使用其他运算符将解析器管道连接到ByteString
s?
如果删除两个'过滤器'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)
答案 0 :(得分:2)
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)
我喜欢管道看起来如何。哦,好吧......