packages feed

Z-Data 0.7.1.0 → 0.7.2.0

raw patch · 6 files changed

+120/−63 lines, 6 filesdep ~integer-gmpPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: integer-gmp

API changes (from Hackage documentation)

+ Z.Data.CBytes: fromMutablePrimArray :: PrimMonad m => MutablePrimArray (PrimState m) Word8 -> m CBytes
+ Z.Data.CBytes: toBuilder' :: CBytes -> Builder ()
+ Z.Data.CBytes: toBytes' :: CBytes -> Bytes

Files

ChangeLog.md view
@@ -1,11 +1,16 @@ # Revision history for Z-Data -## 0.7.1.0  -- 2020-03-03+## 0.7.2.0  -- 2021-03-22 +* Add `fromMutablePrimArray` for constructing CBytes.+* Add `toBytes'/toBuilder'`(convert with the \NUL terminator) to `Z.Data.CBytes`.++## 0.7.1.0  -- 2021-03-03+ * Add `CPtr` type, a more lightweight foreign pointer. * Add `toLower/toUpper/toLowerLatin/toUpperLatin` to `Z.Data.ASCII`. -## 0.7.0.0  -- 2020-03-03+## 0.7.0.0  -- 2021-03-03  * Add more patterns to `Z.Data.ASCII`. * Fix a bug in `Z.Data.Vector.Search` where needle is a singleton.@@ -13,7 +18,7 @@ * Add `scientific'` to `Z.Data.Builder`, Add more `Print` instances. * Bump deps to support GHC 9.0. -## 0.6.1.0  -- 2020-02-04+## 0.6.1.0  -- 2021-02-04  * Add `key` and `nth` lens to `Z.Data.JSON.Value` for manipulating nested value more easily. * Port patch from bytestring #301 #310 #315, Improve `stime`, `sconcat`, `intersperse`.@@ -24,20 +29,20 @@ * Add `displayWidth` to `Z.Data.Text`. * Move `floatToScientific/doubleToScientific` to `Z.Data.JSON.Value`. -## 0.6.0.0  -- 2020-02-04+## 0.6.0.0  -- 2021-02-04  * Add `primArrayFromBE/primArrayFromBE` to `Z.Data.Array.Unaligned`. * Change `[Char]` 's JSON instance to use JSON text, Add `Bytes` 's JSON instance to use base64 encoding. * Add `escapeCBytes`, `toEscapedText` to `Z.Data.CBytes`, change `CBytes` 's JSON instance to use base64 encoding. -## 0.5.0.0  -- 2020-01-15+## 0.5.0.0  -- 2021-01-15  * Add `ParseChunks` type alias, remove `parseChunks'` from `Z.Data.JSON`. * Change JSON instance of `Data.Version` to use JSON Array. * Add `fromByteString` and `toByteString` to `Z.Foreign`. * Change license's copyright to test --test-show-details=direct -## 0.4.0.0  -- 2020-01-11+## 0.4.0.0  -- 2021-01-11  * Merge `FromValue`, `ToValue`, `EncodeJSON` to `JSON` class, add instances for containers. * A new `Z.Data.JSON.Converter` module to be reused in other protocol decoding.@@ -100,7 +105,7 @@ * Remove `Str` newtype. * Make `CBytes` a newtype. * Add JSON instances for `ExitCode`, Add Unaligned instances for `Ptr a`.-* Use type alias instead of newtypes for `Locale`, `Category` in `Z.Data.Text`. +* Use type alias instead of newtypes for `Locale`, `Category` in `Z.Data.Text`.  ## 0.1.6.0  -- 2020-10-09 
Z-Data.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               Z-Data-version:            0.7.1.0+version:            0.7.2.0 synopsis:           Array, vector and text description:        This package provides array, slice and text operations license:            BSD-3-Clause@@ -365,4 +365,4 @@    else     cpp-options:   -DINTEGER_GMP-    build-depends: integer-gmp >=0.2 && <1.1+    build-depends: integer-gmp >=0.2 && <1.2
Z/Data/CBytes.hs view
@@ -15,8 +15,9 @@ module Z.Data.CBytes   (  -- * The CBytes type     CBytes(CB)-  , rawPrimArray, fromPrimArray-  , toBytes, fromBytes, toText, toTextMaybe, fromText, toBuilder, buildCBytes+  , rawPrimArray, fromPrimArray, fromMutablePrimArray+  , toBytes, toBytes', fromBytes, toText, toTextMaybe, fromText+  , toBuilder, toBuilder', buildCBytes   , pack   , unpack   , null, length@@ -29,47 +30,47 @@   , CString   ) where +import           Control.Applicative       ((<|>)) import           Control.DeepSeq-import           Control.Monad-import           Control.Applicative        ((<|>)) import           Control.Exception+import           Control.Monad import           Control.Monad.Primitive import           Control.Monad.ST import           Data.Bits-import           Data.Foldable              (foldlM)-import           Data.Hashable              (Hashable(..))-import qualified Data.List                  as List+import           Data.Foldable             (foldlM)+import           Data.Hashable             (Hashable (..))+import qualified Data.List                 as List import           Data.Primitive.PrimArray import           Data.Word import           Foreign.C.String-import           GHC.Exts import           GHC.CString+import           GHC.Exts import           GHC.Ptr import           GHC.Stack-import           Prelude                    hiding (all, any, appendFile, break,-                                                concat, concatMap, drop, dropWhile,-                                                elem, filter, foldl, foldl1, foldr,-                                                foldr1, getContents, getLine, head,-                                                init, interact, last, length, lines,-                                                map, maximum, minimum, notElem, null,-                                                putStr, putStrLn, readFile, replicate,-                                                reverse, scanl, scanl1, scanr, scanr1,-                                                span, splitAt, tail, take, takeWhile,-                                                unlines, unzip, writeFile, zip,-                                                zipWith)+import           Prelude                   hiding (all, any, appendFile, break,+                                            concat, concatMap, drop, dropWhile,+                                            elem, filter, foldl, foldl1, foldr,+                                            foldr1, getContents, getLine, head,+                                            init, interact, last, length, lines,+                                            map, maximum, minimum, notElem,+                                            null, putStr, putStrLn, readFile,+                                            replicate, reverse, scanl, scanl1,+                                            scanr, scanr1, span, splitAt, tail,+                                            take, takeWhile, unlines, unzip,+                                            writeFile, zip, zipWith)+import           System.IO.Unsafe          (unsafeDupablePerformIO)+import           Test.QuickCheck.Arbitrary (Arbitrary (..), CoArbitrary (..))+import           Text.Read                 (Read (..)) import           Z.Data.Array-import qualified Z.Data.Builder             as B-import qualified Z.Data.Text                as T-import qualified Z.Data.Text.Print          as T-import qualified Z.Data.Text.UTF8Codec      as T-import qualified Z.Data.JSON.Base           as JSON-import           Z.Data.JSON.Base           ((.=), (.!), (.:))-import           Z.Data.Text.UTF8Codec      (encodeCharModifiedUTF8, decodeChar)-import qualified Z.Data.Vector.Base         as V-import           Z.Foreign                  hiding (fromStdString)-import           System.IO.Unsafe           (unsafeDupablePerformIO)-import           Test.QuickCheck.Arbitrary  (Arbitrary(..), CoArbitrary(..))-import           Text.Read                 (Read(..))+import qualified Z.Data.Builder            as B+import           Z.Data.JSON.Base          ((.!), (.:), (.=))+import qualified Z.Data.JSON.Base          as JSON+import qualified Z.Data.Text               as T+import qualified Z.Data.Text.Print         as T+import           Z.Data.Text.UTF8Codec     (decodeChar, encodeCharModifiedUTF8)+import qualified Z.Data.Text.UTF8Codec     as T+import qualified Z.Data.Vector.Base        as V+import           Z.Foreign                 hiding (fromStdString)  -- | A efficient wrapper for short immutable null-terminated byte sequences which can be -- automatically freed by ghc garbage collector.@@ -100,13 +101,13 @@         rawPrimArray :: PrimArray Word8     } --- | Constuctor a 'CBytes' from arbitrary array, result will be trimmed down to first @\\NUL@ byte if there's any.+-- | Construct a 'CBytes' from arbitrary array, result will be trimmed down to first @\\NUL@ byte if there's any. fromPrimArray :: PrimArray Word8 -> CBytes {-# INLINE fromPrimArray #-} fromPrimArray arr = runST (do     let l = case V.elemIndex 0 arr of             Just i -> i-            _ -> sizeofPrimArray arr+            _      -> sizeofPrimArray arr     if l+1 == sizeofPrimArray arr     then return (CBytes arr)     else do@@ -117,6 +118,31 @@         pa <- unsafeFreezePrimArray mpa         return (CBytes pa)) +-- | Construct a 'CBytes' from a 'MutablePrimArray'.+--+-- Result will be shrinked to first @\\NUL@ byte without copy. If there is no+-- @\\NUL@ found in the array, We will resize the origin MutablePrimArray, so,+-- to avoid undefined behaviour, the original MutablePrimArray shall not be+-- accessed anymore. Moreover, no reference to the old one should be kept in+-- order to allow garbage collection of the original MutablePrimArray in case+-- a new MutablePrimArray had to be allocated.+fromMutablePrimArray+    :: PrimMonad m+    => MutablePrimArray (PrimState m) Word8+    -> m CBytes+{-# INLINE fromMutablePrimArray #-}+fromMutablePrimArray marr = do+    let l = sizeofMutablePrimArray marr+    arr <- unsafeFreezePrimArray marr+    marr' <- case V.elemIndex 0 arr of+        Just i -> shrinkMutablePrimArray marr (i + 1) >> return marr+        _ -> do+            marr' <- resizeMutablePrimArray marr (l + 1)+            writePrimArray marr' l 0+            return marr'+    !pa <- unsafeFreezePrimArray marr'+    return $ CBytes pa+ -- | Use this pattern to match or construct 'CBytes', result will be trimmed down to first @\\NUL@ byte if there's any. pattern CB :: V.Bytes -> CBytes {-# COMPLETE CB #-}@@ -222,11 +248,11 @@                 <|> JSON.withFlatMapR "Z.Data.CBytes" (\ o -> fromBytes <$> o .: "base64") v     {-# INLINE toValue #-}     toValue cbytes = case toTextMaybe cbytes of-        Just t -> JSON.toValue t+        Just t  -> JSON.toValue t         Nothing -> JSON.object $ [ "base64" .= toBytes cbytes ]     {-# INLINE encodeJSON #-}     encodeJSON cbytes = case toTextMaybe cbytes of-        Just t -> JSON.encodeJSON t+        Just t  -> JSON.encodeJSON t         Nothing -> JSON.object' $ "base64" .! toBytes cbytes  -- | Concatenate two 'CBytes'.@@ -426,7 +452,7 @@ {-# INLINE null #-} null (CBytes pa) = indexPrimArray pa 0 == 0 --- | /O(1)/, Return the BTYE length of 'CBytes'.+-- | /O(1)/, Return the BTYE length of 'CBytes' without NULL terminator. -- length :: CBytes -> Int {-# INLINE length #-}@@ -437,6 +463,11 @@ {-# INLINABLE toBytes #-} toBytes (CBytes arr) = V.PrimVector arr 0 (sizeofPrimArray arr - 1) +-- | /O(1)/, convert to 'V.Bytes' with its NULL terminator.+toBytes' :: CBytes -> V.Bytes+{-# INLINABLE toBytes' #-}+toBytes' (CBytes arr) = V.PrimVector arr 0 (sizeofPrimArray arr)+ -- | /O(n)/, convert from 'V.Bytes' -- -- Result will be trimmed down to first @\\NUL@ byte if there's any.@@ -449,7 +480,7 @@     | otherwise = runST (do         let l' = case V.elemIndex 0 v of                 Just i -> i-                _ -> l+                _      -> l         mpa <- newPrimArray (l'+1)         copyPrimArray mpa 0 arr s l'         writePrimArray mpa l' 0      -- the \\NUL terminator@@ -482,11 +513,20 @@ -- This function is different from 'T.Print' instance in that it directly write byte sequence without -- checking if it's UTF8 encoded. toBuilder :: CBytes -> B.Builder ()+{-# INLINABLE toBuilder #-} toBuilder = B.bytes . toBytes --- | Build a 'CBytes' with builder, result will be trimmed down to first @\\NUL@ byte if there's any.+-- | Write 'CBytes' \'s byte sequence to buffer, with its NULL terminator.+--+toBuilder' :: CBytes -> B.Builder ()+{-# INLINABLE toBuilder' #-}+toBuilder' = B.bytes . toBytes'++-- | Build a 'CBytes' with builder, will automatically be trimmed down to first @\\NUL@ byte if there's any,+-- or append with one if there's none. buildCBytes :: B.Builder a -> CBytes-buildCBytes = fromBytes . B.build+{-# INLINABLE buildCBytes #-}+buildCBytes b = fromBytes (B.build (b >> B.word8 0))  -------------------------------------------------------------------------------- 
Z/Data/Parser/Base.hs view
@@ -731,7 +731,7 @@         else kf ["Z.Data.Parser.Base.bytes: mismatch bytes"] inp)  --- | Same as 'bytes' but ignoring case.+-- | Same as 'bytes' but ignoring ASCII case. bytesCI :: V.Bytes -> Parser () {-# INLINE bytesCI #-} bytesCI bs = do
test/Z/Data/CBytesSpec.hs view
@@ -1,23 +1,24 @@-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}  module Z.Data.CBytesSpec where -import qualified Data.List                  as List-import qualified GHC.Exts                   as List+import           Data.Char                (ord)+import           Data.Hashable            (hash, hashWithSalt)+import qualified Data.List                as List import           Data.Word-import           Data.Hashable              (hashWithSalt, hash)-import qualified Z.Data.CBytes              as CB-import qualified Z.Data.JSON                as JSON-import           Z.Foreign-import qualified Z.Data.Vector.Base         as V+import qualified GHC.Exts                 as List import           System.IO.Unsafe+import           Test.Hspec+import           Test.Hspec.QuickCheck import           Test.QuickCheck import           Test.QuickCheck.Function import           Test.QuickCheck.Property-import           Test.Hspec-import           Test.Hspec.QuickCheck+import qualified Z.Data.CBytes            as CB+import qualified Z.Data.JSON              as JSON+import qualified Z.Data.Vector.Base       as V+import           Z.Foreign  spec :: Spec spec = describe "CBytes-base" $ do@@ -77,3 +78,15 @@             CB.toBytes (CB.pack xs) ===                 (unsafeDupablePerformIO $ CB.withCBytes (CB.pack xs) fromNullTerminated) +    describe "CBytes.fromPrimArray" $ do+        prop "CBytes pack === CBytes fromPrimArray" $ \(ASCIIString xs) ->+            let xs' = List.filter (/= '\NUL') xs+             in CB.pack xs' === CB.fromPrimArray (primArrayFromList $ map (fromIntegral . ord) xs')++    describe "CBytes.fromMutablePrimArray" $ do+        prop "CBytes pack === CBytes fromMutablePrimArray" $ \(ASCIIString xs) ->+            let xs' = List.filter (/= '\NUL') xs+             in unsafeDupablePerformIO $ do+                 marr <- unsafeThawPrimArray (primArrayFromList $ map (fromIntegral . ord) xs')+                 cb <- CB.fromMutablePrimArray marr+                 return $ CB.pack xs' === cb
test/Z/Data/Parser/BaseSpec.hs view
@@ -8,8 +8,7 @@ import           Data.Int import           GHC.Float import           Text.Printf                 (printf)-import           Data.Char                   (toLower)-import           Z.Data.ASCII                (w2c, c2w)+import           Z.Data.ASCII                (w2c, c2w, toLower) import qualified Z.Data.Parser.Base    as P import qualified Z.Data.Text as T import qualified Z.Data.Vector.Base as V@@ -99,7 +98,7 @@             parse'' (P.bytesCI . V.pack $ t) (t ++ s) === Just (V.pack s, ())          prop "bytesCI" $ \ s t ->-            parse'' (P.bytesCI . V.pack $ t) (L.map (c2w . toLower . w2c) t ++ s) === Just (V.pack s, ())+            parse'' (P.bytesCI . V.pack $ t) (L.map toLower t ++ s) === Just (V.pack s, ())          prop "atEnd" $ \ s ->             parse' P.atEnd s ===