Skip to content

Commit 904cccb

Browse files
committed
add packZipWith for backward compatibility with GHC 8.10.7
1 parent 135e7fe commit 904cccb

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/Simplex/Messaging/Agent/Store/SQLite.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB
7070
import Simplex.Messaging.Agent.Store.SQLite.Util
7171
import Simplex.Messaging.Agent.Store.Shared (Migration (..), MigrationConfig (..), MigrationError (..))
7272
import qualified Simplex.Messaging.Crypto as C
73-
import Simplex.Messaging.Util (ifM, safeDecodeUtf8)
73+
import Simplex.Messaging.Util (ifM, packZipWith, safeDecodeUtf8)
7474
import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist)
7575
import System.FilePath (takeDirectory, takeFileName, (</>))
7676

@@ -146,7 +146,8 @@ sqliteXorMd5Combine = mkSQLiteFunc $ \cxt args -> do
146146
SQLite3.funcResultBlob cxt $ xorMd5Combine idsHash rId
147147

148148
xorMd5Combine :: ByteString -> ByteString -> ByteString
149-
xorMd5Combine idsHash rId = B.packZipWith xor idsHash $ C.md5Hash rId
149+
xorMd5Combine idsHash rId = packZipWith xor idsHash $ C.md5Hash rId
150+
{-# INLINE xorMd5Combine #-}
150151

151152
closeDBStore :: DBStore -> IO ()
152153
closeDBStore st@DBStore {dbClosed} =

src/Simplex/Messaging/Util.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE BangPatterns #-}
12
{-# LANGUAGE MonadComprehensions #-}
23
{-# LANGUAGE OverloadedStrings #-}
34
{-# LANGUAGE ScopedTypeVariables #-}
@@ -15,6 +16,7 @@ import qualified Data.Aeson as J
1516
import Data.Bifunctor (first, second)
1617
import Data.ByteString.Char8 (ByteString)
1718
import qualified Data.ByteString.Char8 as B
19+
import Data.ByteString.Internal (toForeignPtr, unsafeCreate)
1820
import qualified Data.ByteString.Lazy.Char8 as LB
1921
import Data.IORef
2022
import Data.Int (Int64)
@@ -29,6 +31,9 @@ import qualified Data.Text as T
2931
import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
3032
import Data.Time (NominalDiffTime)
3133
import Data.Tuple (swap)
34+
import Data.Word (Word8)
35+
import Foreign.ForeignPtr (withForeignPtr)
36+
import Foreign.Storable (peekByteOff, pokeByteOff)
3237
import GHC.Conc (labelThread, myThreadId, threadDelay)
3338
import UnliftIO hiding (atomicModifyIORef')
3439
import qualified UnliftIO.Exception as UE
@@ -156,6 +161,27 @@ mapAccumLM_NonEmpty
156161
mapAccumLM_NonEmpty f s (x :| xs) =
157162
[(s2, x' :| xs') | (s1, x') <- f s x, (s2, xs') <- mapAccumLM_List f s1 xs]
158163

164+
-- | Optimized from bytestring package for GHC 8.10.7 compatibility
165+
packZipWith :: (Word8 -> Word8 -> Word8) -> ByteString -> ByteString -> ByteString
166+
packZipWith f s1 s2 =
167+
unsafeCreate len $ \r ->
168+
withForeignPtr fp1 $ \p1 ->
169+
withForeignPtr fp2 $ \p2 -> zipWith_ p1 p2 r
170+
where
171+
zipWith_ p1 p2 r = go 0
172+
where
173+
go :: Int -> IO ()
174+
go !n
175+
| n >= len = pure ()
176+
| otherwise = do
177+
x <- peekByteOff p1 (off1 + n)
178+
y <- peekByteOff p2 (off2 + n)
179+
pokeByteOff r n (f x y)
180+
go (n + 1)
181+
(fp1, off1, l1) = toForeignPtr s1
182+
(fp2, off2, l2) = toForeignPtr s2
183+
len = min l1 l2
184+
159185
tryWriteTBQueue :: TBQueue a -> a -> STM Bool
160186
tryWriteTBQueue q a = do
161187
full <- isFullTBQueue q

0 commit comments

Comments
 (0)