1
- {-# LANGUAGE CPP, GeneralizedNewtypeDeriving, BangPatterns, DeriveTraversable, ScopedTypeVariables, RankNTypes #-}
1
+ {-# LANGUAGE BangPatterns #-}
2
+ {-# LANGUAGE DeriveTraversable #-}
3
+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
4
+ {-# LANGUAGE PackageImports #-}
5
+ {-# LANGUAGE QuasiQuotes #-}
6
+ {-# LANGUAGE RankNTypes #-}
7
+ {-# LANGUAGE ScopedTypeVariables #-}
8
+
2
9
-----------------------------------------------------------------------------
3
10
-- |
4
11
-- Module : Codec.Archive.Tar.Types
@@ -88,6 +95,8 @@ import qualified System.FilePath.Windows as FilePath.Windows
88
95
( joinPath , addTrailingPathSeparator , pathSeparator )
89
96
import System.Posix.Types
90
97
( FileMode )
98
+ import "os-string" System.OsString.Posix (PosixString , PosixChar )
99
+ import qualified "os-string" System.OsString.Posix as PS
91
100
92
101
import Codec.Archive.Tar.PackAscii
93
102
@@ -278,7 +287,7 @@ symlinkEntry name targetLink =
278
287
-- @since 0.6.0.0
279
288
longLinkEntry :: FilePath -> GenEntry TarPath linkTarget
280
289
longLinkEntry tarpath = Entry {
281
- entryTarPath = TarPath ( BS.Char8. pack " . /./@LongLink" ) BS. empty ,
290
+ entryTarPath = TarPath [ PS. pstr |. /./@LongLink|] mempty ,
282
291
entryContent = OtherEntryType ' L' (LBS. fromStrict $ packAscii tarpath) (fromIntegral $ length tarpath),
283
292
entryPermissions = ordinaryFilePermissions,
284
293
entryOwnership = Ownership " " " " 0 0 ,
@@ -295,7 +304,7 @@ longLinkEntry tarpath = Entry {
295
304
-- @since 0.6.0.0
296
305
longSymLinkEntry :: FilePath -> GenEntry TarPath linkTarget
297
306
longSymLinkEntry linkTarget = Entry {
298
- entryTarPath = TarPath ( BS.Char8. pack " . /./@LongLink" ) BS. empty ,
307
+ entryTarPath = TarPath [ PS. pstr |. /./@LongLink|] mempty ,
299
308
entryContent = OtherEntryType ' K' (LBS. fromStrict . packAscii $ linkTarget) (fromIntegral $ length linkTarget),
300
309
entryPermissions = ordinaryFilePermissions,
301
310
entryOwnership = Ownership " " " " 0 0 ,
@@ -338,8 +347,11 @@ directoryEntry name = simpleEntry name Directory
338
347
--
339
348
-- * The directory separator between the prefix and name is /not/ stored.
340
349
--
341
- data TarPath = TarPath {- # UNPACK #-} !BS. ByteString -- path name, 100 characters max.
342
- {- # UNPACK #-} !BS. ByteString -- path prefix, 155 characters max.
350
+ data TarPath = TarPath
351
+ {- # UNPACK #-} !PosixString
352
+ -- ^ path name, 100 characters max.
353
+ {- # UNPACK #-} !PosixString
354
+ -- ^ path prefix, 155 characters max.
343
355
deriving (Eq , Ord )
344
356
345
357
instance NFData TarPath where
@@ -362,7 +374,7 @@ instance Show TarPath where
362
374
-- (e.g., using 'Codec.Archive.Tar.Check.checkEntrySecurity').
363
375
--
364
376
fromTarPath :: TarPath -> FilePath
365
- fromTarPath = BS.Char8. unpack . fromTarPathInternal FilePath.Native. pathSeparator
377
+ fromTarPath = fromPosixString . fromTarPathInternal ( PS. unsafeFromChar FilePath.Native. pathSeparator)
366
378
367
379
-- | Convert a 'TarPath' to a Unix\/Posix 'FilePath'.
368
380
--
@@ -373,7 +385,7 @@ fromTarPath = BS.Char8.unpack . fromTarPathInternal FilePath.Native.pathSeparato
373
385
-- operating system, eg to perform portability checks.
374
386
--
375
387
fromTarPathToPosixPath :: TarPath -> FilePath
376
- fromTarPathToPosixPath = BS.Char8. unpack . fromTarPathInternal FilePath.Posix. pathSeparator
388
+ fromTarPathToPosixPath = fromPosixString . fromTarPathInternal ( PS. unsafeFromChar FilePath.Posix. pathSeparator)
377
389
378
390
-- | Convert a 'TarPath' to a Windows 'FilePath'.
379
391
--
@@ -384,18 +396,18 @@ fromTarPathToPosixPath = BS.Char8.unpack . fromTarPathInternal FilePath.Posix.pa
384
396
-- operating system, eg to perform portability checks.
385
397
--
386
398
fromTarPathToWindowsPath :: TarPath -> FilePath
387
- fromTarPathToWindowsPath = BS.Char8. unpack . fromTarPathInternal FilePath.Windows. pathSeparator
399
+ fromTarPathToWindowsPath = fromPosixString . fromTarPathInternal ( PS. unsafeFromChar FilePath.Windows. pathSeparator)
388
400
389
- fromTarPathInternal :: Char -> TarPath -> BS. ByteString
401
+ fromTarPathInternal :: PosixChar -> TarPath -> PosixString
390
402
fromTarPathInternal sep = go
391
403
where
392
- posixSep = FilePath.Posix. pathSeparator
404
+ posixSep = PS. unsafeFromChar FilePath.Posix. pathSeparator
393
405
adjustSeps = if sep == posixSep then id else
394
- BS.Char8 .map $ \ c -> if c == posixSep then sep else c
406
+ PS .map $ \ c -> if c == posixSep then sep else c
395
407
go (TarPath name prefix)
396
- | BS .null prefix = adjustSeps name
397
- | BS .null name = adjustSeps prefix
398
- | otherwise = adjustSeps prefix <> BS.Char8 . cons sep (adjustSeps name)
408
+ | PS .null prefix = adjustSeps name
409
+ | PS .null name = adjustSeps prefix
410
+ | otherwise = adjustSeps prefix <> PS . cons sep (adjustSeps name)
399
411
{-# INLINE fromTarPathInternal #-}
400
412
401
413
-- | Convert a native 'FilePath' to a 'TarPath'.
@@ -453,12 +465,12 @@ splitLongPath :: FilePath -> ToTarPathResult
453
465
splitLongPath path = case reverse (FilePath.Posix. splitPath path) of
454
466
[] -> FileNameEmpty
455
467
c : cs -> case packName nameMax (c :| cs) of
456
- Nothing -> FileNameTooLong $ TarPath (packAscii $ take 100 path) BS. empty
457
- Just (name, [] ) -> FileNameOK $! TarPath (packAscii name) BS. empty
468
+ Nothing -> FileNameTooLong $ TarPath (toPosixString $ take 100 path) mempty
469
+ Just (name, [] ) -> FileNameOK $! TarPath (toPosixString name) mempty
458
470
Just (name, first: rest) -> case packName prefixMax remainder of
459
- Nothing -> FileNameTooLong $ TarPath (packAscii $ take 100 path) BS. empty
460
- Just (_ , _: _) -> FileNameTooLong $ TarPath (packAscii $ take 100 path) BS. empty
461
- Just (prefix, [] ) -> FileNameOK $! TarPath (packAscii name) (packAscii prefix)
471
+ Nothing -> FileNameTooLong $ TarPath (toPosixString $ take 100 path) mempty
472
+ Just (_ , _: _) -> FileNameTooLong $ TarPath (toPosixString $ take 100 path) mempty
473
+ Just (prefix, [] ) -> FileNameOK $! TarPath (toPosixString name) (toPosixString prefix)
462
474
where
463
475
-- drop the '/' between the name and prefix:
464
476
remainder = init first :| rest
0 commit comments