1{- Some git commands output encoded filenames, in a rather annoyingly complex
2 - C-style encoding.
3 -
4 - Copyright 2010, 2011 Joey Hess <id@joeyh.name>
5 -
6 - Licensed under the GNU AGPL version 3 or higher.
7 -}
8
9module Git.Filename where
10
11import Common
12import Utility.Format (decode_c, encode_c)
13import Utility.QuickCheck
14
15import Data.Char
16import Data.Word
17import qualified Data.ByteString as S
18
19-- encoded filenames will be inside double quotes
20decode :: S.ByteString -> RawFilePath
21decode b = case S.uncons b of
22	Nothing -> b
23	Just (h, t)
24		| h /= q -> b
25		| otherwise -> case S.unsnoc t of
26			Nothing -> b
27			Just (i, l)
28				| l /= q -> b
29				| otherwise ->
30					encodeBS $ decode_c $ decodeBS i
31  where
32  	q :: Word8
33	q = fromIntegral (ord '"')
34
35{- Should not need to use this, except for testing decode. -}
36encode :: RawFilePath -> S.ByteString
37encode s = encodeBS $ "\"" ++ encode_c (decodeBS s) ++ "\""
38
39-- Encoding and then decoding roundtrips only when the string does not
40-- contain high unicode, because eg,  both "\12345" and "\227\128\185"
41-- are encoded to "\343\200\271".
42--
43-- That is not a real-world problem, and using TestableFilePath
44-- limits what's tested to ascii, so avoids running into it.
45prop_encode_decode_roundtrip :: TestableFilePath -> Bool
46prop_encode_decode_roundtrip ts =
47	s == fromRawFilePath (decode (encode (toRawFilePath s)))
48  where
49	s = fromTestableFilePath ts
50