Skip to content

Commit 84bd935

Browse files
authored
Merge pull request #904 from haskell/internal-modules
Add internal modules for bytestring and text compat
2 parents 1145745 + 7e289c5 commit 84bd935

File tree

6 files changed

+97
-27
lines changed

6 files changed

+97
-27
lines changed

aeson.cabal

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ library
8484

8585
other-modules:
8686
Data.Aeson.Encoding.Builder
87+
Data.Aeson.Internal.ByteString
8788
Data.Aeson.Internal.Functions
89+
Data.Aeson.Internal.Text
8890
Data.Aeson.Parser.Time
8991
Data.Aeson.Parser.Unescape
9092
Data.Aeson.Types.Class
@@ -146,7 +148,7 @@ library
146148
cpp-options: -DCFFI
147149
hs-source-dirs: src-ffi
148150
other-modules: Data.Aeson.Parser.UnescapeFFI
149-
build-depends: text < 2.0
151+
build-depends: text <2.0
150152

151153
if flag(ordered-keymap)
152154
cpp-options: -DUSE_ORDEREDMAP=1
@@ -157,7 +159,6 @@ test-suite aeson-tests
157159
hs-source-dirs: tests
158160
main-is: Tests.hs
159161
ghc-options: -Wall -threaded -rtsopts
160-
161162
other-modules:
162163
DataFamilies.Encoders
163164
DataFamilies.Instances

benchmarks/aeson-benchmarks.cabal

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ library
7272
Data.Aeson.Encoding.Builder
7373
Data.Aeson.Encoding.Internal
7474
Data.Aeson.Internal
75+
Data.Aeson.Internal.ByteString
7576
Data.Aeson.Internal.Functions
77+
Data.Aeson.Internal.Text
7678
Data.Aeson.Internal.Time
7779
Data.Aeson.Key
7880
Data.Aeson.KeyMap
@@ -122,6 +124,7 @@ executable aeson-benchmark-suite
122124
, time
123125
, unordered-containers
124126
, vector
127+
125128
other-modules:
126129
AesonFoldable
127130
AesonMap
@@ -167,5 +170,4 @@ executable aeson-benchmark-suite
167170
other-modules: Compare.BufferBuilder
168171

169172
-- this module won't
170-
other-modules:
171-
UnescapePureText1
173+
other-modules: UnescapePureText1

src-pure/Data/Aeson/Parser/UnescapePure.hs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ import Foreign.ForeignPtr (withForeignPtr)
1717
import Foreign.Ptr (Ptr, plusPtr)
1818
import Foreign.Storable (peek)
1919

20-
import qualified Data.ByteString.Internal as BS
2120
import qualified Data.Primitive as P
2221
import qualified Data.Text.Array as T
2322
import qualified Data.Text.Internal as T
2423

24+
import Data.Aeson.Internal.ByteString
25+
2526
#if !MIN_VERSION_text(2,0,0)
2627
import Data.Word (Word16)
2728
#endif
2829

30+
2931
unescapeText :: ByteString -> Either UnicodeException Text
3032
unescapeText = unsafeDupablePerformIO . try . unescapeTextIO
3133

@@ -48,11 +50,10 @@ unescapeTextIO :: ByteString -> IO Text
4850

4951
#if MIN_VERSION_text(2,0,0)
5052

51-
unescapeTextIO bs = case bs of
52-
BS.PS fptr off len -> withForeignPtr fptr $ \bsPtr -> do
53-
let begin, end :: Ptr Word8
54-
begin = plusPtr bsPtr off
55-
end = plusPtr begin len
53+
unescapeTextIO bs = withBS bs $ \fptr len ->
54+
withForeignPtr fptr $ \begin -> do
55+
let end :: Ptr Word8
56+
end = plusPtr begin len
5657

5758
arr <- P.newPrimArray len
5859

@@ -397,11 +398,10 @@ unescapeTextIO bs = case bs of
397398
state_start (0 :: Int) begin
398399
#else
399400

400-
unescapeTextIO bs = case bs of
401-
BS.PS fptr off len -> withForeignPtr fptr $ \bsPtr -> do
402-
let begin, end :: Ptr Word8
403-
begin = plusPtr bsPtr off
404-
end = plusPtr begin len
401+
unescapeTextIO bs = withBS bs $ \fptr len ->
402+
withForeignPtr fptr $ \begin -> do
403+
let end :: Ptr Word8
404+
end = plusPtr begin len
405405

406406
arr <- P.newPrimArray len
407407

