packages feed

serialise 0.1.0.0 → 0.2.0.0

raw patch · 18 files changed

+537/−85 lines, 18 filesdep ~QuickCheckdep ~aesondep ~binaryPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: QuickCheck, aeson, binary, cborg, criterion, ghc-prim, half, tasty, tasty-quickcheck

API changes (from Hackage documentation)

- Codec.Serialise.Class: instance (GHC.Classes.Ord a, Codec.Serialise.Class.Serialise a) => Codec.Serialise.Class.Serialise (Data.Set.Internal.Set a)
- Codec.Serialise.Class: instance (GHC.Classes.Ord k, Codec.Serialise.Class.Serialise k, Codec.Serialise.Class.Serialise v) => Codec.Serialise.Class.Serialise (Data.Map.Internal.Map k v)
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.IntSet.Internal.IntSet
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.Time.Clock.Internal.UTCTime.UTCTime
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.Typeable.Internal.SomeTypeRep
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise GHC.Types.KindRep
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise GHC.Types.RuntimeRep
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise GHC.Types.TypeLitSort
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise GHC.Types.VecCount
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise GHC.Types.VecElem
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise a => Codec.Serialise.Class.Serialise (Data.IntMap.Internal.IntMap a)
- Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise a => Codec.Serialise.Class.Serialise (Data.Sequence.Internal.Seq a)
- Codec.Serialise.Class: instance forall k (a :: k -> *) i (c :: GHC.Generics.Meta). Codec.Serialise.Class.GSerialiseDecode a => Codec.Serialise.Class.GSerialiseDecode (GHC.Generics.M1 i c a)
- Codec.Serialise.Class: instance forall k (a :: k -> *) i (c :: GHC.Generics.Meta). Codec.Serialise.Class.GSerialiseEncode a => Codec.Serialise.Class.GSerialiseEncode (GHC.Generics.M1 i c a)
- Codec.Serialise.Class: instance forall k (a :: k). Data.Typeable.Internal.Typeable a => Codec.Serialise.Class.Serialise (Data.Typeable.Internal.TypeRep a)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseDecode (f GHC.Generics.:*: g)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseEncode (f GHC.Generics.:*: g)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseProd (f GHC.Generics.:*: g)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseDecode (f GHC.Generics.:+: g)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseEncode (f GHC.Generics.:+: g)
- Codec.Serialise.Class: instance forall k (f :: k -> *) (g :: k -> *). (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseSum (f GHC.Generics.:+: g)
- Codec.Serialise.Class: instance forall k i (f :: k -> *) (c :: GHC.Generics.Meta). (i ~ GHC.Generics.C, Codec.Serialise.Class.GSerialiseProd f) => Codec.Serialise.Class.GSerialiseSum (GHC.Generics.M1 i c f)
- Codec.Serialise.Class: instance forall k i (f :: k -> *) (c :: GHC.Generics.Meta). (i ~ GHC.Generics.S, Codec.Serialise.Class.GSerialiseProd f) => Codec.Serialise.Class.GSerialiseProd (GHC.Generics.M1 i c f)
+ Codec.Serialise.Class: class GSerialiseProd f
+ Codec.Serialise.Class: class GSerialiseSum f
+ Codec.Serialise.Class: conNumber :: GSerialiseSum f => f a -> Word
+ Codec.Serialise.Class: decodeSum :: GSerialiseSum f => Word -> Decoder s (f a)
+ Codec.Serialise.Class: encodeSeq :: GSerialiseProd f => f a -> Encoding
+ Codec.Serialise.Class: encodeSum :: GSerialiseSum f => f a -> Encoding
+ Codec.Serialise.Class: fieldsForCon :: GSerialiseSum f => Proxy f -> Word -> Decoder s Word
+ Codec.Serialise.Class: gdecodeSeq :: GSerialiseProd f => Decoder s (f a)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseDecode (f GHC.Generics.:*: g)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseEncode (f GHC.Generics.:*: g)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseProd f, Codec.Serialise.Class.GSerialiseProd g) => Codec.Serialise.Class.GSerialiseProd (f GHC.Generics.:*: g)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseDecode (f GHC.Generics.:+: g)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseEncode (f GHC.Generics.:+: g)
+ Codec.Serialise.Class: instance (Codec.Serialise.Class.GSerialiseSum f, Codec.Serialise.Class.GSerialiseSum g) => Codec.Serialise.Class.GSerialiseSum (f GHC.Generics.:+: g)
+ Codec.Serialise.Class: instance (GHC.Classes.Ord a, Codec.Serialise.Class.Serialise a) => Codec.Serialise.Class.Serialise (Data.Set.Base.Set a)
+ Codec.Serialise.Class: instance (GHC.Classes.Ord k, Codec.Serialise.Class.Serialise k, Codec.Serialise.Class.Serialise v) => Codec.Serialise.Class.Serialise (Data.Map.Base.Map k v)
+ Codec.Serialise.Class: instance (i ~ GHC.Generics.C, Codec.Serialise.Class.GSerialiseProd f) => Codec.Serialise.Class.GSerialiseSum (GHC.Generics.M1 i c f)
+ Codec.Serialise.Class: instance (i ~ GHC.Generics.S, Codec.Serialise.Class.GSerialiseProd f) => Codec.Serialise.Class.GSerialiseProd (GHC.Generics.M1 i c f)
+ Codec.Serialise.Class: instance Codec.Serialise.Class.GSerialiseDecode a => Codec.Serialise.Class.GSerialiseDecode (GHC.Generics.M1 i c a)
+ Codec.Serialise.Class: instance Codec.Serialise.Class.GSerialiseEncode a => Codec.Serialise.Class.GSerialiseEncode (GHC.Generics.M1 i c a)
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.ByteString.Short.Internal.ShortByteString
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.IntSet.Base.IntSet
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.Time.Clock.UTC.UTCTime
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise Data.Typeable.Internal.TypeRep
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise a => Codec.Serialise.Class.Serialise (Data.IntMap.Base.IntMap a)
+ Codec.Serialise.Class: instance Codec.Serialise.Class.Serialise a => Codec.Serialise.Class.Serialise (Data.Sequence.Seq a)
+ Codec.Serialise.Class: nConstructors :: GSerialiseSum f => Proxy f -> Word
+ Codec.Serialise.Class: nFields :: GSerialiseProd f => Proxy f -> Word
+ Codec.Serialise.Class: numOfFields :: GSerialiseSum f => f a -> Word
+ Codec.Serialise.Decoding: ConsumeByteArray :: (ByteArray -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeDoubleCanonical :: (Double# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeFloat16Canonical :: (Float# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeFloatCanonical :: (Float# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt16Canonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt32Canonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt8Canonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeIntCanonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeIntegerCanonical :: (Integer -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeListLenCanonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeMapLenCanonical :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeNegWordCanonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeSimpleCanonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeTagCanonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeUtf8ByteArray :: (ByteArray -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord16Canonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord32Canonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord8Canonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWordCanonical :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
+ Codec.Serialise.Decoding: decodeByteArray :: Decoder s ByteArray
+ Codec.Serialise.Decoding: decodeUtf8ByteArray :: Decoder s ByteArray
+ Codec.Serialise.Encoding: TkByteArray :: {-# UNPACK #-} ~SlicedByteArray -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkUtf8ByteArray :: {-# UNPACK #-} ~SlicedByteArray -> Tokens -> Tokens
+ Codec.Serialise.Encoding: encodeByteArray :: SlicedByteArray -> Encoding
+ Codec.Serialise.Encoding: encodeUtf8ByteArray :: SlicedByteArray -> Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: ConformantUTF8 :: UTF8Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: GeneralisedUTF8 :: UTF8Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: data UTF8Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: decodeGenUTF8 :: ByteArray -> String
+ Codec.Serialise.Internal.GeneralisedUTF8: encodeGenUTF8 :: String -> (SlicedByteArray, UTF8Encoding)
+ Codec.Serialise.Internal.GeneralisedUTF8: instance GHC.Classes.Eq Codec.Serialise.Internal.GeneralisedUTF8.UTF8Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: instance GHC.Show.Show Codec.Serialise.Internal.GeneralisedUTF8.UTF8Encoding
+ Codec.Serialise.Internal.GeneralisedUTF8: isSurrogate :: Char -> Bool
+ Codec.Serialise.Internal.GeneralisedUTF8: isValid :: UTF8Encoding -> [Word8] -> Bool
- Codec.Serialise: Done :: !ByteString -> {-# UNPACK #-} !ByteOffset -> a -> IDecode s a
+ Codec.Serialise: Done :: ~ByteString -> {-# UNPACK #-} ~ByteOffset -> a -> IDecode s a
- Codec.Serialise: Fail :: !ByteString -> {-# UNPACK #-} !ByteOffset -> DeserialiseFailure -> IDecode s a
+ Codec.Serialise: Fail :: ~ByteString -> {-# UNPACK #-} ~ByteOffset -> DeserialiseFailure -> IDecode s a
- Codec.Serialise: Partial :: (Maybe ByteString -> ST s IDecode s a) -> IDecode s a
+ Codec.Serialise: Partial :: (Maybe ByteString -> ST s (IDecode s a)) -> IDecode s a
- Codec.Serialise: class Serialise a
+ Codec.Serialise: class Serialise a where encode = gencode . from decode = to <$> gdecode encodeList = defaultEncodeList decodeList = defaultDecodeList
- Codec.Serialise.Class: class Serialise a
+ Codec.Serialise.Class: class Serialise a where encode = gencode . from decode = to <$> gdecode encodeList = defaultEncodeList decodeList = defaultDecodeList
- Codec.Serialise.Decoding: ConsumeBool :: (Bool -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeBool :: (Bool -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeBreakOr :: (Bool -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeBreakOr :: (Bool -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeBytes :: (ByteString -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeBytes :: (ByteString -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeBytesIndef :: ST s DecodeAction s a -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeBytesIndef :: ST s (DecodeAction s a) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeDouble :: (Double# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeDouble :: (Double# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeFloat :: (Float# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeFloat :: (Float# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeInt :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeInt16 :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt16 :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeInt32 :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt32 :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeInt8 :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInt8 :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeInteger :: (Integer -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeInteger :: (Integer -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeListLen :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeListLen :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeListLenIndef :: ST s DecodeAction s a -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeListLenIndef :: ST s (DecodeAction s a) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeListLenOrIndef :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeListLenOrIndef :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeMapLen :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeMapLen :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeMapLenIndef :: ST s DecodeAction s a -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeMapLenIndef :: ST s (DecodeAction s a) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeMapLenOrIndef :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeMapLenOrIndef :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeNegWord :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeNegWord :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeNull :: ST s DecodeAction s a -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeNull :: ST s (DecodeAction s a) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeSimple :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeSimple :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeString :: (Text -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeString :: (Text -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeStringIndef :: ST s DecodeAction s a -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeStringIndef :: ST s (DecodeAction s a) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeTag :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeTag :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeWord :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeWord16 :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord16 :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeWord32 :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord32 :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: ConsumeWord8 :: (Word# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: ConsumeWord8 :: (Word# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: PeekAvailable :: (Int# -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: PeekAvailable :: (Int# -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: PeekTokenType :: (TokenType -> ST s DecodeAction s a) -> DecodeAction s a
+ Codec.Serialise.Decoding: PeekTokenType :: (TokenType -> ST s (DecodeAction s a)) -> DecodeAction s a
- Codec.Serialise.Decoding: decodeBool :: () => Decoder s Bool
+ Codec.Serialise.Decoding: decodeBool :: Decoder s Bool
- Codec.Serialise.Decoding: decodeBreakOr :: () => Decoder s Bool
+ Codec.Serialise.Decoding: decodeBreakOr :: Decoder s Bool
- Codec.Serialise.Decoding: decodeBytes :: () => Decoder s ByteString
+ Codec.Serialise.Decoding: decodeBytes :: Decoder s ByteString
- Codec.Serialise.Decoding: decodeBytesIndef :: () => Decoder s ()
+ Codec.Serialise.Decoding: decodeBytesIndef :: Decoder s ()
- Codec.Serialise.Decoding: decodeDouble :: () => Decoder s Double
+ Codec.Serialise.Decoding: decodeDouble :: Decoder s Double
- Codec.Serialise.Decoding: decodeFloat :: () => Decoder s Float
+ Codec.Serialise.Decoding: decodeFloat :: Decoder s Float
- Codec.Serialise.Decoding: decodeInt :: () => Decoder s Int
+ Codec.Serialise.Decoding: decodeInt :: Decoder s Int
- Codec.Serialise.Decoding: decodeInt16 :: () => Decoder s Int16
+ Codec.Serialise.Decoding: decodeInt16 :: Decoder s Int16
- Codec.Serialise.Decoding: decodeInt32 :: () => Decoder s Int32
+ Codec.Serialise.Decoding: decodeInt32 :: Decoder s Int32
- Codec.Serialise.Decoding: decodeInt64 :: () => Decoder s Int64
+ Codec.Serialise.Decoding: decodeInt64 :: Decoder s Int64
- Codec.Serialise.Decoding: decodeInt8 :: () => Decoder s Int8
+ Codec.Serialise.Decoding: decodeInt8 :: Decoder s Int8
- Codec.Serialise.Decoding: decodeInteger :: () => Decoder s Integer
+ Codec.Serialise.Decoding: decodeInteger :: Decoder s Integer
- Codec.Serialise.Decoding: decodeListLen :: () => Decoder s Int
+ Codec.Serialise.Decoding: decodeListLen :: Decoder s Int
- Codec.Serialise.Decoding: decodeListLenIndef :: () => Decoder s ()
+ Codec.Serialise.Decoding: decodeListLenIndef :: Decoder s ()
- Codec.Serialise.Decoding: decodeListLenOf :: () => Int -> Decoder s ()
+ Codec.Serialise.Decoding: decodeListLenOf :: Int -> Decoder s ()
- Codec.Serialise.Decoding: decodeListLenOrIndef :: () => Decoder s Maybe Int
+ Codec.Serialise.Decoding: decodeListLenOrIndef :: Decoder s (Maybe Int)
- Codec.Serialise.Decoding: decodeMapLen :: () => Decoder s Int
+ Codec.Serialise.Decoding: decodeMapLen :: Decoder s Int
- Codec.Serialise.Decoding: decodeMapLenIndef :: () => Decoder s ()
+ Codec.Serialise.Decoding: decodeMapLenIndef :: Decoder s ()
- Codec.Serialise.Decoding: decodeMapLenOrIndef :: () => Decoder s Maybe Int
+ Codec.Serialise.Decoding: decodeMapLenOrIndef :: Decoder s (Maybe Int)
- Codec.Serialise.Decoding: decodeNegWord :: () => Decoder s Word
+ Codec.Serialise.Decoding: decodeNegWord :: Decoder s Word
- Codec.Serialise.Decoding: decodeNegWord64 :: () => Decoder s Word64
+ Codec.Serialise.Decoding: decodeNegWord64 :: Decoder s Word64
- Codec.Serialise.Decoding: decodeNull :: () => Decoder s ()
+ Codec.Serialise.Decoding: decodeNull :: Decoder s ()
- Codec.Serialise.Decoding: decodeSequenceLenIndef :: () => (r -> a -> r) -> r -> (r -> r') -> Decoder s a -> Decoder s r'
+ Codec.Serialise.Decoding: decodeSequenceLenIndef :: (r -> a -> r) -> r -> (r -> r') -> Decoder s a -> Decoder s r'
- Codec.Serialise.Decoding: decodeSequenceLenN :: () => (r -> a -> r) -> r -> (r -> r') -> Int -> Decoder s a -> Decoder s r'
+ Codec.Serialise.Decoding: decodeSequenceLenN :: (r -> a -> r) -> r -> (r -> r') -> Int -> Decoder s a -> Decoder s r'
- Codec.Serialise.Decoding: decodeSimple :: () => Decoder s Word8
+ Codec.Serialise.Decoding: decodeSimple :: Decoder s Word8
- Codec.Serialise.Decoding: decodeString :: () => Decoder s Text
+ Codec.Serialise.Decoding: decodeString :: Decoder s Text
- Codec.Serialise.Decoding: decodeStringIndef :: () => Decoder s ()
+ Codec.Serialise.Decoding: decodeStringIndef :: Decoder s ()
- Codec.Serialise.Decoding: decodeTag :: () => Decoder s Word
+ Codec.Serialise.Decoding: decodeTag :: Decoder s Word
- Codec.Serialise.Decoding: decodeTag64 :: () => Decoder s Word64
+ Codec.Serialise.Decoding: decodeTag64 :: Decoder s Word64
- Codec.Serialise.Decoding: decodeWord :: () => Decoder s Word
+ Codec.Serialise.Decoding: decodeWord :: Decoder s Word
- Codec.Serialise.Decoding: decodeWord16 :: () => Decoder s Word16
+ Codec.Serialise.Decoding: decodeWord16 :: Decoder s Word16
- Codec.Serialise.Decoding: decodeWord32 :: () => Decoder s Word32
+ Codec.Serialise.Decoding: decodeWord32 :: Decoder s Word32
- Codec.Serialise.Decoding: decodeWord64 :: () => Decoder s Word64
+ Codec.Serialise.Decoding: decodeWord64 :: Decoder s Word64
- Codec.Serialise.Decoding: decodeWord8 :: () => Decoder s Word8
+ Codec.Serialise.Decoding: decodeWord8 :: Decoder s Word8
- Codec.Serialise.Decoding: decodeWordOf :: () => Word -> Decoder s ()
+ Codec.Serialise.Decoding: decodeWordOf :: Word -> Decoder s ()
- Codec.Serialise.Decoding: getDecodeAction :: () => Decoder s a -> ST s DecodeAction s a
+ Codec.Serialise.Decoding: getDecodeAction :: Decoder s a -> ST s (DecodeAction s a)
- Codec.Serialise.Decoding: peekAvailable :: () => Decoder s Int
+ Codec.Serialise.Decoding: peekAvailable :: Decoder s Int
- Codec.Serialise.Decoding: peekTokenType :: () => Decoder s TokenType
+ Codec.Serialise.Decoding: peekTokenType :: Decoder s TokenType
- Codec.Serialise.Encoding: TkBool :: !Bool -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkBool :: ~Bool -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkBytes :: {-# UNPACK #-} !ByteString -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkBytes :: {-# UNPACK #-} ~ByteString -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkFloat16 :: {-# UNPACK #-} !Float -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkFloat16 :: {-# UNPACK #-} ~Float -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkFloat32 :: {-# UNPACK #-} !Float -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkFloat32 :: {-# UNPACK #-} ~Float -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkFloat64 :: {-# UNPACK #-} !Double -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkFloat64 :: {-# UNPACK #-} ~Double -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkInt :: {-# UNPACK #-} !Int -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkInt :: {-# UNPACK #-} ~Int -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkInt64 :: {-# UNPACK #-} !Int64 -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkInt64 :: {-# UNPACK #-} ~Int64 -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkInteger :: !Integer -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkInteger :: ~Integer -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkListLen :: {-# UNPACK #-} !Word -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkListLen :: {-# UNPACK #-} ~Word -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkMapLen :: {-# UNPACK #-} !Word -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkMapLen :: {-# UNPACK #-} ~Word -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkSimple :: {-# UNPACK #-} !Word8 -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkSimple :: {-# UNPACK #-} ~Word8 -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkString :: {-# UNPACK #-} !Text -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkString :: {-# UNPACK #-} ~Text -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkTag :: {-# UNPACK #-} !Word -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkTag :: {-# UNPACK #-} ~Word -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkTag64 :: {-# UNPACK #-} !Word64 -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkTag64 :: {-# UNPACK #-} ~Word64 -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkWord :: {-# UNPACK #-} !Word -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkWord :: {-# UNPACK #-} ~Word -> Tokens -> Tokens
- Codec.Serialise.Encoding: TkWord64 :: {-# UNPACK #-} !Word64 -> Tokens -> Tokens
+ Codec.Serialise.Encoding: TkWord64 :: {-# UNPACK #-} ~Word64 -> Tokens -> Tokens

Files

serialise.cabal view
@@ -1,5 +1,5 @@ name:                serialise-version:             0.1.0.0+version:             0.2.0.0 synopsis:            A binary serialisation library for Haskell values. description:   This package (formerly @binary-serialise-cbor@) provides pure, efficient@@ -12,6 +12,11 @@   serialised Haskell values have implicit structure outside of the   Haskell program itself, meaning they can be inspected or analyzed   with custom tools.+  .+  An implementation of the standard bijection between CBOR and JSON is provided+  by the [cborg-json](/package/cborg-json) package. Also see+  [cbor-tool](/package/cbor-tool) for a convenient command-line utility for+  working with CBOR data. homepage:            https://github.com/well-typed/cborg license:             BSD3 license-file:        LICENSE.txt@@ -38,7 +43,7 @@ -- Flags  flag newtime15-  default: False+  default: True   manual: False   description: Use the new time 1.5 library @@ -55,12 +60,13 @@     Codec.Serialise.IO     Codec.Serialise.Properties     Codec.Serialise.Tutorial+    Codec.Serialise.Internal.GeneralisedUTF8    build-depends:     array                   >= 0.4     && < 0.6,     base                    >= 4.6     && < 5.0,     bytestring              >= 0.10.4  && < 0.11,-    cborg                   == 0.1.*,+    cborg                   == 0.2.*,     containers              >= 0.5     && < 0.6,     ghc-prim                >= 0.3     && < 0.6,     half                    >= 0.2.2.3 && < 0.3,@@ -99,20 +105,23 @@     Tests.Negative     Tests.Orphanage     Tests.Serialise+    Tests.Serialise.Canonical     Tests.Regress     Tests.Regress.Issue13     Tests.Regress.Issue67     Tests.Regress.Issue80     Tests.Regress.Issue106+    Tests.Regress.Issue135     Tests.Regress.FlatTerm     Tests.Reference     Tests.Reference.Implementation     Tests.Deriving+    Tests.GeneralisedUTF8    build-depends:     array                   >= 0.4     && < 0.6,     base                    >= 4.6     && < 5.0,-    binary                  >= 0.7     && < 0.9,+    binary                  >= 0.7     && < 0.10,     bytestring              >= 0.10.4  && < 0.11,     directory               >= 1.0     && < 1.4,     filepath                >= 1.0     && < 1.5,@@ -122,19 +131,20 @@     containers              >= 0.5     && < 0.6,     unordered-containers    >= 0.2     && < 0.3,     hashable                >= 1.2     && < 2.0,+    primitive               >= 0.5     && < 0.7,     cborg,     serialise, -    aeson                   >= 0.7     && < 1.2,+    aeson                   >= 0.7     && < 1.3,     base64-bytestring       >= 1.0     && < 1.1,     base16-bytestring       >= 0.1     && < 0.2,     deepseq                 >= 1.0     && < 1.5,     half                    >= 0.2.2.3 && < 0.3,-    QuickCheck              >= 2.9     && < 2.10,+    QuickCheck              >= 2.9     && < 2.11,     scientific              >= 0.3     && < 0.4,-    tasty                   >= 0.11    && < 0.12,+    tasty                   >= 0.11    && < 0.13,     tasty-hunit             >= 0.9     && < 0.10,-    tasty-quickcheck        >= 0.8     && < 0.9,+    tasty-quickcheck        >= 0.8     && < 0.10,     quickcheck-instances    >= 0.3.12  && < 0.4,     vector                  >= 0.10    && < 0.13 @@ -157,14 +167,14 @@    build-depends:     base                    >= 4.6     && < 5.0,-    binary                  >= 0.7     && < 0.9,+    binary                  >= 0.7     && < 0.10,     bytestring              >= 0.10.4  && < 0.11,     vector                  >= 0.10    && < 0.13,     cborg,     serialise,      deepseq                 >= 1.0     && < 1.5,-    criterion               >= 1.0     && < 1.2+    criterion               >= 1.0     && < 1.3    if flag(newtime15)     build-depends:@@ -201,16 +211,16 @@    build-depends:     base                    >= 4.6     && < 5.0,-    binary                  >= 0.7     && < 0.9,+    binary                  >= 0.7     && < 0.10,     bytestring              >= 0.10.4  && < 0.11,     ghc-prim                >= 0.3     && < 0.6,     vector                  >= 0.10    && < 0.13,     cborg,     serialise, -    aeson                   >= 0.7     && < 1.2,+    aeson                   >= 0.7     && < 1.3,     deepseq                 >= 1.0     && < 1.5,-    criterion               >= 1.0     && < 1.2,+    criterion               >= 1.0     && < 1.3,     cereal                  >= 0.5.2.0 && < 0.6,     cereal-vector           >= 0.2     && < 0.3,     store                   >= 0.4     && < 0.5@@ -247,7 +257,7 @@   build-depends:     array                   >= 0.4     && < 0.6,     base                    >= 4.6     && < 5.0,-    binary                  >= 0.7     && < 0.9,+    binary                  >= 0.7     && < 0.10,     bytestring              >= 0.10.4  && < 0.11,     directory               >= 1.0     && < 1.4,     ghc-prim                >= 0.3     && < 0.6,@@ -259,13 +269,13 @@     filepath                >= 1.0     && < 1.5,     containers              >= 0.5     && < 0.6,     deepseq                 >= 1.0     && < 1.5,-    aeson                   >= 0.7     && < 1.2,+    aeson                   >= 0.7     && < 1.3,     cereal                  >= 0.5.2.0 && < 0.6,     half                    >= 0.2.2.3 && < 0.3,     tar                     >= 0.4     && < 0.6,     zlib                    >= 0.5     && < 0.7,     pretty                  >= 1.0     && < 1.2,-    criterion               >= 1.0     && < 1.2,+    criterion               >= 1.0     && < 1.3,     store                   >= 0.4     && < 0.5    if flag(newtime15)
src/Codec/Serialise.hs view
@@ -16,7 +16,7 @@ -- and utilities to help you make your types serialisable. -- -- For a full tutorial on using this module, see--- "Codec.CBOR.Tutorial".+-- "Codec.Serialise.Tutorial". -- module Codec.Serialise   ( -- * High level, one-shot API
src/Codec/Serialise/Class.hs view
@@ -24,6 +24,8 @@    Serialise(..)  , GSerialiseEncode(..)  , GSerialiseDecode(..)+ , GSerialiseProd(..)+ , GSerialiseSum(..)  , encodeVector  , decodeVector  ) where@@ -31,6 +33,7 @@ import           Control.Applicative  import           Control.Monad+import           Data.Char import           Data.Hashable import           Data.Int import           Data.Monoid@@ -54,6 +57,7 @@  import qualified Data.Foldable                       as Foldable import qualified Data.ByteString                     as BS+import qualified Data.ByteString.Short.Internal      as BSS import qualified Data.Text                           as Text  -- TODO FIXME: more instances@@ -68,6 +72,7 @@ import qualified Data.HashSet                        as HashSet import qualified Data.HashMap.Strict                 as HashMap import qualified Data.Tree                           as Tree+import qualified Data.Primitive.ByteArray            as Prim import qualified Data.Vector                         as Vector import qualified Data.Vector.Unboxed                 as Vector.Unboxed import qualified Data.Vector.Storable                as Vector.Storable@@ -105,6 +110,9 @@ import           Codec.CBOR.Decoding import           Codec.CBOR.Encoding import           Codec.CBOR.Term+import           Codec.Serialise.Internal.GeneralisedUTF8+import qualified Codec.CBOR.ByteArray                as BA+import qualified Codec.CBOR.ByteArray.Sliced         as BAS   --------------------------------------------------------------------------------@@ -304,16 +312,37 @@  -- | @since 0.2.0.0 instance Serialise Char where-    encode c = encodeString (Text.singleton c)-    decode = do t <- decodeString-                if Text.length t == 1-                  then return $! Text.head t-                  else fail "expected a single char, found a string"+    -- Here we've taken great pains to ensure that surrogate characters, which+    -- are not representable in UTF-8 yet still admitted by Char,+    -- round-trip properly. We scan the encoded characters during encoding+    -- looking for surrogates; if we find any we encode the string as a+    -- a list of code-points encoded as words. This is slow, but should be rare.+    encode c+      | isSurrogate c = encodeWord (fromIntegral $ ord c)+      | otherwise     = encodeString (Text.singleton c)+    decode = do ty <- peekTokenType+                case ty of+                  TypeUInt -> chr . fromIntegral <$> decodeWord+                  TypeString -> do+                    t <- decodeString+                    if Text.length t == 1+                      then return $! Text.head t+                      else fail "expected a single char, found a string"+                  _ -> fail "expected a word or string"      -- For [Char]/String we have a special encoding-    encodeList cs = encodeString (Text.pack cs)-    decodeList    = do txt <- decodeString-                       return (Text.unpack txt) -- unpack lazily+    encodeList cs =+        case encodeGenUTF8 cs of+          (ba, ConformantUTF8)  -> encodeUtf8ByteArray ba+          (ba, GeneralisedUTF8) -> encodeByteArray ba+    decodeList    = do+        ty <- peekTokenType+        case ty of+          TypeBytes  -> decodeGenUTF8 . BA.unBA <$> decodeByteArray+          TypeString -> do+              txt <- decodeString+              return (Text.unpack txt) -- unpack lazily+          _          -> fail "expected a list or string"  -- | @since 0.2.0.0 instance Serialise Text.Text where@@ -325,6 +354,14 @@     encode = encodeBytes     decode = decodeBytes +-- | @since 0.2.0.0+instance Serialise BSS.ShortByteString where+    encode sbs@(BSS.SBS ba) =+        encodeByteArray $ BAS.SBA (Prim.ByteArray ba) 0 (BSS.length sbs)+    decode = do+        BA.BA (Prim.ByteArray ba) <- decodeByteArray+        return $ BSS.SBS ba+ encodeChunked :: Serialise c               => Encoding               -> ((c -> Encoding -> Encoding) -> Encoding -> a -> Encoding)@@ -1242,7 +1279,7 @@         Just HRefl -> pure rep         Nothing    -> fail $ unlines                       [ "Codec.CBOR.Class.decode(TypeRep): Type mismatch"-                      , "    Deserialized type: " ++ show rep+                      , "    Deserialised type: " ++ show rep                       , "    Expected type:     " ++ show expected                       ]     where expected = typeRep :: TypeRep a
src/Codec/Serialise/Decoding.hs view
@@ -35,8 +35,10 @@   , decodeDouble        -- :: Decoder s Double   , decodeBytes         -- :: Decoder s ByteString   , decodeBytesIndef    -- :: Decoder s ()+  , decodeByteArray     -- :: Decoder s ByteArray   , decodeString        -- :: Decoder s Text   , decodeStringIndef   -- :: Decoder s ()+  , decodeUtf8ByteArray -- :: Decoder s ByteArray   , decodeListLen       -- :: Decoder s Int   , decodeListLenIndef  -- :: Decoder s ()   , decodeMapLen        -- :: Decoder s Int
src/Codec/Serialise/Encoding.hs view
@@ -29,8 +29,10 @@   , encodeInteger            -- :: Integer -> Encoding   , encodeBytes              -- :: B.ByteString -> Encoding   , encodeBytesIndef         -- :: Encoding+  , encodeByteArray          -- :: ByteArray -> Encoding   , encodeString             -- :: T.Text -> Encoding   , encodeStringIndef        -- :: Encoding+  , encodeUtf8ByteArray      -- :: ByteArray -> Encoding   , encodeListLen            -- :: Word -> Encoding   , encodeListLenIndef       -- :: Encoding   , encodeMapLen             -- :: Word -> Encoding
+ src/Codec/Serialise/Internal/GeneralisedUTF8.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE BangPatterns #-}++module Codec.Serialise.Internal.GeneralisedUTF8+    ( encodeGenUTF8+    , UTF8Encoding(..)+    , decodeGenUTF8+      -- * Utilities+    , isSurrogate+    , isValid+    ) where++import Control.Monad.ST+import Data.Bits+import Data.Char+import Data.Word+import qualified Codec.CBOR.ByteArray.Sliced as BAS+import Data.Primitive.ByteArray++data UTF8Encoding = ConformantUTF8 | GeneralisedUTF8+                  deriving (Show, Eq)++-- | Is a 'Char' a UTF-16 surrogate?+isSurrogate :: Char -> Bool+isSurrogate c = c >= '\xd800' && c <= '\xdfff'++-- | Encode a string as (generalized) UTF-8. In addition to the encoding, we+-- return a flag indicating whether the encoded string contained any surrogate+-- characters, in which case the output is generalized UTF-8.+encodeGenUTF8 :: String -> (BAS.SlicedByteArray, UTF8Encoding)+encodeGenUTF8 st = runST $ do+    -- We slightly over-allocate such that we won't need to copy in the+    -- ASCII-only case.+    ba <- newByteArray (length st + 4)+    go ba ConformantUTF8 0 st+  where+    go :: MutableByteArray s -> UTF8Encoding+       -> Int -> [Char]+       -> ST s (BAS.SlicedByteArray, UTF8Encoding)+    go ba !enc !off  [] = do+        ba' <- unsafeFreezeByteArray ba+        return (BAS.SBA ba' 0 off, enc)+    go ba enc off  (c:cs)+      | off + 4 >= cap = do+        -- We ran out of room; reallocate and copy+        ba' <- newByteArray (cap + cap `div` 2 + 1)+        copyMutableByteArray ba' 0 ba 0 off+        go ba' enc off (c:cs)++      | c >= '\x10000' = do+        writeByteArray ba (off+0) (0xf0 .|. (0x07 .&. shiftedByte 18))+        writeByteArray ba (off+1) (0x80 .|. (0x3f .&. shiftedByte 12))+        writeByteArray ba (off+2) (0x80 .|. (0x3f .&. shiftedByte  6))+        writeByteArray ba (off+3) (0x80 .|. (0x3f .&. shiftedByte  0))+        go ba enc (off+4) cs++      | c >= '\x0800'  = do+        writeByteArray ba (off+0) (0xe0 .|. (0x0f .&. shiftedByte 12))+        writeByteArray ba (off+1) (0x80 .|. (0x3f .&. shiftedByte  6))+        writeByteArray ba (off+2) (0x80 .|. (0x3f .&. shiftedByte  0))++        -- Is this a surrogate character?+        let enc'+              | isSurrogate c = GeneralisedUTF8+              | otherwise     = enc+        go ba enc' (off+3) cs++      | c >= '\x0080'  = do+        writeByteArray ba (off+0) (0xc0 .|. (0x1f .&. shiftedByte  6))+        writeByteArray ba (off+1) (0x80 .|. (0x3f .&. shiftedByte  0))+        go ba enc (off+2) cs++      | c <= '\x007f'  = do+        writeByteArray ba off (fromIntegral n :: Word8)+        go ba enc (off+1) cs++      | otherwise      = error "encodeGenUTF8: Impossible"+      where+        cap = sizeofMutableByteArray ba+        n = ord c+        shiftedByte :: Int -> Word8+        shiftedByte shft = fromIntegral $ n `shiftR` shft++decodeGenUTF8 :: ByteArray -> String+decodeGenUTF8 ba = go 0+  where+    !len = sizeofByteArray ba++    index :: Int -> Int+    index i = fromIntegral (ba `indexByteArray` i :: Word8)++    go !off+      | off == len = []++      | n0 .&. 0xf8 == 0xf0 =+        let n1 = index (off + 1)+            n2 = index (off + 2)+            n3 = index (off + 3)+            c  = chr $  (n0 .&. 0x07) `shiftL` 18+                    .|. (n1 .&. 0x3f) `shiftL` 12+                    .|. (n2 .&. 0x3f) `shiftL`  6+                    .|. (n3 .&. 0x3f)+        in c : go (off + 4)++      | n0 .&. 0xf0 == 0xe0 =+        let n1 = index (off + 1)+            n2 = index (off + 2)+            c  = chr $  (n0 .&. 0x0f) `shiftL` 12+                    .|. (n1 .&. 0x3f) `shiftL`  6+                    .|. (n2 .&. 0x3f)+        in c : go (off + 3)++      | n0 .&. 0xe0 == 0xc0 =+        let n1 = index (off + 1)+            c  = chr $  (n0 .&. 0x1f) `shiftL`  6+                    .|. (n1 .&. 0x3f)+        in c : go (off + 2)++      | otherwise =+        let c =  chr $  (n0 .&. 0x7f)+        in c : go (off + 1)+      where !n0 = index off++-- | Is the given byte sequence valid under the given encoding?+isValid :: UTF8Encoding -> [Word8] -> Bool+isValid encoding = go+  where+    go [] = True+    go (b0:bs)+      | inRange 0x00 0x7f b0 = go bs+    go (b0:b1:bs)+      | inRange 0xc2 0xdf b0+      , inRange 0x80 0xbf b1 = go bs+    go (0xe0:b1:b2:bs)+      | inRange 0xa0 0xbf b1+      , inRange 0x80 0xbf b2 = go bs+    go (0xed:b1:_)+      -- surrogate range+      | encoding == ConformantUTF8+      , inRange 0xa0 0xbf b1+      = False+    go (b0:b1:b2:bs)+      | inRange 0xe1 0xef b0+      , inRange 0x80 0xbf b1+      , inRange 0x80 0xbf b2 = go bs+    go (0xf0:b1:b2:b3:bs)+      | inRange 0x90 0xbf b1+      , inRange 0x80 0xbf b2+      , inRange 0x80 0xbf b3 = go bs+    go (b0:b1:b2:b3:bs)+      | inRange 0xf1 0xf3 b0+      , inRange 0x80 0xbf b1+      , inRange 0x80 0xbf b2+      , inRange 0x80 0xbf b3 = go bs+    go (0xf4:b1:b2:b3:bs)+      | inRange 0x80 0x8f b1+      , inRange 0x80 0xbf b2+      , inRange 0x80 0xbf b3 = go bs+    go _ = False++inRange :: Ord a => a -> a -> a -> Bool+inRange lower upper x = lower <= x && x <= upper
src/Codec/Serialise/Tutorial.hs view
@@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fno-warn-unused-imports #-}  -- |--- Module      : Codec.CBOR.Tutorial+-- Module      : Codec.Serialise.Tutorial -- Copyright   : (c) Duncan Coutts 2015-2017 -- License     : BSD3-style (see LICENSE.txt) --@@ -53,7 +53,7 @@ As in modern serialisation libraries, @cborg@ offers instance derivation via GHC's 'GHC.Generic' mechanism, -> import Serialise.Cborg+> import Codec.Serialise > import qualified Data.ByteString.Lazy as BSL > > data Animal = HoppingAnimal { animalName :: String, hoppingHeight :: Int }@@ -162,16 +162,16 @@ {- $encoding  For the purposes of encoding, abstract CBOR representations are embodied by the-'Serialise.Cborg.Encoding.Tokens' type. Such a representation can be efficiently-built using the 'Serialise.Cborg.Encoding.Encoding' 'Monoid'.+'Codec.CBOR.Encoding.Tokens' type. Such a representation can be efficiently+built using the 'Codec.CBOR.Encoding.Encoding' 'Monoid'.  For instance, to implement an encoder for the @Animal@ type above we might write,  > encodeAnimal :: Animal -> Encoding > encodeAnimal (HoppingAnimal name height) =->     encodeListLen 3 <> encodeTag 0 <> encode name <> encode height+>     encodeListLen 3 <> encodeWord 0 <> encode name <> encode height > encodeAnimal (WalkingAnimal name speed) =->     encodeListLen 3 <> encodeTag 1 <> encode name <> encode speed+>     encodeListLen 3 <> encodeWord 1 <> encode name <> encode speed  Here we see that each encoding begins with a /length/, describing how many values belonging to our @Animal@ will follow. We then encode a /tag/, which@@ -182,6 +182,9 @@ the length and tag, to ensure that you have the option to migrate your types later on. +Also note that the recommended encoding represents Haskell constructor indexes+as CBOR words, not CBOR tags.+ -}  {- $decoding@@ -193,7 +196,7 @@ > decodeAnimal :: Decoder s Animal > decodeAnimal = do >     len <- decodeListLen->     tag <- decodeTag+>     tag <- decodeWord >     case (len, tag) of >       (3, 0) -> HoppingAnimal <$> decode <*> decode >       (3, 1) -> WalkingAnimal <$> decode <*> decode@@ -232,17 +235,17 @@ > encodeAnimal :: Animal -> Encoding > -- HoppingAnimal, SwimmingAnimal cases are unchanged... > encodeAnimal (HoppingAnimal name height) =->     encodeListLen 3 <> encodeTag 0 <> encode name <> encode height+>     encodeListLen 3 <> encodeWord 0 <> encode name <> encode height > encodeAnimal (WalkingAnimal name speed) =->     encodeListLen 3 <> encodeTag 1 <> encode name <> encode speed+>     encodeListLen 3 <> encodeWord 1 <> encode name <> encode speed > -- Here is out new case... > encodeAnimal (SwimmingAnimal numberOfFins) =->     encodeListLen 2 <> encodeTag 2 <> encode numberOfFins+>     encodeListLen 2 <> encodeWord 2 <> encode numberOfFins > > decodeAnimal :: Decoder s Animal > decodeAnimal = do >     len <- decodeListLen->     tag <- decodeTag+>     tag <- decodeWord >     case (len, tag) of >       -- these cases are unchanged... >       (3, 0) -> HoppingAnimal <$> decode <*> decode@@ -266,17 +269,17 @@ > encodeAnimal :: Animal -> Encoding > -- HoppingAnimal, SwimmingAnimal cases are unchanged... > encodeAnimal (HoppingAnimal name height) =->     encodeListLen 3 <> encodeTag 0 <> encode name <> encode height+>     encodeListLen 3 <> encodeWord 0 <> encode name <> encode height > encodeAnimal (WalkingAnimal name speed) =->     encodeListLen 3 <> encodeTag 1 <> encode name <> encode speed+>     encodeListLen 3 <> encodeWord 1 <> encode name <> encode speed > -- This is new... > encodeAnimal (WalkingAnimal animalName walkingSpeed numberOfFeet) =->     encodeListLen 4 <> encodeTag 3 <> encode animalName <> encode walkingSpeed <> encode numberOfFins+>     encodeListLen 4 <> encodeWord 3 <> encode animalName <> encode walkingSpeed <> encode numberOfFins > > decodeAnimal :: Decoder s Animal > decodeAnimal = do >     len <- decodeListLen->     tag <- decodeTag+>     tag <- decodeWord >     case (len, tag) of >       -- this cases are unchanged... >       (3, 0) -> HoppingAnimal <$> decode <*> decode@@ -295,7 +298,7 @@  When working with foreign encodings, it can sometimes be useful to capture a serialised CBOR term verbatim (for instance, so you can later re-serialise it in-some later result). The 'Serialise.Cborg.Term.Term' type provides such a+some later result). The 'Codec.CBOR.Term.Term' type provides such a representation, losslessly capturing a CBOR AST. It can be serialised and deserialised with its 'Serialise' instance. @@ -305,9 +308,9 @@  We can also look In addition to serialisation and deserialisation, @cborg@ provides a variety of tools for representing arbitrary CBOR encodings in the-"Serialise.Cborg.FlatTerm" and "Serialise.Cborg.Pretty" modules.+"Codec.CBOR.FlatTerm" and "Codec.CBOR.Pretty" modules. -The 'Serialise.Cborg.FlatTerm.FlatTerm' type represents a single CBOR /term/, as+The 'Codec.CBOR.FlatTerm.FlatTerm' type represents a single CBOR /term/, as would be found in the ultimate CBOR representation. For instance, we can easily look at the structure of our @Animal@ encoding above, @@ -319,10 +322,10 @@ This can be useful both for understanding external CBOR formats, as well as understanding and testing your own hand-rolled encodings. -The package also includes a pretty-printer in "Serialise.Cborg.Pretty", for+The package also includes a pretty-printer in "Codec.CBOR.Pretty", for visualising the CBOR wire protocol alongside its semantic structure. For instance, ->>> putStrLn $ Serialise.Cborg.Pretty.prettyHexEnc $ encode $ HoppingAnimal "Fred" 42+>>> putStrLn $ Codec.CBOR.Pretty.prettyHexEnc $ encode $ HoppingAnimal "Fred" 42 83  # list(3)    00  # word(0)    64 46 72 65 64  # text("Fred")
tests/Main.hs view
@@ -10,6 +10,7 @@ import qualified Tests.Serialise as Serialise import qualified Tests.Negative  as Negative import qualified Tests.Deriving  as Deriving+import qualified Tests.GeneralisedUTF8  as GeneralisedUTF8  main :: IO () main = Reference.loadTestCases >>= \tcs -> defaultMain $@@ -22,4 +23,5 @@     , IO.testTree     , Regress.testTree     , Deriving.testTree+    , GeneralisedUTF8.testTree     ]
tests/Tests/CBOR.hs view
@@ -155,9 +155,15 @@ toRefTerm  TNull        = RefImpl.TNull toRefTerm (TSimple  23) = RefImpl.TUndef toRefTerm (TSimple   w) = RefImpl.TSimple (fromIntegral w)-toRefTerm (THalf     f) = RefImpl.TFloat16 (Half.toHalf f)-toRefTerm (TFloat    f) = RefImpl.TFloat32 f-toRefTerm (TDouble   f) = RefImpl.TFloat64 f+toRefTerm (THalf     f) = if isNaN f+                          then RefImpl.TFloat16 RefImpl.canonicalNaN+                          else RefImpl.TFloat16 (Half.toHalf f)+toRefTerm (TFloat    f) = if isNaN f+                          then RefImpl.TFloat16 RefImpl.canonicalNaN+                          else RefImpl.TFloat32 f+toRefTerm (TDouble   f) = if isNaN f+                          then RefImpl.TFloat16 RefImpl.canonicalNaN+                          else RefImpl.TFloat64 f   fromRefTerm :: RefImpl.Term -> Term@@ -191,8 +197,12 @@ fromRefTerm  RefImpl.TUndef      = TSimple 23 fromRefTerm (RefImpl.TSimple  w) = TSimple w fromRefTerm (RefImpl.TFloat16 f) = THalf (Half.fromHalf f)-fromRefTerm (RefImpl.TFloat32 f) = TFloat f-fromRefTerm (RefImpl.TFloat64 f) = TDouble f+fromRefTerm (RefImpl.TFloat32 f) = if isNaN f+                                   then THalf (Half.fromHalf RefImpl.canonicalNaN)+                                   else TFloat f+fromRefTerm (RefImpl.TFloat64 f) = if isNaN f+                                   then THalf (Half.fromHalf RefImpl.canonicalNaN)+                                   else TDouble f  -- NaNs are so annoying... eqTerm :: Term -> Term -> Bool
+ tests/Tests/GeneralisedUTF8.hs view
@@ -0,0 +1,37 @@+module Tests.GeneralisedUTF8 where++import GHC.Exts+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.ByteString as BS++import Test.Tasty+import Test.Tasty.QuickCheck++import qualified Codec.CBOR.ByteArray as BA+import Codec.Serialise.Internal.GeneralisedUTF8++testEncoder :: String -> Property+testEncoder s =+    case encodeGenUTF8 s of+      (ba, enc) ->+          toList ba === BS.unpack (T.encodeUtf8 $ T.pack s)+          .&&.+          enc === correctEnc+  where+    correctEnc+      | any isSurrogate s = GeneralisedUTF8+      | otherwise         = ConformantUTF8++testDecoder :: String -> Property+testDecoder s =+    decodeGenUTF8 ba === s+  where+    BA.BA ba = BA.fromByteString $ T.encodeUtf8 $ T.pack s++testTree :: TestTree+testTree =+    testGroup "Generalised UTF-8 codec"+        [ testProperty "encoder" testEncoder+        , testProperty "decoder" testDecoder+        ]
tests/Tests/Orphanage.hs view
@@ -4,26 +4,29 @@ {-# LANGUAGE DeriveDataTypeable #-} module Tests.Orphanage where -#if !MIN_VERSION_base(4,8,0)+#if !MIN_VERSION_base(4,8,0) && !MIN_VERSION_QuickCheck(2,10,0) import           Control.Applicative import           Data.Monoid as Monoid #endif -#if MIN_VERSION_base(4,9,0)+#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_QuickCheck(2,10,0) import qualified Data.Semigroup as Semigroup #endif -import           Data.Typeable-+import           GHC.Fingerprint.Type import           Data.Ord+#if !MIN_VERSION_QuickCheck(2,10,0)+import           Data.Typeable import           Foreign.C.Types import           System.Exit (ExitCode(..))-import           GHC.Fingerprint.Type  import           Test.QuickCheck.Gen+#endif+ import           Test.QuickCheck.Arbitrary  import qualified Data.Vector.Primitive      as Vector.Primitive+import qualified Data.ByteString.Short      as BSS  -------------------------------------------------------------------------------- -- QuickCheck Orphans@@ -35,6 +38,7 @@  -- Foreign C types +#if !MIN_VERSION_QuickCheck(2,10,0) instance Arbitrary CChar where   arbitrary = CChar <$> arbitrary   shrink (CChar x) = CChar <$> shrink x@@ -134,10 +138,11 @@ instance Arbitrary CDouble where   arbitrary = CDouble <$> arbitrary   shrink (CDouble x) = CDouble <$> shrink x+#endif  -- Miscellaneous types from base -#if MIN_VERSION_base(4,9,0)+#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_QuickCheck(2,10,0) instance Arbitrary a => Arbitrary (Semigroup.Min a) where   arbitrary = fmap Semigroup.Min arbitrary   shrink = map Semigroup.Min . shrink . Semigroup.getMin@@ -167,11 +172,13 @@   arbitrary = fmap Down arbitrary   shrink = map Down . shrink . (\(Down a) -> a) +#if !MIN_VERSION_QuickCheck(2,10,0) instance Arbitrary ExitCode where   arbitrary = frequency [(1, return ExitSuccess), (3, fmap ExitFailure arbitrary)]    shrink (ExitFailure x) = ExitSuccess : [ ExitFailure x' | x' <- shrink x ]   shrink _        = []+#endif  #if !MIN_VERSION_base(4,8,0) deriving instance Typeable Const@@ -188,11 +195,14 @@ deriving instance Eq a   => Eq   (Const a b) #endif +instance Arbitrary BSS.ShortByteString where+  arbitrary = BSS.pack <$> arbitrary+ instance (Vector.Primitive.Prim a, Arbitrary a          ) => Arbitrary (Vector.Primitive.Vector a) where     arbitrary = Vector.Primitive.fromList <$> arbitrary -#if MIN_VERSION_base(4,7,0)+#if MIN_VERSION_base(4,7,0) && !MIN_VERSION_QuickCheck(2,10,0) instance Arbitrary (Proxy a) where   arbitrary = return Proxy #endif
tests/Tests/Reference.hs view
@@ -185,10 +185,8 @@   , ("NaN",       [0xf9, 0x7e, 0x00])   , ("-Infinity", [0xf9, 0xfc, 0x00])   , ("Infinity",  [0xfa, 0x7f, 0x80, 0x00, 0x00])-  , ("NaN",       [0xfa, 0x7f, 0xc0, 0x00, 0x00])   , ("-Infinity", [0xfa, 0xff, 0x80, 0x00, 0x00])   , ("Infinity",  [0xfb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])-  , ("NaN",       [0xfb, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])   , ("-Infinity", [0xfb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])    , ("false",       [0xf4])
tests/Tests/Reference/Implementation.hs view
@@ -38,6 +38,8 @@     decodeTokens,     decodeToken, +    canonicalNaN,+     diagnosticNotation,      encodeTerm,@@ -64,7 +66,7 @@ import           Data.Bits import           Data.Word import           Data.Int-import           Numeric.Half (Half)+import           Numeric.Half (Half(..)) import qualified Numeric.Half as Half import           Data.List import           Numeric@@ -816,6 +818,12 @@                            = TNInt (toUInt (fromIntegral (-1 - n)))   | otherwise              = TBigInt n canonicaliseTerm (TFloat16 f)   = TFloat16 (canonicaliseHalf f)+canonicaliseTerm (TFloat32 f)   = if isNaN f+                                  then TFloat16 canonicalNaN+                                  else TFloat32 f+canonicaliseTerm (TFloat64 f)   = if isNaN f+                                  then TFloat16 canonicalNaN+                                  else TFloat64 f canonicaliseTerm (TBytess  wss) = TBytess  (filter (not . null) wss) canonicaliseTerm (TStrings css) = TStrings (filter (not . null) css) canonicaliseTerm (TArray  ts) = TArray  (map canonicaliseTerm ts)@@ -828,12 +836,16 @@ canonicaliseUInt :: UInt -> UInt canonicaliseUInt = toUInt . fromUInt --- some NaNs do not roundtrip https://github.com/ekmett/half/issues/3 canonicaliseHalf :: Half -> Half-canonicaliseHalf = Half.toHalf . Half.fromHalf+canonicaliseHalf f+  | isNaN f   = canonicalNaN+  | otherwise = f  canonicaliseTermPair :: (Term, Term) -> (Term, Term) canonicaliseTermPair (x,y) = (canonicaliseTerm x, canonicaliseTerm y)++canonicalNaN :: Half+canonicalNaN = Half 0x7e00  ------------------------------------------------------------------------------- 
tests/Tests/Regress.hs view
@@ -7,7 +7,8 @@ import qualified Tests.Regress.Issue13  as Issue13 import qualified Tests.Regress.Issue67  as Issue67 import qualified Tests.Regress.Issue80  as Issue80-import qualified Tests.Regress.Issue106  as Issue106+import qualified Tests.Regress.Issue106 as Issue106+import qualified Tests.Regress.Issue135 as Issue135 import qualified Tests.Regress.FlatTerm as FlatTerm  --------------------------------------------------------------------------------@@ -20,4 +21,5 @@   , Issue67.testTree   , Issue80.testTree   , Issue106.testTree+  , Issue135.testTree   ]
+ tests/Tests/Regress/Issue135.hs view
@@ -0,0 +1,34 @@+-- Issue #135: Ensure that surrogate characters round-trip+--+module Tests.Regress.Issue135+  ( testTree -- :: TestTree+  ) where++import           Codec.Serialise++import           Test.Tasty+import           Test.Tasty.QuickCheck+import           Test.Tasty.HUnit++newtype StringWithSurrogates = StringWithSurrogates String+                             deriving (Show)++instance Arbitrary StringWithSurrogates where+  arbitrary =+      fmap StringWithSurrogates $ listOf1+      $ oneof [choose ('\xd800', '\xdfff'), arbitrary]++prop_surrogateRoundtrip :: StringWithSurrogates -> Property+prop_surrogateRoundtrip (StringWithSurrogates s) =+    s === deserialise (serialise s)++roundTrips :: (Eq a, Serialise a) => a -> Bool+roundTrips x = x == deserialise (serialise x)++testTree :: TestTree+testTree =+  testGroup "Issue 135 - surrogate characters round-trip"+    [ testCase "simple reproduction case"   (True @=? all (\c -> c == deserialise (serialise c)) ['\xdc80'..'\xdcff'])+    , testCase "all Chars round-trip" ([] @=? filter (not . roundTrips) ['\x0000'..'\x10ffff'])+    , testProperty "surrogates round-trip" prop_surrogateRoundtrip+    ]
tests/Tests/Serialise.hs view
@@ -19,6 +19,7 @@ import qualified Data.Semigroup as Semigroup #endif +import           Data.Char (ord) import           Data.Complex import           Data.Int import           Data.Fixed@@ -27,6 +28,7 @@ import           Data.Ratio import           Data.Time import           Data.Word+import           GHC.Exts (IsList(..)) import           GHC.Float (float2Double) import           Data.Version @@ -40,17 +42,21 @@ import           Test.QuickCheck.Instances () import           Test.Tasty.HUnit import           GHC.Generics  (Generic)-import qualified Data.Text            as Text-import qualified Data.Text.Lazy       as Text.Lazy-import qualified Data.ByteString      as BS-import qualified Data.ByteString.Lazy as BS.Lazy+import qualified Data.Text                      as Text+import qualified Data.Text.Encoding             as Text+import qualified Data.Text.Lazy                 as Text.Lazy+import qualified Data.ByteString                as BS+import qualified Data.ByteString.Lazy           as BS.Lazy+import qualified Data.ByteString.Short          as BSS+import qualified Data.ByteString.Short.Internal as BSS import           System.Exit (ExitCode(..)) +import qualified Codec.CBOR.ByteArray           as CBOR.BA import           Codec.CBOR.FlatTerm (toFlatTerm, fromFlatTerm) import           Codec.Serialise import           Codec.Serialise.Encoding import           Codec.Serialise.Decoding-import qualified Codec.Serialise.Properties as Props+import qualified Codec.Serialise.Properties     as Props  import qualified Data.HashMap.Strict        as HashMap import qualified Data.HashSet               as HashSet@@ -65,8 +71,10 @@ import qualified Data.Vector.Storable       as Vector.Storable import qualified Data.Vector.Primitive      as Vector.Primitive import           GHC.Fingerprint.Type (Fingerprint(..))+import           Data.Primitive.ByteArray   as Prim  import           Tests.Orphanage()+import           Tests.Serialise.Canonical  -------------------------------------------------------------------------------- -- Tests and properties@@ -152,9 +160,22 @@       , mkTest (T :: T Word16)       , mkTest (T :: T Word32)       , mkTest (T :: T Word64)+      , mkTest (T :: T (Canonical Int))+      , mkTest (T :: T (Canonical Int8))+      , mkTest (T :: T (Canonical Int16))+      , mkTest (T :: T (Canonical Int32))+      , mkTest (T :: T (Canonical Int64))+      , mkTest (T :: T (Canonical Word))+      , mkTest (T :: T (Canonical Word8))+      , mkTest (T :: T (Canonical Word16))+      , mkTest (T :: T (Canonical Word32))+      , mkTest (T :: T (Canonical Word64))       , mkTest (T :: T Integer)       , mkTest (T :: T Float)       , mkTest (T :: T Double)+      , mkTest (T :: T (Canonical Integer))+      , mkTest (T :: T (Canonical Float))+      , mkTest (T :: T (Canonical Double))       , mkTest (T :: T [()]) #if MIN_VERSION_base(4,9,0)       , mkTest (T :: T (NonEmpty ()))@@ -214,6 +235,9 @@       , mkTest (T :: T Text.Lazy.Text)       , mkTest (T :: T BS.ByteString)       , mkTest (T :: T BS.Lazy.ByteString)+      , mkTest (T :: T BSS.ShortByteString)+      , mkTest (T :: T BytesByteArray)+      , mkTest (T :: T Utf8ByteArray)       , mkTest (T :: T [Int])       , mkTest (T :: T UTCTime)       , mkTest (T :: T Version)@@ -274,7 +298,7 @@       (TkListLen 3 $ TkWord 0 $ TkInt 12 $ TkFloat32 0.5 $ TkEnd)   , format       (P3 12 0.5 "asdf")-      (TkListLen 4 $ TkWord 0 $ TkInt 12 $ TkFloat32 0.5 $ TkString "asdf" $ TkEnd)+      (TkListLen 4 $ TkWord 0 $ TkInt 12 $ TkFloat32 0.5 $ tkStr "asdf" $ TkEnd)   , format       (C1 12)       (TkListLen 2 $ TkWord 0 $ TkInt 12 $ TkEnd)@@ -283,18 +307,20 @@       (TkListLen 3 $ TkWord 1 $ TkInt 12 $ TkFloat32 0.5 $ TkEnd)   , format       (C3 12 0.5 "asdf")-      (TkListLen 4 $ TkWord 2 $ TkInt 12 $ TkFloat32 0.5 $ TkString "asdf" $ TkEnd)+      (TkListLen 4 $ TkWord 2 $ TkInt 12 $ TkFloat32 0.5 $ tkStr "asdf" $ TkEnd)   , format        C4       (TkListLen 1 $ TkWord 3 $ TkEnd)   , format       (Cons "foo" (Cons "bar" Nil) :: List String)-      (TkListLen 3 $ TkWord 0 $ TkString "foo" $-       TkListLen 3 $ TkWord 0 $ TkString "bar" $+      (TkListLen 3 $ TkWord 0 $ tkStr "foo" $+       TkListLen 3 $ TkWord 0 $ tkStr "bar" $        TkListLen 1 $ TkWord 1 $        TkEnd)   ] +  where tkStr = TkUtf8ByteArray . fromList . map (fromIntegral . ord)+ -------------------------------------------------------------------------------- -- Extra machinery @@ -366,3 +392,25 @@       where         cnv :: [a] -> List a         cnv = foldr Cons Nil++newtype BytesByteArray = BytesBA CBOR.BA.ByteArray+                       deriving (Eq, Ord, Show)++instance Serialise BytesByteArray where+    encode (BytesBA ba) = encodeByteArray $ CBOR.BA.toSliced ba+    decode = BytesBA <$> decodeByteArray++instance Arbitrary BytesByteArray where+    arbitrary = BytesBA . fromList <$> arbitrary++newtype Utf8ByteArray = Utf8BA CBOR.BA.ByteArray+                      deriving (Eq, Ord, Show)++instance Serialise Utf8ByteArray where+    encode (Utf8BA ba) = encodeUtf8ByteArray $ CBOR.BA.toSliced ba+    decode = Utf8BA <$> decodeUtf8ByteArray++instance Arbitrary Utf8ByteArray where+    arbitrary = do+        BSS.SBS ba <- BSS.toShort . Text.encodeUtf8 <$> arbitrary+        return $ Utf8BA $ CBOR.BA.BA $ Prim.ByteArray ba
+ tests/Tests/Serialise/Canonical.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE StandaloneDeriving #-}+module Tests.Serialise.Canonical where++import Data.Bits+import Data.Int+import Data.Typeable+import Data.Word+import Test.QuickCheck++import Codec.CBOR.Decoding+import Codec.CBOR.Encoding as E+import Codec.Serialise.Class++newtype Canonical a = Canonical { fromCanonical :: a }+  deriving (Typeable, Eq, Show)++-- | Generate "proper" big integers (as standard Arbitrary Integer instance+-- doesn't really do that) to test canonicity.+instance Arbitrary (Canonical Integer) where+  arbitrary = do+    c <- choose (1, 5)+    neg <- arbitrary+    Canonical . (if neg then negate else id) . foldr combine 0+      <$> vectorOf c arbitrary+    where+      combine :: Word64 -> Integer -> Integer+      combine v acc = (acc `shiftL` finiteBitSize v) + toInteger v++deriving instance Arbitrary (Canonical Word)+deriving instance Arbitrary (Canonical Word8)+deriving instance Arbitrary (Canonical Word16)+deriving instance Arbitrary (Canonical Word32)+deriving instance Arbitrary (Canonical Word64)+deriving instance Arbitrary (Canonical Int)+deriving instance Arbitrary (Canonical Int8)+deriving instance Arbitrary (Canonical Int16)+deriving instance Arbitrary (Canonical Int32)+deriving instance Arbitrary (Canonical Int64)+deriving instance Arbitrary (Canonical Float)+deriving instance Arbitrary (Canonical Double)++----------------------------------------++instance Serialise (Canonical Word) where+  encode = encodeWord . fromCanonical+  decode = Canonical <$> decodeWordCanonical++instance Serialise (Canonical Word8) where+  encode = encodeWord8 . fromCanonical+  decode = Canonical <$> decodeWord8Canonical++instance Serialise (Canonical Word16) where+  encode = encodeWord16 . fromCanonical+  decode = Canonical <$> decodeWord16Canonical++instance Serialise (Canonical Word32) where+  encode = encodeWord32 . fromCanonical+  decode = Canonical <$> decodeWord32Canonical++instance Serialise (Canonical Word64) where+  encode = encodeWord64 . fromCanonical+  decode = Canonical <$> decodeWord64Canonical++instance Serialise (Canonical Int) where+  encode = encodeInt . fromCanonical+  decode = Canonical <$> decodeIntCanonical++instance Serialise (Canonical Int8) where+  encode = encodeInt8 . fromCanonical+  decode = Canonical <$> decodeInt8Canonical++instance Serialise (Canonical Int16) where+  encode = encodeInt16 . fromCanonical+  decode = Canonical <$> decodeInt16Canonical++instance Serialise (Canonical Int32) where+  encode = encodeInt32 . fromCanonical+  decode = Canonical <$> decodeInt32Canonical++instance Serialise (Canonical Int64) where+  encode = encodeInt64 . fromCanonical+  decode = Canonical <$> decodeInt64Canonical++instance Serialise (Canonical Integer) where+  encode = encodeInteger . fromCanonical+  decode = Canonical <$> decodeIntegerCanonical++instance Serialise (Canonical Float) where+    encode = E.encodeFloat . fromCanonical+    decode = Canonical <$> decodeFloatCanonical++instance Serialise (Canonical Double) where+    encode = encodeDouble . fromCanonical+    decode = Canonical <$> decodeDoubleCanonical
tests/test-vectors/appendix_a.json view
@@ -210,12 +210,6 @@     "diagnostic": "Infinity"   },   {-    "cbor": "+n/AAAA=",-    "hex": "fa7fc00000",-    "roundtrip": false,-    "diagnostic": "NaN"-  },-  {     "cbor": "+v+AAAA=",     "hex": "faff800000",     "roundtrip": false,@@ -226,12 +220,6 @@     "hex": "fb7ff0000000000000",     "roundtrip": false,     "diagnostic": "Infinity"-  },-  {-    "cbor": "+3/4AAAAAAAA",-    "hex": "fb7ff8000000000000",-    "roundtrip": false,-    "diagnostic": "NaN"   },   {     "cbor": "+//wAAAAAAAA",