{-# LANGUAGE OverloadedStrings
           , StandaloneDeriving #-}

module System.Posix.ARX.Tar where

import Prelude hiding (drop, take)
import Data.ByteString.Lazy.Char8


{-| Handled styles of Tar archive.
 -}
data Tar                     =  TAR | TBZ | TGZ | TXZ
deriving instance Eq Tar
deriving instance Ord Tar
deriving instance Show Tar


{-| Scan a lazy ByteString for file magic.
 -}
magic                       ::  ByteString -> Maybe Tar
magic :: ByteString -> Maybe Tar
magic ByteString
b | ByteString -> Bool
bzMagic ByteString
b          =  Tar -> Maybe Tar
forall a. a -> Maybe a
Just Tar
TBZ
        | ByteString -> Bool
gzMagic ByteString
b          =  Tar -> Maybe Tar
forall a. a -> Maybe a
Just Tar
TGZ
        | ByteString -> Bool
tarMagic ByteString
b         =  Tar -> Maybe Tar
forall a. a -> Maybe a
Just Tar
TAR
        | ByteString -> Bool
xzMagic ByteString
b          =  Tar -> Maybe Tar
forall a. a -> Maybe a
Just Tar
TXZ
        | Bool
otherwise          =  Maybe Tar
forall a. Maybe a
Nothing

bzMagic :: ByteString -> Bool
bzMagic                      =  (ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
"BZh")      (ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
take Int64
3

gzMagic :: ByteString -> Bool
gzMagic                      =  (ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
"\x1F\x8b") (ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
take Int64
2

tarMagic :: ByteString -> Bool
tarMagic                     =  (ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
"ustar")    (ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
take Int64
5 (ByteString -> ByteString)
-> (ByteString -> ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
drop Int64
257

xzMagic :: ByteString -> Bool
xzMagic                      =  (ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
xzBytes)    (ByteString -> Bool)
-> (ByteString -> ByteString) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ByteString -> ByteString
take Int64
6
 where
  xzBytes :: ByteString
xzBytes                    = Char
'\xFD' Char -> ByteString -> ByteString
`cons` ByteString
"7zXZ\0"