src/Data/Aeson/Internal/ByteString.hs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{-# LANGUAGE BangPatterns #-}
2+
{-# LANGUAGE CPP #-}
3+
{-# LANGUAGE MagicHash #-}
4+
module Data.Aeson.Internal.ByteString (
5+
mkBS,
6+
withBS,
7+
) where
8+
9+
import Data.ByteString.Internal (ByteString (..))
10+
import Data.Word (Word8)
11+
import Foreign.ForeignPtr (ForeignPtr)
12+
13+
#if !MIN_VERSION_bytestring(0,11,0)
14+
#if MIN_VERSION_base(4,10,0)
15+
import GHC.ForeignPtr (plusForeignPtr)
16+
#else
17+
import GHC.ForeignPtr (ForeignPtr(ForeignPtr))
18+
import GHC.Types (Int (..))
19+
import GHC.Prim (plusAddr#)
20+
#endif
21+
#endif
22+
23+
mkBS :: ForeignPtr Word8 -> Int -> ByteString
24+
#if MIN_VERSION_bytestring(0,11,0)
25+
mkBS dfp n = BS dfp n
26+
#else
27+
mkBS dfp n = PS dfp 0 n
28+
#endif
29+
{-# INLINE mkBS #-}
30+
31+
withBS :: ByteString -> (ForeignPtr Word8 -> Int -> r) -> r
32+
#if MIN_VERSION_bytestring(0,11,0)
33+
withBS (BS !sfp !slen) kont = kont sfp slen
34+
#else
35+
withBS (PS !sfp !soff !slen) kont = kont (plusForeignPtr sfp soff) slen
36+
#endif
37+
{-# INLINE withBS #-}
38+
39+
#if !MIN_VERSION_bytestring(0,11,0)
40+
#if !MIN_VERSION_base(4,10,0)
41+
-- |Advances the given address by the given offset in bytes.
42+
--
43+
-- The new 'ForeignPtr' shares the finalizer of the original,
44+
-- equivalent from a finalization standpoint to just creating another
45+
-- reference to the original. That is, the finalizer will not be
46+
-- called before the new 'ForeignPtr' is unreachable, nor will it be
47+
-- called an additional time due to this call, and the finalizer will
48+
-- be called with the same address that it would have had this call
49+
-- not happened, *not* the new address.
50+
plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
51+
plusForeignPtr (ForeignPtr addr guts) (I# offset) = ForeignPtr (plusAddr# addr offset) guts
52+
{-# INLINE [0] plusForeignPtr #-}
53+
{-# RULES
54+
"ByteString plusForeignPtr/0" forall fp .
55+
plusForeignPtr fp 0 = fp
56+
#-}
57+
#endif
58+
#endif

src/Data/Aeson/Internal/Text.hs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{-# LANGUAGE CPP #-}
2+
module Data.Aeson.Internal.Text (
3+
unsafeDecodeASCII,
4+
) where
5+
6+
import Data.ByteString (ByteString)
7+
import Data.Text (Text)
8+
9+
import qualified Data.Text.Encoding as TE
10+
11+
-- | The input is assumed to contain only 7bit ASCII characters (i.e. @< 0x80@).
12+
-- We use TE.decodeLatin1 here because TE.decodeASCII is currently (text-1.2.4.0)
13+
-- deprecated and equal to TE.decodeUtf8, which is slower than TE.decodeLatin1.
14+
unsafeDecodeASCII :: ByteString -> Text
15+
16+
#if MIN_VERSION_text(2,0,0)
17+
unsafeDecodeASCII = TE.decodeASCII
18+
#else
19+
unsafeDecodeASCII = TE.decodeLatin1
20+
#endif

src/Data/Aeson/Parser/Internal.hs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ import Data.Function (fix)
5959
import Data.Functor.Compat (($>))
6060
import Data.Scientific (Scientific)
6161
import Data.Text (Text)
62-
import qualified Data.Text.Encoding as TE
6362
import Data.Vector (Vector)
6463
import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
6564
import qualified Data.Attoparsec.ByteString as A
@@ -72,6 +71,7 @@ import qualified Data.ByteString.Lazy.Char8 as C
7271
import qualified Data.ByteString.Builder as B
7372
import qualified Data.Scientific as Sci
7473
import Data.Aeson.Parser.Unescape (unescapeText)
74+
import Data.Aeson.Internal.Text
7575

7676
-- $setup
7777
-- >>> :set -XOverloadedStrings
@@ -342,17 +342,6 @@ jstring_ = do
342342
Just w | w < 0x20 -> fail "unescaped control character"
343343
_ -> jstringSlow s
344344

345-
#if MIN_VERSION_text(2,0,0)
346-
unsafeDecodeASCII :: B.ByteString -> Text
347-
unsafeDecodeASCII = TE.decodeASCII
348-
#else
349-
-- | The input is assumed to contain only 7bit ASCII characters (i.e. @< 0x80@).
350-
-- We use TE.decodeLatin1 here because TE.decodeASCII is currently (text-1.2.4.0)
351-
-- deprecated and equal to TE.decodeUtf8, which is slower than TE.decodeLatin1.
352-
unsafeDecodeASCII :: B.ByteString -> Text
353-
unsafeDecodeASCII = TE.decodeLatin1
354-
#endif
355-
356345
jstringSlow :: B.ByteString -> Parser Text
357346
{-# INLINE jstringSlow #-}
358347
jstringSlow s' = {-# SCC "jstringSlow" #-} do

0 commit comments

Comments
 (0)