Skip to content

Instantly share code, notes, and snippets.

@sawaken
Last active August 29, 2015 14:16
Show Gist options
  • Save sawaken/113392a84c49d51383a6 to your computer and use it in GitHub Desktop.
Save sawaken/113392a84c49d51383a6 to your computer and use it in GitHub Desktop.
Attempt to handle byte-stream in Haskell.
import qualified Data.ByteString as B
import GHC.IO.Handle
import System.Process
import System.IO
type Packet = B.ByteString
pktsize = 188
main = do
(out, err, pid) <- record "recpt1 --b25 --strip 16 100 -"
outFileHdl <- makeOutputFile "out.ts"
repeatIO (getAndWrite out outFileHdl)
hClose outFileHdl
getAndWrite :: Handle -> Handle -> IO Bool
getAndWrite getHdl writeHdl = do
(final, pkts) <- getAccumulatedPackets getHdl
appendToFile pkts writeHdl
return final
repeatIO :: IO Bool -> IO ()
repeatIO io = do
flag <- io
if flag then
return ()
else
repeatIO io
makeOutputFile :: FilePath -> IO Handle
makeOutputFile fp = do
hdl <- openFile fp WriteMode
return hdl
appendToFile :: [Packet] -> Handle -> IO ()
appendToFile pkts hdl = do
B.hPut hdl (foldr B.append B.empty pkts)
hFlush hdl
record :: String -> IO (Handle, Handle, ProcessHandle)
record command = do
(inp, out, err, pid) <- runInteractiveProcess file args Nothing Nothing
return (out, err, pid)
where
file:args = words command
getAccumulatedPackets :: Handle -> IO (Bool, [Packet])
getAccumulatedPackets hdl = do
bytes <- B.hGet hdl (pktsize*1000)
finished <- hIsEOF hdl
return (finished, splitByLength pktsize bytes)
splitByLength :: Int -> B.ByteString -> [Packet]
splitByLength n b
| B.null b = []
| otherwise = let (pkt, rest) = B.splitAt n b in pkt:(splitByLength n rest)
import qualified Foreign.Marshal.Array as Array
import qualified Data.ByteString.Lazy as B
import Foreign.Ptr
import Data.Word8
import GHC.IO.Handle
import System.Process
type Packet = B.ByteString
packetsize = 188
bufsize = packetsize * 2000
main = do
buf <- Array.mallocArray bufsize
(out, err, pid) <- record "recpt1 --b25 --strip 16 30 -"
write buf out "out.ts"
write :: Ptr Word8 -> Handle -> FilePath -> IO ()
write buf out file = do
(fin, ps) <- getNextPacket out buf
B.appendFile file ps
if fin then do
return ()
else do
write buf out file
record :: String -> IO (Handle, Handle, ProcessHandle)
record command = do
(inp, out, err, pid) <- runInteractiveProcess file args Nothing Nothing
return (out, err, pid)
where
file:args = words command
getNextPacket :: Handle -> Ptr Word8 -> IO (Bool, B.ByteString)
getNextPacket hdl buf = do
len <- hGetBuf hdl buf bufsize
ls <- Array.peekArray bufsize buf
return (len /= bufsize, B.pack ls)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment