{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ScopedTypeVariables #-} -- | -- Module : Codec.CBOR.ByteArray -- Copyright : (c) Ben Gamari 2017-2018 -- License : BSD3-style (see LICENSE.txt) -- -- Maintainer : duncan@community.haskell.org -- Stability : experimental -- Portability : non-portable (GHC extensions) -- -- A ByteArray with more instances than 'Data.Primitive.ByteArray.ByteArray'. -- Some day when these instances are reliably available from @primitive@ we can -- likely replace this with 'Data.Primitive.ByteArray.ByteArray'. -- module Codec.CBOR.ByteArray ( -- * Simple byte arrays ByteArray(..) , sizeofByteArray -- * Conversions , fromShortByteString , toShortByteString , fromByteString , toBuilder , toSliced ) where import Data.Char (ord) import Data.Word import GHC.Exts (IsList(..), IsString(..)) import qualified Data.Primitive.ByteArray as Prim import qualified Data.ByteString as BS import qualified Data.ByteString.Short as BSS import qualified Data.ByteString.Short.Internal as BSS import qualified Data.ByteString.Builder as BSB import qualified Codec.CBOR.ByteArray.Sliced as Sliced import Codec.CBOR.ByteArray.Internal newtype ByteArray = BA {unBA :: Prim.ByteArray} sizeofByteArray :: ByteArray -> Int {-# INLINE sizeofByteArray #-} sizeofByteArray (BA ba) = Prim.sizeofByteArray ba fromShortByteString :: BSS.ShortByteString -> ByteArray fromShortByteString (BSS.SBS ba) = BA (Prim.ByteArray ba) toShortByteString :: ByteArray -> BSS.ShortByteString toShortByteString (BA (Prim.ByteArray ba)) = BSS.SBS ba fromByteString :: BS.ByteString -> ByteArray fromByteString = fromShortByteString . BSS.toShort toBuilder :: ByteArray -> BSB.Builder toBuilder = Sliced.toBuilder . toSliced toSliced :: ByteArray -> Sliced.SlicedByteArray toSliced ba@(BA arr) = Sliced.SBA arr 0 (sizeofByteArray ba) instance Show ByteArray where showsPrec _ = shows . toSliced instance Eq ByteArray where ba1 == ba2 = toSliced ba1 == toSliced ba2 instance Ord ByteArray where ba1 `compare` ba2 = toSliced ba1 `compare` toSliced ba2 instance IsString ByteArray where fromString = fromList . map checkedOrd where checkedOrd c | c > '\xff' = error "IsString(Codec.CBOR.ByteArray): Non-ASCII character" | otherwise = fromIntegral $ ord c instance IsList ByteArray where type Item ByteArray = Word8 fromList xs = fromListN (Prelude.length xs) xs fromListN n xs = let arr = mkByteArray n xs in BA arr toList ba@(BA arr) = foldrByteArray (:) [] 0 (sizeofByteArray ba) arr