module Data.Graph.Planar.Serialisation
( PlanarEncoding(..)
, encodePlanarFile
, encodePlanarFileFrom
, decodePlanarFile
) where
import Data.Graph.Planar hiding (isEmpty)
import Data.Graph.Planar.Serialisation.Internal
import Blaze.ByteString.Builder(toLazyByteString)
import Blaze.ByteString.Builder.Char8(fromChar)
import Data.Attoparsec.ByteString.Lazy(parse, eitherResult, many1, (<?>))
import Data.Attoparsec.ByteString.Char8(endOfLine)
import qualified Data.ByteString.Lazy as B
import Data.Monoid(mempty, mappend)
import Control.Applicative((<*))
import Control.Monad(foldM)
encodePlanarFile :: (PlanarEncoding ser) => ser -> FilePath
-> [PlanarGraph (NLabel ser) (ELabel ser)]
-> IO Int
encodePlanarFile ser fp = encodePlanarFileFrom ser fp . map ((,) Nothing)
encodePlanarFileFrom :: (PlanarEncoding ser) => ser -> FilePath
-> [(Maybe Edge,PlanarGraph (NLabel ser) (ELabel ser))]
-> IO Int
encodePlanarFileFrom ser fp pgs = do B.writeFile fp $ toLazyByteString header
foldM printCount 0 pgs
where
header = putName ser
maybeNewline | sepByNewline ser = fromChar '\n'
| otherwise = mempty
printCount c pg = c `seq` (B.appendFile fp (toB pg) >> return (c+1))
toB pg = toLazyByteString $ putSG ser (toSer pg) `mappend` maybeNewline
toSer (me,pg) = ((order pg, size pg), serialiseBFS pg me)
decodePlanarFile :: (PlanarEncoding ser) => ser -> FilePath
-> IO [PlanarGraph (NLabel ser) (ELabel ser)]
decodePlanarFile ser fp = do bs <- B.readFile fp
case eitherResult $ parse parser bs of
Left err -> error $ "Could not parse file " ++ fp ++ " with the error: " ++ err
Right sgs -> return $ map deserialise sgs
where
parser = do nm <- fmap (`asTypeOf` ser) getName <?> "Parsing encoding header"
many1 $ getSG nm <* maybeNewLine
maybeNewLine | sepByNewline ser = endOfLine
| otherwise = return ()