{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE CPP #-}
module Data.Conduit.Tar.Types
( Header(..)
, TarChunk(..)
, TarException(..)
, TarCreateException(..)
, FileType(..)
, FileInfo(..)
, FileOffset
, ByteCount
, UserID
, GroupID
, DeviceID
, EpochTime
, CUid(..)
, CGid(..)
, encodeFilePath
, decodeFilePath
, getFileInfoPath
) where
import Control.Exception (Exception)
import Data.ByteString (ByteString)
import Data.ByteString.Short (ShortByteString)
import Data.Typeable
import Data.Word
import System.Posix.Types
import qualified Data.ByteString.Char8 as S8
import Data.Text as T
import Data.Text.Encoding as T
import Data.Text.Encoding.Error as T
#if WINDOWS
import Data.Bits
import Foreign.Storable
newtype CUid =
CUid Word32
deriving ( Bounded
, Enum
, Eq
, Integral
, Num
, Ord
, Read
, Real
, Show
, Bits
, Storable
)
newtype CGid =
CGid Word32
deriving ( Bounded
, Enum
, Eq
, Integral
, Num
, Ord
, Read
, Real
, Show
, Bits
, Storable
)
type UserID = CUid
type GroupID = CGid
#endif
data FileType
= FTNormal
| FTHardLink
| FTSymbolicLink !ByteString
| FTCharacterSpecial
| FTBlockSpecial
| FTDirectory
| FTFifo
| FTOther !Word8
deriving (Show, Eq)
data FileInfo = FileInfo
{ filePath :: !ByteString
, fileUserId :: !UserID
, fileUserName :: !ByteString
, fileGroupId :: !GroupID
, fileGroupName :: !ByteString
, fileMode :: !FileMode
, fileSize :: !FileOffset
, fileType :: !FileType
, fileModTime :: !EpochTime
} deriving (Show, Eq)
data Header = Header
{ headerOffset :: !FileOffset
, headerPayloadOffset :: !FileOffset
, headerFileNameSuffix :: !ShortByteString
, headerFileMode :: !CMode
, headerOwnerId :: !UserID
, headerGroupId :: !GroupID
, headerPayloadSize :: !FileOffset
, headerTime :: !EpochTime
, headerLinkIndicator :: !Word8
, headerLinkName :: !ShortByteString
, headerMagicVersion :: !ShortByteString
, headerOwnerName :: !ShortByteString
, headerGroupName :: !ShortByteString
, headerDeviceMajor :: !DeviceID
, headerDeviceMinor :: !DeviceID
, headerFileNamePrefix :: !ShortByteString
}
deriving Show
data TarChunk
= ChunkHeader Header
| ChunkPayload !FileOffset !ByteString
| ChunkException TarException
deriving Show
data TarException
= NoMoreHeaders
| UnexpectedPayload !FileOffset
| IncompleteHeader !FileOffset
| IncompletePayload !FileOffset !ByteCount
| ShortTrailer !FileOffset
| BadTrailer !FileOffset
| InvalidHeader !FileOffset
| BadChecksum !FileOffset
| FileTypeError !FileOffset !Char !String
| UnsupportedType !FileType
deriving (Show, Typeable)
instance Exception TarException
data TarCreateException
= FileNameTooLong !FileInfo
| TarCreationError !String
deriving (Show, Typeable)
instance Exception TarCreateException
encodeFilePath :: FilePath -> S8.ByteString
encodeFilePath = T.encodeUtf8 . T.pack
decodeFilePath :: S8.ByteString -> FilePath
decodeFilePath = T.unpack . T.decodeUtf8With T.lenientDecode
getFileInfoPath :: FileInfo -> FilePath
getFileInfoPath = decodeFilePath . filePath