gpt4 book ai didi

haskell - 使用 Conduit 从 ByteString 过滤 ANSI 转义序列

转载 作者:行者123 更新时间:2023-12-04 15:31:38 26 4
gpt4 key购买 nike

我正在尝试制作一个从 ByteStrings 过滤 ANSI 转义码的导管。我想出了一个函数,它将 ByteString 转换为 Word8 的流,进行过滤,最后转换回 ByteStream 流。

当我在 GHCi 中使用它时,它似乎工作正常:

> runConduit $ yield "hello\27[23;1m world" .| ansiFilter .| printC
"hello world"

当我在我的应用程序中使用它时,包含 ansiFilter 的管道似乎没有通过任何东西。这是完整的来源:
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Conduit
import Control.Concurrent.Async
import Control.Concurrent.STM
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Conduit.TQueue
import Data.Word8 (Word8)
import qualified Data.Word8 as Word8

main :: IO ()
main = do

queue <- atomically $ newTBQueue 25
let qSource = sourceTBQueue queue
atomically $ writeTBQueue queue ("hello" :: ByteString)

race_
(putInputIntoQueue queue)
(doConversionAndPrint qSource)

putInputIntoQueue q =
runConduit
$ stdinC
.| iterMC (atomically . writeTBQueue q)
.| sinkNull

doConversionAndPrint src =
runConduit
$ src
.| ansiFilter
.| stdoutC

ansiFilter :: MonadIO m => ConduitM ByteString ByteString m ()
ansiFilter = toWord8 .| ansiFilter' .| toByteString
where
ansiFilter' = awaitForever $ \first -> do
msecond <- peekC
case (first, msecond) of
(0x1b, Just 0x5b) -> do
dropWhileC (not . Word8.isLetter)
dropC 1
_ -> yield first

toWord8 = concatC

toByteString :: Monad m => ConduitM Word8 ByteString m ()
toByteString =
(mapC BS.singleton .| foldC) >>= yield

这个程序应该回显 stdin 的过滤内容。 ,但没有任何回应。

但是,如果我注释掉 ansiFilterdoConversionAndPrint ,回声确实有效,这让我喜欢 ansiFilter功能错误。

任何帮助将不胜感激!

最佳答案

我重新实现了 ansiFilter就管道组合器中更高级别的分 block 数据功能而言,如 takeWhileCE .这似乎可行,并且应该通过让更多数据保留在有效的内存表示中来提高效率:

ansiFilter :: MonadIO m => ConduitM ByteString ByteString m ()
ansiFilter = loop
where
loop = do
takeWhileCE (/= 0x1b)
mfirst <- headCE
case mfirst of
Nothing -> return ()
Just first -> assert (first == 0x1b) $ do
msecond <- peekCE
case msecond of
Just 0x5b -> do
dropWhileCE (not . Word8.isLetter)
dropCE 1
_ -> yield $ BS.singleton first
loop

关于haskell - 使用 Conduit 从 ByteString 过滤 ANSI 转义序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41030290/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com