inumToCS :: (ChunkData t, Show d, Monad m) => Inum t (CtlStream t d) m a
inumToCS = mkInumM $ withCleanup pullup $ irepeat $ dataI >>= ifeed . csData
    where pullup = ipopresid >>= ungetI . flatten
          flatten (CSData h t) = mappend h $ flatten t
          flatten (CSCtl _ t)  = flatten t
          flatten CSEmpty      = mempty

-- | Return the next chunk of data or next control request in a
-- 'CtlStream'.  On end of file, returns 'CSEmpty'.  On any other
-- condition, returns a 'CtlStream' in which the tail is always
-- 'CSEmpty' and thus may be ignored.
inumToCS :: (ChunkData t, Show d, Monad m) => Inum t (CtlStream t d) m a
inumToCS = mkInumM $ withCleanup pullup $ irepeat $ dataI >>= ifeed . csData
    where pullup = ipopresid >>= ungetI . flatten
          flatten (CSData h t) = mappend h $ flatten t
          flatten (CSCtl _ t)  = flatten t
          flatten CSEmpty      = mempty

-- | Return the next chunk of data or next control request in a
-- 'CtlStream'.  On end of file, returns 'CSEmpty'.  On any other
-- condition, returns a 'CtlStream' in which the tail is always
-- 'CSEmpty' and thus may be ignored.
inumToCS = mkInumM $ withCleanup pullup $ irepeat $ dataI >>= ifeed . csData
    where pullup = ipopresid >>= ungetI . flatten
          flatten (CSData h t) = mappend h $ flatten t
          flatten (CSCtl _ t)  = flatten t
          flatten CSEmpty      = mempty

-- | Return the next chunk of data or next control request in a
-- 'CtlStream'.  On end of file, returns 'CSEmpty'.  On any other
-- condition, returns a 'CtlStream' in which the tail is always
-- 'CSEmpty' and thus may be ignored.