Skip to content

Commit 2f5671a

Browse files
committed
fixup! fixup! Implemented TH splices for validated ByteString literals
Andrew Lelechenko review fixes
1 parent 28a0cb6 commit 2f5671a

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

Data/ByteString/Internal/Type.hs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,35 @@ packUptoLenChars len cs0 =
532532
go !p (c:cs) = pokeFp p (c2w c) >> go (p `plusForeignPtr` 1) cs
533533
in go p0 cs0
534534

535+
#if MIN_VERSION_template_haskell(2,17,0)
536+
type THLift a = forall m. (MonadFail m, TH.Quote m) => TH.Code m a
537+
538+
liftTyped :: forall a m. (MonadFail m, TH.Quote m, TH.Lift a) => a -> TH.Code m a
539+
liftTyped = TH.liftTyped
540+
541+
liftCode :: forall a m. (MonadFail m, TH.Quote m) => m (TH.TExp a) -> TH.Code m a
542+
liftCode = TH.liftCode
543+
#else
544+
type THLift a = TH.Q (TH.TExp a)
545+
546+
liftTyped :: forall a. TH.Lift a => a -> TH.Q (TH.TExp a)
547+
liftTyped = TH.unsafeTExpCoerce . TH.lift
548+
549+
liftCode :: forall a. TH.Q TH.Exp -> TH.Q (TH.TExp a)
550+
liftCode = TH.unsafeTExpCoerce
551+
#endif
552+
535553
data S2W = Octets {-# UNPACK #-} !Int [Word8]
554+
-- ^ Decoded some octets (<= 0xFF)
536555
| Hichar {-# UNPACK #-} !Int {-# UNPACK #-} !Word
556+
-- ^ Found a high char (> 0xFF)
557+
558+
data H2W = Hex {-# UNPACK #-} !Int [Word8]
559+
-- ^ Decoded some full bytes (nibble pairs)
560+
| Odd {-# UNPACK #-} !Int {-# UNPACK #-} !Word [Word8]
561+
-- ^ Decoded a nibble plus some full bytes
562+
| Bad {-# UNPACK #-} !Int {-# UNPACK #-} !Word
563+
-- ^ Found a non hex-digit character
537564

538565
-- | Template Haskell splice to convert string constants to compile-time
539566
-- ByteString literals. Unlike the 'IsString' instance, the input string
@@ -546,39 +573,20 @@ data S2W = Octets {-# UNPACK #-} !Int [Word8]
546573
-- > ehloCmd :: ByteString
547574
-- > ehloCmd = $$(literalFromChar8 "EHLO")
548575
--
549-
#if MIN_VERSION_template_haskell(2,17,0)
550-
liftTyped :: forall a m. (TH.Lift a, TH.Quote m) => a -> TH.Code m a
551-
liftTyped = TH.liftTyped
552-
553-
liftCode :: forall a m. m (TH.TExp a) -> TH.Code m a
554-
liftCode = TH.liftCode
555-
556-
literalFromChar8 :: (MonadFail m, TH.Quote m) => String -> TH.Code m ByteString
557-
#else
558-
liftTyped :: forall a. TH.Lift a => a -> TH.Q (TH.TExp a)
559-
liftTyped = TH.unsafeTExpCoerce . TH.lift
560-
561-
liftCode :: forall a. TH.Q TH.Exp -> TH.Q (TH.TExp a)
562-
liftCode = TH.unsafeTExpCoerce
563-
564-
literalFromChar8 :: String -> TH.Q (TH.TExp ByteString)
565-
#endif
576+
literalFromChar8 :: String -> THLift ByteString
566577
literalFromChar8 "" = [||empty||]
567578
literalFromChar8 s = case foldr' op (Octets 0 []) s of
568579
Octets n ws -> liftTyped (unsafePackLenBytes n ws)
569580
Hichar i w -> liftCode $ fail $ "non-octet character '\\" ++
570581
show w ++ "' at offset: " ++ show i
571582
where
572-
op (fromIntegral . fromEnum -> !w) acc
583+
op :: Char -> S2W -> S2W
584+
op (fromIntegral . fromEnum -> !(w :: Word)) acc
573585
| w <= 0xff = case acc of
574586
Octets i ws -> Octets (i + 1) (fromIntegral w : ws)
575587
Hichar i w' -> Hichar (i + 1) w'
576588
| otherwise = Hichar 0 w
577589

578-
data H2W = Hex {-# UNPACK #-} !Int [Word8]
579-
| Odd {-# UNPACK #-} !Int {-# UNPACK #-} !Word [Word8]
580-
| Bad {-# UNPACK #-} !Int {-# UNPACK #-} !Word
581-
582590
-- | Template Haskell splice to convert hex-encoded string constants to compile-time
583591
-- ByteString literals. The input string is validated to ensure that it consists of
584592
-- an even number of valid hexadecimal digits (case insensitive).
@@ -589,11 +597,7 @@ data H2W = Hex {-# UNPACK #-} !Int [Word8]
589597
-- > ehloCmd :: ByteString
590598
-- > ehloCmd = $$(literalFromHex "45484c4F")
591599
--
592-
#if MIN_VERSION_template_haskell(2,17,0)
593-
literalFromHex :: (MonadFail m, TH.Quote m) => String -> TH.Code m ByteString
594-
#else
595-
literalFromHex :: String -> TH.Q (TH.TExp ByteString)
596-
#endif
600+
literalFromHex :: String -> THLift ByteString
597601
literalFromHex "" = [||empty||]
598602
literalFromHex s =
599603
case foldr' op (Hex 0 []) s of
@@ -612,7 +616,8 @@ literalFromHex s =
612616
c2d :: Char -> Word
613617
c2d c = fromIntegral (fromEnum c) - 0x30
614618

615-
op (c2d -> d) acc
619+
op :: Char -> H2W -> H2W
620+
op (c2d -> !(d :: Word)) acc
616621
| d <= 9 = case acc of
617622
Hex i ws -> Odd i d ws
618623
Odd i lo ws -> Hex (i+1) $ fromIntegral ((d `shiftL` 4 .|. lo)) : ws

0 commit comments

Comments
 (0)