Skip to content

Commit ccfab36

Browse files
authored
Merge pull request #3 from haskell/index-and-write-word16-array
Index and write word16 array
2 parents 13d2830 + e0b6a51 commit ccfab36

File tree

3 files changed

+26
-50
lines changed

3 files changed

+26
-50
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: [ubuntu-latest]
17-
ghc: ['8.0', '8.2', '8.4', '8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6', '9.8']
17+
ghc: ['8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6', '9.8']
1818
cabal: ['3.8.1.0']
1919
include:
2020
- os: macOS-latest

System/OsString/Data/ByteString/Short/Internal.hs

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
{-# LANGUAGE ViewPatterns #-}
77
{-# LANGUAGE UnliftedFFITypes #-}
88

9+
-- Required for WORDS_BIGENDIAN
10+
#include <ghcautoconf.h>
11+
912
-- |
1013
-- Module : System.OsString.Data.ByteString.Short.Internal
1114
-- Copyright : © 2022 Julian Ospald
@@ -21,7 +24,6 @@ module System.OsString.Data.ByteString.Short.Internal where
2124

2225
import Control.Monad.ST
2326
import Control.Exception (assert, throwIO)
24-
import Data.Bits (Bits(..))
2527
import Data.ByteString.Short.Internal (ShortByteString(..), length)
2628
#if !MIN_VERSION_base(4,11,0)
2729
import Data.Semigroup
@@ -282,64 +284,38 @@ packLenWord16Rev len ws0 =
282284
go mba (i - 2) ws
283285

284286

285-
-- | This isn't strictly Word16 array write. Instead it's two consecutive Word8 array
286-
-- writes to avoid endianness issues due to primops doing automatic alignment based
287-
-- on host platform. We want to always write LE to the byte array.
287+
-- | Encode Word16 as little-endian.
288288
writeWord16Array :: MBA s
289289
-> Int -- ^ Word8 index (not Word16)
290290
-> Word16
291291
-> ST s ()
292-
writeWord16Array (MBA# mba#) (I# i#) (W16# w#) =
293-
case encodeWord16LE# w# of
294-
(# lsb#, msb# #) ->
295-
ST (\s -> case writeWord8Array# mba# i# lsb# s of
296-
s' -> (# s', () #)) >>
297-
ST (\s -> case writeWord8Array# mba# (i# +# 1#) msb# s of
298-
s' -> (# s', () #))
292+
writeWord16Array (MBA# mba#) (I# i#) (W16# w#) = ST $ \s ->
293+
case writeWord8ArrayAsWord16# mba# i# (word16ToLE# w#) s of
294+
s' -> (# s', () #)
299295

300296
indexWord8Array :: BA
301297
-> Int -- ^ Word8 index
302298
-> Word8
303299
indexWord8Array (BA# ba#) (I# i#) = W8# (indexWord8Array# ba# i#)
304300

305-
-- | This isn't strictly Word16 array read. Instead it's two Word8 array reads
306-
-- to avoid endianness issues due to primops doing automatic alignment based
307-
-- on host platform. We expect the byte array to be LE always.
301+
-- | Decode Word16 from little-endian.
308302
indexWord16Array :: BA
309303
-> Int -- ^ Word8 index (not Word16)
310304
-> Word16
311-
indexWord16Array ba i = fromIntegral lsb .|. (fromIntegral msb `shiftL` 8)
312-
where
313-
lsb = indexWord8Array ba i
314-
msb = indexWord8Array ba (i + 1)
315-
316-
#if !MIN_VERSION_base(4,16,0)
317-
318-
encodeWord16LE# :: Word# -- ^ Word16
319-
-> (# Word#, Word# #) -- ^ Word8 (LSB, MSB)
320-
encodeWord16LE# x# = (# x# `and#` int2Word# 0xff#
321-
, x# `and#` int2Word# 0xff00# `shiftRL#` 8# #)
322-
323-
decodeWord16LE# :: (# Word#, Word# #) -- ^ Word8 (LSB, MSB)
324-
-> Word# -- ^ Word16
325-
decodeWord16LE# (# lsb#, msb# #) = msb# `shiftL#` 8# `or#` lsb#
305+
indexWord16Array (BA# ba#) (I# i#) =
306+
W16# (word16FromLE# (indexWord8ArrayAsWord16# ba# i#))
326307

308+
#if MIN_VERSION_base(4,16,0)
309+
word16ToLE#, word16FromLE# :: Word16# -> Word16#
327310
#else
328-
329-
encodeWord16LE# :: Word16# -- ^ Word16
330-
-> (# Word8#, Word8# #) -- ^ Word8 (LSB, MSB)
331-
encodeWord16LE# x# = (# word16ToWord8# x#
332-
, word16ToWord8# (x# `uncheckedShiftRLWord16#` 8#) #)
333-
where
334-
word16ToWord8# y = wordToWord8# (word16ToWord# y)
335-
336-
decodeWord16LE# :: (# Word8#, Word8# #) -- ^ Word8 (LSB, MSB)
337-
-> Word16# -- ^ Word16
338-
decodeWord16LE# (# lsb#, msb# #) = ((word8ToWord16# msb# `uncheckedShiftLWord16#` 8#) `orWord16#` word8ToWord16# lsb#)
339-
where
340-
word8ToWord16# y = wordToWord16# (word8ToWord# y)
341-
311+
word16ToLE#, word16FromLE# :: Word# -> Word#
312+
#endif
313+
#ifdef WORDS_BIGENDIAN
314+
word16ToLE# = byteSwap16#
315+
#else
316+
word16ToLE# w# = w#
342317
#endif
318+
word16FromLE# = word16ToLE#
343319

344320
setByteArray :: MBA s -> Int -> Int -> Int -> ST s ()
345321
setByteArray (MBA# dst#) (I# off#) (I# len#) (I# c#) =

os-string.cabal

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ category: System
1616
build-type: Simple
1717
synopsis: Library for manipulating Operating system strings.
1818
tested-with:
19-
GHC ==8.0.2
20-
|| ==8.2.2
21-
|| ==8.4.4
22-
|| ==8.6.5
19+
GHC ==8.6.5
2320
|| ==8.8.4
2421
|| ==8.10.7
2522
|| ==9.0.2
26-
|| ==9.2.3
23+
|| ==9.2.8
24+
|| ==9.4.8
25+
|| ==9.6.3
26+
|| ==9.8.1
2727

2828
description:
2929
This package provides functionality for manipulating @OsString@ values, and is shipped with <https://www.haskell.org/ghc/ GHC>.
@@ -63,7 +63,7 @@ library
6363

6464
default-language: Haskell2010
6565
build-depends:
66-
, base >=4.9 && <4.20
66+
, base >=4.12.0.0 && <4.20
6767
, bytestring >=0.11.3.0
6868
, deepseq
6969
, exceptions

0 commit comments

Comments
 (0)