module Foreign.Erlang
( OtpErlangTerm(..)
, Error(..)
, Result
, binaryToTerm
, termToBinary
) where
import Prelude hiding (length,tail,(<>))
import Data.Bits ((.&.))
import Control.Monad (replicateM)
import qualified Data.Monoid as Monoid
import qualified Data.Binary.Get as Get
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Char8 as Char8
import qualified Data.ByteString.Lazy as LazyByteString
import qualified Data.ByteString.Builder as Builder
import qualified Data.Int as DataInt
import qualified Data.List as List
import qualified Data.Map.Strict as Map
import qualified Data.Word as Word
import qualified Codec.Compression.Zlib as Zlib
import qualified Foreign.Erlang.Pid as E
import qualified Foreign.Erlang.Port as E
import qualified Foreign.Erlang.Reference as E
import qualified Foreign.Erlang.Function as E
type Get = Get.Get
type Builder = Builder.Builder
type ByteString = ByteString.ByteString
type LazyByteString = LazyByteString.ByteString
type Int32 = DataInt.Int32
type Map = Map.Map
type Word8 = Word.Word8
type Word16 = Word.Word16
type Word32 = Word.Word32
type Pid = E.Pid
type Port = E.Port
type Reference = E.Reference
type Function = E.Function
tagVersion :: Word8
tagVersion :: Word8
tagVersion = Word8
131
tagCompressedZlib :: Word8
tagCompressedZlib :: Word8
tagCompressedZlib = Word8
80
tagNewFloatExt :: Word8
tagNewFloatExt :: Word8
tagNewFloatExt = Word8
70
tagBitBinaryExt :: Word8
tagBitBinaryExt :: Word8
tagBitBinaryExt = Word8
77
tagAtomCacheRef :: Word8
tagAtomCacheRef :: Word8
tagAtomCacheRef = Word8
78
tagNewPidExt :: Word8
tagNewPidExt :: Word8
tagNewPidExt = Word8
88
tagNewPortExt :: Word8
tagNewPortExt :: Word8
tagNewPortExt = Word8
89
tagNewerReferenceExt :: Word8
tagNewerReferenceExt :: Word8
tagNewerReferenceExt = Word8
90
tagSmallIntegerExt :: Word8
tagSmallIntegerExt :: Word8
tagSmallIntegerExt = Word8
97
tagIntegerExt :: Word8
tagIntegerExt :: Word8
tagIntegerExt = Word8
98
tagFloatExt :: Word8
tagFloatExt :: Word8
tagFloatExt = Word8
99
tagAtomExt :: Word8
tagAtomExt :: Word8
tagAtomExt = Word8
100
tagReferenceExt :: Word8
tagReferenceExt :: Word8
tagReferenceExt = Word8
101
tagPortExt :: Word8
tagPortExt :: Word8
tagPortExt = Word8
102
tagPidExt :: Word8
tagPidExt :: Word8
tagPidExt = Word8
103
tagSmallTupleExt :: Word8
tagSmallTupleExt :: Word8
tagSmallTupleExt = Word8
104
tagLargeTupleExt :: Word8
tagLargeTupleExt :: Word8
tagLargeTupleExt = Word8
105
tagNilExt :: Word8
tagNilExt :: Word8
tagNilExt = Word8
106
tagStringExt :: Word8
tagStringExt :: Word8
tagStringExt = Word8
107
tagListExt :: Word8
tagListExt :: Word8
tagListExt = Word8
108
tagBinaryExt :: Word8
tagBinaryExt :: Word8
tagBinaryExt = Word8
109
tagSmallBigExt :: Word8
tagSmallBigExt :: Word8
tagSmallBigExt = Word8
110
tagLargeBigExt :: Word8
tagLargeBigExt :: Word8
tagLargeBigExt = Word8
111
tagNewFunExt :: Word8
tagNewFunExt :: Word8
tagNewFunExt = Word8
112
tagExportExt :: Word8
tagExportExt :: Word8
tagExportExt = Word8
113
tagNewReferenceExt :: Word8
tagNewReferenceExt :: Word8
tagNewReferenceExt = Word8
114
tagSmallAtomExt :: Word8
tagSmallAtomExt :: Word8
tagSmallAtomExt = Word8
115
tagMapExt :: Word8
tagMapExt :: Word8
tagMapExt = Word8
116
tagFunExt :: Word8
tagFunExt :: Word8
tagFunExt = Word8
117
tagAtomUtf8Ext :: Word8
tagAtomUtf8Ext :: Word8
tagAtomUtf8Ext = Word8
118
tagSmallAtomUtf8Ext :: Word8
tagSmallAtomUtf8Ext :: Word8
tagSmallAtomUtf8Ext = Word8
119
data OtpErlangTerm =
OtpErlangInteger Int
| OtpErlangIntegerBig Integer
| OtpErlangFloat Double
| OtpErlangAtom ByteString
| OtpErlangAtomUTF8 ByteString
| OtpErlangAtomCacheRef Int
| OtpErlangAtomBool Bool
| OtpErlangString ByteString
| OtpErlangBinary ByteString
| OtpErlangBinaryBits (ByteString, Int)
| OtpErlangList [OtpErlangTerm]
| OtpErlangListImproper [OtpErlangTerm]
| OtpErlangTuple [OtpErlangTerm]
| OtpErlangMap (Map OtpErlangTerm OtpErlangTerm)
| OtpErlangPid Pid
| OtpErlangPort Port
| OtpErlangReference Reference
| OtpErlangFunction Function
deriving (Eq OtpErlangTerm
Eq OtpErlangTerm
-> (OtpErlangTerm -> OtpErlangTerm -> Ordering)
-> (OtpErlangTerm -> OtpErlangTerm -> Bool)
-> (OtpErlangTerm -> OtpErlangTerm -> Bool)
-> (OtpErlangTerm -> OtpErlangTerm -> Bool)
-> (OtpErlangTerm -> OtpErlangTerm -> Bool)
-> (OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm)
-> (OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm)
-> Ord OtpErlangTerm
OtpErlangTerm -> OtpErlangTerm -> Bool
OtpErlangTerm -> OtpErlangTerm -> Ordering
OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm
$cmin :: OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm
max :: OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm
$cmax :: OtpErlangTerm -> OtpErlangTerm -> OtpErlangTerm
>= :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c>= :: OtpErlangTerm -> OtpErlangTerm -> Bool
> :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c> :: OtpErlangTerm -> OtpErlangTerm -> Bool
<= :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c<= :: OtpErlangTerm -> OtpErlangTerm -> Bool
< :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c< :: OtpErlangTerm -> OtpErlangTerm -> Bool
compare :: OtpErlangTerm -> OtpErlangTerm -> Ordering
$ccompare :: OtpErlangTerm -> OtpErlangTerm -> Ordering
$cp1Ord :: Eq OtpErlangTerm
Ord, OtpErlangTerm -> OtpErlangTerm -> Bool
(OtpErlangTerm -> OtpErlangTerm -> Bool)
-> (OtpErlangTerm -> OtpErlangTerm -> Bool) -> Eq OtpErlangTerm
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c/= :: OtpErlangTerm -> OtpErlangTerm -> Bool
== :: OtpErlangTerm -> OtpErlangTerm -> Bool
$c== :: OtpErlangTerm -> OtpErlangTerm -> Bool
Eq, Int -> OtpErlangTerm -> ShowS
[OtpErlangTerm] -> ShowS
OtpErlangTerm -> String
(Int -> OtpErlangTerm -> ShowS)
-> (OtpErlangTerm -> String)
-> ([OtpErlangTerm] -> ShowS)
-> Show OtpErlangTerm
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OtpErlangTerm] -> ShowS
$cshowList :: [OtpErlangTerm] -> ShowS
show :: OtpErlangTerm -> String
$cshow :: OtpErlangTerm -> String
showsPrec :: Int -> OtpErlangTerm -> ShowS
$cshowsPrec :: Int -> OtpErlangTerm -> ShowS
Show)
data Error =
InputError String
| OutputError String
| ParseError String
deriving (Error -> Error -> Bool
(Error -> Error -> Bool) -> (Error -> Error -> Bool) -> Eq Error
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Error -> Error -> Bool
$c/= :: Error -> Error -> Bool
== :: Error -> Error -> Bool
$c== :: Error -> Error -> Bool
Eq, Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
(Int -> Error -> ShowS)
-> (Error -> String) -> ([Error] -> ShowS) -> Show Error
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Error] -> ShowS
$cshowList :: [Error] -> ShowS
show :: Error -> String
$cshow :: Error -> String
showsPrec :: Int -> Error -> ShowS
$cshowsPrec :: Int -> Error -> ShowS
Show)
type Result a = Either Error a
ok :: a -> Result a
ok :: a -> Result a
ok a
value = a -> Result a
forall a b. b -> Either a b
Right a
value
errorType :: Error -> Result a
errorType :: Error -> Result a
errorType Error
value = Error -> Result a
forall a b. a -> Either a b
Left Error
value
getUnsignedInt8 :: Word8 -> Int
getUnsignedInt8 :: Word8 -> Int
getUnsignedInt8 Word8
value = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
value
getUnsignedInt16 :: Word16 -> Int
getUnsignedInt16 :: Word16 -> Int
getUnsignedInt16 Word16
value = Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
value
getUnsignedInt32 :: Word32 -> Int
getUnsignedInt32 :: Word32 -> Int
getUnsignedInt32 Word32
value = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
value
getSignedInt32 :: Word32 -> Int
getSignedInt32 :: Word32 -> Int
getSignedInt32 Word32
value = Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
value :: Int32)
getUnsignedInt8or32 :: Bool -> Get Int
getUnsignedInt8or32 :: Bool -> Get Int
getUnsignedInt8or32 Bool
True = do
Word8
value <- Get Word8
Get.getWord8
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
value
getUnsignedInt8or32 Bool
False = do
Word32
value <- Get Word32
Get.getWord32be
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
value
boolTrue :: ByteString
boolTrue :: ByteString
boolTrue = String -> ByteString
Char8.pack String
"true"
boolFalse :: ByteString
boolFalse :: ByteString
boolFalse = String -> ByteString
Char8.pack String
"false"
infixr 4 <>
(<>) :: Monoid.Monoid m => m -> m -> m
<> :: m -> m -> m
(<>) = m -> m -> m
forall a. Monoid a => a -> a -> a
Monoid.mappend
binaryToTerm :: LazyByteString -> Result OtpErlangTerm
binaryToTerm :: LazyByteString -> Result OtpErlangTerm
binaryToTerm LazyByteString
binary =
let size :: Int64
size = LazyByteString -> Int64
LazyByteString.length LazyByteString
binary in
if Int64
size Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
1 then
Error -> Result OtpErlangTerm
forall a. Error -> Result a
errorType (Error -> Result OtpErlangTerm) -> Error -> Result OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String -> Error
ParseError String
"null input"
else if LazyByteString -> Word8
LazyByteString.head LazyByteString
binary Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
tagVersion then
Error -> Result OtpErlangTerm
forall a. Error -> Result a
errorType (Error -> Result OtpErlangTerm) -> Error -> Result OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String -> Error
ParseError String
"invalid version"
else
case Get OtpErlangTerm
-> LazyByteString
-> Either
(LazyByteString, Int64, String)
(LazyByteString, Int64, OtpErlangTerm)
forall a.
Get a
-> LazyByteString
-> Either
(LazyByteString, Int64, String) (LazyByteString, Int64, a)
Get.runGetOrFail Get OtpErlangTerm
binaryToTerms (LazyByteString -> LazyByteString
LazyByteString.tail LazyByteString
binary) of
Left (LazyByteString
_, Int64
_, String
err) ->
Error -> Result OtpErlangTerm
forall a. Error -> Result a
errorType (Error -> Result OtpErlangTerm) -> Error -> Result OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String -> Error
ParseError String
err
Right (LazyByteString
_, Int64
_, OtpErlangTerm
term) ->
OtpErlangTerm -> Result OtpErlangTerm
forall a. a -> Result a
ok OtpErlangTerm
term
termToBinary :: OtpErlangTerm -> Int -> Result LazyByteString
termToBinary :: OtpErlangTerm -> Int -> Result LazyByteString
termToBinary OtpErlangTerm
term Int
compressed
| Int
compressed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (-Int
1) Bool -> Bool -> Bool
|| Int
compressed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
9 =
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
InputError String
"compressed in [-1..9]"
| Bool
otherwise =
case OtpErlangTerm -> Result LazyByteString
termsToBinary OtpErlangTerm
term of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right LazyByteString
dataUncompressed ->
if Int
compressed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (-Int
1) then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Word8 -> LazyByteString -> LazyByteString
LazyByteString.cons Word8
tagVersion LazyByteString
dataUncompressed
else
let sizeUncompressed :: Int64
sizeUncompressed =
LazyByteString -> Int64
LazyByteString.length LazyByteString
dataUncompressed
params :: CompressParams
params = CompressParams
Zlib.defaultCompressParams {
compressLevel :: CompressionLevel
Zlib.compressLevel =
Int -> CompressionLevel
Zlib.CompressionLevel Int
compressed }
dataCompressed :: LazyByteString
dataCompressed =
CompressParams -> LazyByteString -> LazyByteString
Zlib.compressWith CompressParams
params LazyByteString
dataUncompressed in
if Int64
sizeUncompressed Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
> Int64
4294967295 then
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
else
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagVersion Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
tagCompressedZlib Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
sizeUncompressed) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
LazyByteString -> Builder
Builder.lazyByteString LazyByteString
dataCompressed
binaryToTerms :: Get OtpErlangTerm
binaryToTerms :: Get OtpErlangTerm
binaryToTerms = do
Word8
tag <- Get Word8
Get.getWord8
case () of
()
_ | Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewFloatExt -> do
Double
value <- Get Double
Get.getDoublebe
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Double -> OtpErlangTerm
OtpErlangFloat Double
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagBitBinaryExt -> do
Word32
j <- Get Word32
Get.getWord32be
Word8
bits <- Get Word8
Get.getWord8
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ (ByteString, Int) -> OtpErlangTerm
OtpErlangBinaryBits (ByteString
value, Word8 -> Int
getUnsignedInt8 Word8
bits)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomCacheRef -> do
Word8
value <- Get Word8
Get.getWord8
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Int -> OtpErlangTerm
OtpErlangAtomCacheRef (Int -> OtpErlangTerm) -> Int -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallIntegerExt -> do
Word8
value <- Get Word8
Get.getWord8
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Int -> OtpErlangTerm
OtpErlangInteger (Int -> OtpErlangTerm) -> Int -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagIntegerExt -> do
Word32
value <- Get Word32
Get.getWord32be
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Int -> OtpErlangTerm
OtpErlangInteger (Int -> OtpErlangTerm) -> Int -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getSignedInt32 Word32
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagFloatExt -> do
ByteString
str <- Int -> Get ByteString
Get.getByteString Int
31
let value :: String
value = ByteString -> String
Char8.unpack (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> ByteString -> ByteString
Char8.takeWhile (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\0') ByteString
str
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Double -> OtpErlangTerm
OtpErlangFloat (String -> Double
forall a. Read a => String -> a
read String
value :: Double)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomExt -> do
Word16
j <- Get Word16
Get.getWord16be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
getUnsignedInt16 Word16
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtom ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewPortExt Bool -> Bool -> Bool
||
Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagReferenceExt Bool -> Bool -> Bool
|| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagPortExt -> do
(Word8
nodeTag, ByteString
node) <- Get (Word8, ByteString)
binaryToAtom
ByteString
eid <- Int -> Get ByteString
Get.getByteString Int
4
let creationSize :: Int
creationSize = if Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewPortExt then Int
4 else Int
1
ByteString
creation <- Int -> Get ByteString
Get.getByteString Int
creationSize
if Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagReferenceExt then
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Reference -> OtpErlangTerm
OtpErlangReference (Reference -> OtpErlangTerm) -> Reference -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> ByteString -> ByteString -> Reference
E.Reference
Word8
nodeTag ByteString
node ByteString
eid ByteString
creation
else
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Port -> OtpErlangTerm
OtpErlangPort (Port -> OtpErlangTerm) -> Port -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> ByteString -> ByteString -> Port
E.Port
Word8
nodeTag ByteString
node ByteString
eid ByteString
creation
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewPidExt Bool -> Bool -> Bool
|| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagPidExt -> do
(Word8
nodeTag, ByteString
node) <- Get (Word8, ByteString)
binaryToAtom
ByteString
eid <- Int -> Get ByteString
Get.getByteString Int
4
ByteString
serial <- Int -> Get ByteString
Get.getByteString Int
4
let creationSize :: Int
creationSize = if Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewPidExt then Int
4 else Int
1
ByteString
creation <- Int -> Get ByteString
Get.getByteString Int
creationSize
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Pid -> OtpErlangTerm
OtpErlangPid (Pid -> OtpErlangTerm) -> Pid -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8
-> ByteString -> ByteString -> ByteString -> ByteString -> Pid
E.Pid
Word8
nodeTag ByteString
node ByteString
eid ByteString
serial ByteString
creation
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallTupleExt Bool -> Bool -> Bool
|| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagLargeTupleExt -> do
Int
length <- Bool -> Get Int
getUnsignedInt8or32 (Bool -> Get Int) -> Bool -> Get Int
forall a b. (a -> b) -> a -> b
$ Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallTupleExt
[OtpErlangTerm]
value <- Int -> Get [OtpErlangTerm]
binaryToTermSequence Int
length
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [OtpErlangTerm] -> OtpErlangTerm
OtpErlangTuple [OtpErlangTerm]
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNilExt -> do
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [OtpErlangTerm] -> OtpErlangTerm
OtpErlangList []
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagStringExt -> do
Word16
j <- Get Word16
Get.getWord16be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
getUnsignedInt16 Word16
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangString ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagListExt -> do
Word32
length <- Get Word32
Get.getWord32be
[OtpErlangTerm]
tmp <- Int -> Get [OtpErlangTerm]
binaryToTermSequence (Int -> Get [OtpErlangTerm]) -> Int -> Get [OtpErlangTerm]
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
length
OtpErlangTerm
tail <- Get OtpErlangTerm
binaryToTerms
if OtpErlangTerm
tail OtpErlangTerm -> OtpErlangTerm -> Bool
forall a. Eq a => a -> a -> Bool
== [OtpErlangTerm] -> OtpErlangTerm
OtpErlangList [] then
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [OtpErlangTerm] -> OtpErlangTerm
OtpErlangList [OtpErlangTerm]
tmp
else
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [OtpErlangTerm] -> OtpErlangTerm
OtpErlangListImproper ([OtpErlangTerm] -> OtpErlangTerm)
-> [OtpErlangTerm] -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [OtpErlangTerm]
tmp [OtpErlangTerm] -> [OtpErlangTerm] -> [OtpErlangTerm]
forall a. [a] -> [a] -> [a]
++ [OtpErlangTerm
tail]
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagBinaryExt -> do
Word32
j <- Get Word32
Get.getWord32be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangBinary ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallBigExt Bool -> Bool -> Bool
|| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagLargeBigExt -> do
Int
j <- Bool -> Get Int
getUnsignedInt8or32 (Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallBigExt)
Word8
sign <- Get Word8
Get.getWord8
[Word8]
digits <- Int -> Get Word8 -> Get [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
j Get Word8
Get.getWord8
let f :: Word8 -> Integer -> Integer
f = (\Word8
d -> \Integer
b -> Integer
b Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> (Word8 -> Int) -> Word8 -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
getUnsignedInt8) Word8
d)
value :: Integer
value = (Word8 -> Integer -> Integer) -> Integer -> [Word8] -> Integer
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr Word8 -> Integer -> Integer
f (Integer
0 :: Integer) [Word8]
digits
if Word8
sign Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
1 then
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Integer -> OtpErlangTerm
OtpErlangIntegerBig (Integer -> OtpErlangTerm) -> Integer -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ (-Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
value
else
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Integer -> OtpErlangTerm
OtpErlangIntegerBig Integer
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewFunExt -> do
Word32
length <- Get Word32
Get.getWord32be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
length
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Function -> OtpErlangTerm
OtpErlangFunction (Function -> OtpErlangTerm) -> Function -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Function
E.Function
Word8
tag ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagExportExt -> do
Int
length <- Get Int -> Get Int
forall a. Get a -> Get a
Get.lookAhead (Get Int -> Get Int) -> Get Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Get Int
binaryToExportSize
ByteString
value <- Int -> Get ByteString
Get.getByteString Int
length
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Function -> OtpErlangTerm
OtpErlangFunction (Function -> OtpErlangTerm) -> Function -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Function
E.Function
Word8
tag ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewerReferenceExt Bool -> Bool -> Bool
|| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewReferenceExt -> do
Word16
j <- Get Word16
Get.getWord16be
(Word8
nodeTag, ByteString
node) <- Get (Word8, ByteString)
binaryToAtom
let creationSize :: Int
creationSize = if Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewerReferenceExt then Int
4 else Int
1
ByteString
creation <- Int -> Get ByteString
Get.getByteString Int
creationSize
ByteString
eid <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ (Word16 -> Int
getUnsignedInt16 Word16
j) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
4
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Reference -> OtpErlangTerm
OtpErlangReference (Reference -> OtpErlangTerm) -> Reference -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> ByteString -> ByteString -> Reference
E.Reference
Word8
nodeTag ByteString
node ByteString
eid ByteString
creation
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallAtomExt -> do
Word8
j <- Get Word8
Get.getWord8
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
j
if ByteString
value ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
boolTrue then
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Bool -> OtpErlangTerm
OtpErlangAtomBool Bool
True
else if ByteString
value ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
boolFalse then
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Bool -> OtpErlangTerm
OtpErlangAtomBool Bool
False
else
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtom ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagMapExt -> do
Word32
length <- Get Word32
Get.getWord32be
[(OtpErlangTerm, OtpErlangTerm)]
pairs <- Int
-> Get (OtpErlangTerm, OtpErlangTerm)
-> Get [(OtpErlangTerm, OtpErlangTerm)]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (Word32 -> Int
getUnsignedInt32 Word32
length) Get (OtpErlangTerm, OtpErlangTerm)
binaryToMapPair
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Map OtpErlangTerm OtpErlangTerm -> OtpErlangTerm
OtpErlangMap (Map OtpErlangTerm OtpErlangTerm -> OtpErlangTerm)
-> Map OtpErlangTerm OtpErlangTerm -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ [(OtpErlangTerm, OtpErlangTerm)] -> Map OtpErlangTerm OtpErlangTerm
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(OtpErlangTerm, OtpErlangTerm)]
pairs
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagFunExt -> do
Int
length <- Get Int -> Get Int
forall a. Get a -> Get a
Get.lookAhead (Get Int -> Get Int) -> Get Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Get Int
binaryToFunSize
ByteString
value <- Int -> Get ByteString
Get.getByteString Int
length
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Function -> OtpErlangTerm
OtpErlangFunction (Function -> OtpErlangTerm) -> Function -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Function
E.Function
Word8
tag ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomUtf8Ext -> do
Word16
j <- Get Word16
Get.getWord16be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word16 -> Int
getUnsignedInt16 Word16
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtomUTF8 ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallAtomUtf8Ext -> do
Word8
j <- Get Word8
Get.getWord8
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
j
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm -> Get OtpErlangTerm)
-> OtpErlangTerm -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtomUTF8 ByteString
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagCompressedZlib -> do
Word32
sizeUncompressed <- Get Word32
Get.getWord32be
LazyByteString
compressed <- Get LazyByteString
Get.getRemainingLazyByteString
let dataUncompressed :: LazyByteString
dataUncompressed = LazyByteString -> LazyByteString
Zlib.decompress (LazyByteString -> LazyByteString)
-> LazyByteString -> LazyByteString
forall a b. (a -> b) -> a -> b
$ LazyByteString
compressed
size1 :: Int64
size1 = Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int64) -> Int -> Int64
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getUnsignedInt32 Word32
sizeUncompressed
size2 :: Int64
size2 = LazyByteString -> Int64
LazyByteString.length LazyByteString
dataUncompressed
if Int64
size1 Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== Int64
0 Bool -> Bool -> Bool
|| Int64
size1 Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
/= Int64
size2 then
String -> Get OtpErlangTerm
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get OtpErlangTerm) -> String -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String
"compression corrupt"
else
case Get OtpErlangTerm
-> LazyByteString
-> Either
(LazyByteString, Int64, String)
(LazyByteString, Int64, OtpErlangTerm)
forall a.
Get a
-> LazyByteString
-> Either
(LazyByteString, Int64, String) (LazyByteString, Int64, a)
Get.runGetOrFail Get OtpErlangTerm
binaryToTerms LazyByteString
dataUncompressed of
Left (LazyByteString
_, Int64
_, String
err) ->
String -> Get OtpErlangTerm
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
err
Right (LazyByteString
_, Int64
_, OtpErlangTerm
term) ->
OtpErlangTerm -> Get OtpErlangTerm
forall (m :: * -> *) a. Monad m => a -> m a
return OtpErlangTerm
term
| Bool
otherwise ->
String -> Get OtpErlangTerm
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get OtpErlangTerm) -> String -> Get OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String
"invalid tag"
binaryToTermSequence :: Int -> Get [OtpErlangTerm]
binaryToTermSequence :: Int -> Get [OtpErlangTerm]
binaryToTermSequence Int
length = do
[OtpErlangTerm]
value <- Int -> Get OtpErlangTerm -> Get [OtpErlangTerm]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
length Get OtpErlangTerm
binaryToTerms
[OtpErlangTerm] -> Get [OtpErlangTerm]
forall (m :: * -> *) a. Monad m => a -> m a
return [OtpErlangTerm]
value
binaryToMapPair :: Get (OtpErlangTerm, OtpErlangTerm)
binaryToMapPair :: Get (OtpErlangTerm, OtpErlangTerm)
binaryToMapPair = do
OtpErlangTerm
key <- Get OtpErlangTerm
binaryToTerms
OtpErlangTerm
value <- Get OtpErlangTerm
binaryToTerms
(OtpErlangTerm, OtpErlangTerm)
-> Get (OtpErlangTerm, OtpErlangTerm)
forall (m :: * -> *) a. Monad m => a -> m a
return (OtpErlangTerm
key, OtpErlangTerm
value)
binaryToExportSize :: Get Int
binaryToExportSize :: Get Int
binaryToExportSize = do
Int64
oldI <- Get Int64
Get.bytesRead
(Word8
_, ByteString
_) <- Get (Word8, ByteString)
binaryToAtom
(Word8
_, ByteString
_) <- Get (Word8, ByteString)
binaryToAtom
Word8
arityTag <- Get Word8
Get.getWord8
Word8
_ <- Get Word8
Get.getWord8
Int64
i <- Get Int64
Get.bytesRead
if Word8
arityTag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallIntegerExt then
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64
i Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
- Int64
oldI)
else
String -> Get Int
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get Int) -> String -> Get Int
forall a b. (a -> b) -> a -> b
$ String
"invalid small integer tag"
binaryToFunSize :: Get Int
binaryToFunSize :: Get Int
binaryToFunSize = do
Int64
oldI <- Get Int64
Get.bytesRead
Word32
numfree <- Get Word32
Get.getWord32be
Pid
_ <- Get Pid
binaryToPid
(Word8
_, ByteString
_) <- Get (Word8, ByteString)
binaryToAtom
Int
_ <- Get Int
binaryToInteger
Int
_ <- Get Int
binaryToInteger
[OtpErlangTerm]
_ <- Int -> Get [OtpErlangTerm]
binaryToTermSequence (Word32 -> Int
getUnsignedInt32 Word32
numfree)
Int64
i <- Get Int64
Get.bytesRead
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64
i Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
- Int64
oldI)
binaryToInteger :: Get Int
binaryToInteger :: Get Int
binaryToInteger = do
Word8
tag <- Get Word8
Get.getWord8
case () of
()
_ | Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallIntegerExt -> do
Word8
value <- Get Word8
Get.getWord8
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Word8 -> Int
getUnsignedInt8 Word8
value
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagIntegerExt -> do
Word32
value <- Get Word32
Get.getWord32be
Int -> Get Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Get Int) -> Int -> Get Int
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
getSignedInt32 Word32
value
| Bool
otherwise ->
String -> Get Int
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get Int) -> String -> Get Int
forall a b. (a -> b) -> a -> b
$ String
"invalid integer tag"
binaryToPid :: Get Pid
binaryToPid :: Get Pid
binaryToPid = do
Word8
tag <- Get Word8
Get.getWord8
case () of
()
_ | Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagNewPidExt -> do
(Word8
nodeTag, ByteString
node) <- Get (Word8, ByteString)
binaryToAtom
ByteString
eid <- Int -> Get ByteString
Get.getByteString Int
4
ByteString
serial <- Int -> Get ByteString
Get.getByteString Int
4
ByteString
creation <- Int -> Get ByteString
Get.getByteString Int
4
Pid -> Get Pid
forall (m :: * -> *) a. Monad m => a -> m a
return (Pid -> Get Pid) -> Pid -> Get Pid
forall a b. (a -> b) -> a -> b
$ Word8
-> ByteString -> ByteString -> ByteString -> ByteString -> Pid
E.Pid
Word8
nodeTag ByteString
node ByteString
eid ByteString
serial ByteString
creation
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagPidExt -> do
(Word8
nodeTag, ByteString
node) <- Get (Word8, ByteString)
binaryToAtom
ByteString
eid <- Int -> Get ByteString
Get.getByteString Int
4
ByteString
serial <- Int -> Get ByteString
Get.getByteString Int
4
ByteString
creation <- Int -> Get ByteString
Get.getByteString Int
1
Pid -> Get Pid
forall (m :: * -> *) a. Monad m => a -> m a
return (Pid -> Get Pid) -> Pid -> Get Pid
forall a b. (a -> b) -> a -> b
$ Word8
-> ByteString -> ByteString -> ByteString -> ByteString -> Pid
E.Pid
Word8
nodeTag ByteString
node ByteString
eid ByteString
serial ByteString
creation
| Bool
otherwise ->
String -> Get Pid
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get Pid) -> String -> Get Pid
forall a b. (a -> b) -> a -> b
$ String
"invalid pid tag"
binaryToAtom :: Get (Word8, ByteString)
binaryToAtom :: Get (Word8, ByteString)
binaryToAtom = do
Word8
tag <- Get Word8
Get.getWord8
case () of
()
_ | Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomExt -> do
Word16
j <- Get Word16 -> Get Word16
forall a. Get a -> Get a
Get.lookAhead (Get Word16 -> Get Word16) -> Get Word16 -> Get Word16
forall a b. (a -> b) -> a -> b
$ Get Word16
Get.getWord16be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Word16 -> Int
getUnsignedInt16 Word16
j)
(Word8, ByteString) -> Get (Word8, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
tag, ByteString
value)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomCacheRef -> do
ByteString
value <- Int -> Get ByteString
Get.getByteString Int
1
(Word8, ByteString) -> Get (Word8, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
tag, ByteString
value)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallAtomExt -> do
Word8
j <- Get Word8 -> Get Word8
forall a. Get a -> Get a
Get.lookAhead (Get Word8 -> Get Word8) -> Get Word8 -> Get Word8
forall a b. (a -> b) -> a -> b
$ Get Word8
Get.getWord8
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Word8 -> Int
getUnsignedInt8 Word8
j)
(Word8, ByteString) -> Get (Word8, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
tag, ByteString
value)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagAtomUtf8Ext -> do
Word16
j <- Get Word16 -> Get Word16
forall a. Get a -> Get a
Get.lookAhead (Get Word16 -> Get Word16) -> Get Word16 -> Get Word16
forall a b. (a -> b) -> a -> b
$ Get Word16
Get.getWord16be
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Word16 -> Int
getUnsignedInt16 Word16
j)
(Word8, ByteString) -> Get (Word8, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
tag, ByteString
value)
| Word8
tag Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
tagSmallAtomUtf8Ext -> do
Word8
j <- Get Word8 -> Get Word8
forall a. Get a -> Get a
Get.lookAhead (Get Word8 -> Get Word8) -> Get Word8 -> Get Word8
forall a b. (a -> b) -> a -> b
$ Get Word8
Get.getWord8
ByteString
value <- Int -> Get ByteString
Get.getByteString (Int -> Get ByteString) -> Int -> Get ByteString
forall a b. (a -> b) -> a -> b
$ Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Word8 -> Int
getUnsignedInt8 Word8
j)
(Word8, ByteString) -> Get (Word8, ByteString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8
tag, ByteString
value)
| Bool
otherwise ->
String -> Get (Word8, ByteString)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Get (Word8, ByteString))
-> String -> Get (Word8, ByteString)
forall a b. (a -> b) -> a -> b
$ String
"invalid atom tag"
termsToBinary :: OtpErlangTerm -> Result LazyByteString
termsToBinary :: OtpErlangTerm -> Result LazyByteString
termsToBinary (OtpErlangInteger Int
value)
| Int
value Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
value Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 =
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagSmallIntegerExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
value)
| Int
value Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= (-Int
2147483648) Bool -> Bool -> Bool
&& Int
value Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
2147483647 =
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagIntegerExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Int32 -> Builder
Builder.int32BE (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
value)
| Bool
otherwise =
OtpErlangTerm -> Result LazyByteString
termsToBinary (OtpErlangTerm -> Result LazyByteString)
-> OtpErlangTerm -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Integer -> OtpErlangTerm
OtpErlangIntegerBig (Integer -> OtpErlangTerm) -> Integer -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
value
termsToBinary (OtpErlangIntegerBig Integer
value) =
let sign :: Word8
sign = if Integer
value Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 then Word8
1 else Word8
0
loop :: a -> LazyByteString -> LazyByteString
loop a
bignum LazyByteString
l =
if a
bignum a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 then
a -> LazyByteString -> LazyByteString
loop (a
bignum a -> a -> a
forall a. Integral a => a -> a -> a
`quot` a
256)
(Word8 -> LazyByteString -> LazyByteString
LazyByteString.cons (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8) -> a -> Word8
forall a b. (a -> b) -> a -> b
$ a
bignum a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
255) LazyByteString
l)
else
LazyByteString -> LazyByteString
LazyByteString.reverse LazyByteString
l
lResult :: LazyByteString
lResult = Integer -> LazyByteString -> LazyByteString
forall a.
(Integral a, Bits a) =>
a -> LazyByteString -> LazyByteString
loop (Integer -> Integer
forall a. Num a => a -> a
abs Integer
value) LazyByteString
LazyByteString.empty
lLength :: Int64
lLength = LazyByteString -> Int64
LazyByteString.length LazyByteString
lResult in
if Int64
lLength Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
255 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagSmallBigExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
lLength) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
sign Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
LazyByteString -> Builder
Builder.lazyByteString LazyByteString
lResult
else if Int64
lLength Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4294967295 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagLargeBigExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
lLength) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
sign Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
LazyByteString -> Builder
Builder.lazyByteString LazyByteString
lResult
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangFloat Double
value) =
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagNewFloatExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Double -> Builder
Builder.doubleBE Double
value
termsToBinary (OtpErlangAtom ByteString
value) =
let length :: Int
length = ByteString -> Int
ByteString.length ByteString
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagSmallAtomExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
65535 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagAtomExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word16 -> Builder
Builder.word16BE (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint16 overflow"
termsToBinary (OtpErlangAtomUTF8 ByteString
value) =
let length :: Int
length = ByteString -> Int
ByteString.length ByteString
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagSmallAtomUtf8Ext Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
65535 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagAtomUtf8Ext Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word16 -> Builder
Builder.word16BE (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint16 overflow"
termsToBinary (OtpErlangAtomCacheRef Int
value) =
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagAtomCacheRef Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
value)
termsToBinary (OtpErlangAtomBool Bool
value) =
if Bool
value then
OtpErlangTerm -> Result LazyByteString
termsToBinary (OtpErlangTerm -> Result LazyByteString)
-> OtpErlangTerm -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtom (ByteString -> OtpErlangTerm) -> ByteString -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Char8.pack String
"true"
else
OtpErlangTerm -> Result LazyByteString
termsToBinary (OtpErlangTerm -> Result LazyByteString)
-> OtpErlangTerm -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangAtom (ByteString -> OtpErlangTerm) -> ByteString -> OtpErlangTerm
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Char8.pack String
"false"
termsToBinary (OtpErlangString ByteString
value) =
let length :: Int
length = ByteString -> Int
ByteString.length ByteString
value in
if Int
length Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagNilExt
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
65535 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagStringExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word16 -> Builder
Builder.word16BE (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagListExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
tagSmallIntegerExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString
(Word8 -> ByteString -> ByteString
ByteString.intersperse Word8
tagSmallIntegerExt ByteString
value) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
tagNilExt
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangBinary ByteString
value) =
let length :: Int
length = ByteString -> Int
ByteString.length ByteString
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagBinaryExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangBinaryBits (ByteString
value, Int
8)) =
OtpErlangTerm -> Result LazyByteString
termsToBinary (OtpErlangTerm -> Result LazyByteString)
-> OtpErlangTerm -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> OtpErlangTerm
OtpErlangBinary ByteString
value
termsToBinary (OtpErlangBinaryBits (ByteString
value, Int
bits)) =
let length :: Int
length = ByteString -> Int
ByteString.length ByteString
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagBinaryExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
bits) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangList [OtpErlangTerm]
value) =
let length :: Int
length = [OtpErlangTerm] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [OtpErlangTerm]
value in
if Int
length Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagNilExt
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
case [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [OtpErlangTerm]
value Builder
forall a. Monoid a => a
Monoid.mempty of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right Builder
listValue ->
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagListExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Builder
listValue Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
tagNilExt
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangListImproper [OtpErlangTerm]
value) =
let length :: Int
length = [OtpErlangTerm] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [OtpErlangTerm]
value in
if Int
length Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagNilExt
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
case [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [OtpErlangTerm]
value Builder
forall a. Monoid a => a
Monoid.mempty of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right Builder
listValue ->
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagListExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ Int
length Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Builder
listValue
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangTuple [OtpErlangTerm]
value) =
let length :: Int
length = [OtpErlangTerm] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
List.length [OtpErlangTerm]
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 then
case [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [OtpErlangTerm]
value Builder
forall a. Monoid a => a
Monoid.mempty of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right Builder
tupleValue ->
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagSmallTupleExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Builder
tupleValue
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
case [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [OtpErlangTerm]
value Builder
forall a. Monoid a => a
Monoid.mempty of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right Builder
tupleValue ->
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagLargeTupleExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Builder
tupleValue
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangMap Map OtpErlangTerm OtpErlangTerm
value) =
let length :: Int
length = Map OtpErlangTerm OtpErlangTerm -> Int
forall k a. Map k a -> Int
Map.size Map OtpErlangTerm OtpErlangTerm
value in
if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
4294967295 then
case (Result Builder
-> OtpErlangTerm -> OtpErlangTerm -> Result Builder)
-> Result Builder
-> Map OtpErlangTerm OtpErlangTerm
-> Result Builder
forall a k b. (a -> k -> b -> a) -> a -> Map k b -> a
Map.foldlWithKey Result Builder -> OtpErlangTerm -> OtpErlangTerm -> Result Builder
mapPairToBinary (Builder -> Result Builder
forall a b. b -> Either a b
Right Builder
forall a. Monoid a => a
Monoid.mempty) Map OtpErlangTerm OtpErlangTerm
value of
Left Error
err ->
Error -> Result LazyByteString
forall a. Error -> Result a
errorType Error
err
Right Builder
mapValue ->
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagMapExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word32 -> Builder
Builder.word32BE (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Builder
mapValue
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint32 overflow"
termsToBinary (OtpErlangPid (E.Pid Word8
nodeTag ByteString
node ByteString
eid ByteString
serial ByteString
creation)) =
let tag :: Word8
tag =
if (ByteString -> Int
ByteString.length ByteString
creation) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 then
Word8
tagNewPidExt
else
Word8
tagPidExt in
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
nodeTag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
node Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
eid Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
serial Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
creation
termsToBinary (OtpErlangPort (E.Port Word8
nodeTag ByteString
node ByteString
eid ByteString
creation)) =
let tag :: Word8
tag =
if (ByteString -> Int
ByteString.length ByteString
creation) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 then
Word8
tagNewPortExt
else
Word8
tagPortExt in
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
nodeTag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
node Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
eid Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
creation
termsToBinary (OtpErlangReference (E.Reference Word8
nodeTag ByteString
node ByteString
eid ByteString
creation)) =
let length :: Int
length = (ByteString -> Int
ByteString.length ByteString
eid) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
4 in
if Int
length Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tagReferenceExt Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
nodeTag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
node Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
eid Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
creation
else if Int
length Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
65535 then
let tag :: Word8
tag =
if (ByteString -> Int
ByteString.length ByteString
creation) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
4 then
Word8
tagNewerReferenceExt
else
Word8
tagNewReferenceExt in
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word16 -> Builder
Builder.word16BE (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
length) Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
Word8 -> Builder
Builder.word8 Word8
nodeTag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
node Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
creation Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
eid
else
Error -> Result LazyByteString
forall a. Error -> Result a
errorType (Error -> Result LazyByteString) -> Error -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ String -> Error
OutputError String
"uint16 overflow"
termsToBinary (OtpErlangFunction (E.Function Word8
tag ByteString
value)) =
LazyByteString -> Result LazyByteString
forall a. a -> Result a
ok (LazyByteString -> Result LazyByteString)
-> LazyByteString -> Result LazyByteString
forall a b. (a -> b) -> a -> b
$ Builder -> LazyByteString
Builder.toLazyByteString (Builder -> LazyByteString) -> Builder -> LazyByteString
forall a b. (a -> b) -> a -> b
$
Word8 -> Builder
Builder.word8 Word8
tag Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
ByteString -> Builder
Builder.byteString ByteString
value
termSequenceToBinary :: [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary :: [OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [] Builder
builder =
Builder -> Result Builder
forall a. a -> Result a
ok Builder
builder
termSequenceToBinary (OtpErlangTerm
h:[OtpErlangTerm]
t) Builder
builder =
case OtpErlangTerm -> Result LazyByteString
termsToBinary OtpErlangTerm
h of
Left Error
err ->
Error -> Result Builder
forall a. Error -> Result a
errorType Error
err
Right LazyByteString
binary ->
[OtpErlangTerm] -> Builder -> Result Builder
termSequenceToBinary [OtpErlangTerm]
t (Builder
builder Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<> LazyByteString -> Builder
Builder.lazyByteString LazyByteString
binary)
mapPairToBinary :: Result Builder -> OtpErlangTerm -> OtpErlangTerm ->
Result Builder
mapPairToBinary :: Result Builder -> OtpErlangTerm -> OtpErlangTerm -> Result Builder
mapPairToBinary (Left Error
err) OtpErlangTerm
_ OtpErlangTerm
_ =
Error -> Result Builder
forall a. Error -> Result a
errorType Error
err
mapPairToBinary (Right Builder
builder) OtpErlangTerm
key OtpErlangTerm
value =
case OtpErlangTerm -> Result LazyByteString
termsToBinary OtpErlangTerm
key of
Left Error
err ->
Error -> Result Builder
forall a. Error -> Result a
errorType Error
err
Right LazyByteString
binaryKey ->
case OtpErlangTerm -> Result LazyByteString
termsToBinary OtpErlangTerm
value of
Left Error
err ->
Error -> Result Builder
forall a. Error -> Result a
errorType Error
err
Right LazyByteString
binaryValue ->
Builder -> Result Builder
forall a. a -> Result a
ok (Builder -> Result Builder) -> Builder -> Result Builder
forall a b. (a -> b) -> a -> b
$ Builder
builder Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
LazyByteString -> Builder
Builder.lazyByteString LazyByteString
binaryKey Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
<>
LazyByteString -> Builder
Builder.lazyByteString LazyByteString
binaryValue