module Capnp.Pointer
( Ptr(..)
, ElementSize(..)
, EltSpec(..)
, parsePtr
, parsePtr'
, serializePtr
, serializePtr'
, parseEltSpec
, serializeEltSpec
)
where
import Data.Bits
import Data.Int
import Data.Word
import Capnp.Bits
data Ptr
= StructPtr !Int32 !Word16 !Word16
| ListPtr !Int32 !EltSpec
| FarPtr !Bool !Word32 !Word32
| CapPtr !Word32
deriving(Int -> Ptr -> ShowS
[Ptr] -> ShowS
Ptr -> String
(Int -> Ptr -> ShowS)
-> (Ptr -> String) -> ([Ptr] -> ShowS) -> Show Ptr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ptr] -> ShowS
$cshowList :: [Ptr] -> ShowS
show :: Ptr -> String
$cshow :: Ptr -> String
showsPrec :: Int -> Ptr -> ShowS
$cshowsPrec :: Int -> Ptr -> ShowS
Show, Ptr -> Ptr -> Bool
(Ptr -> Ptr -> Bool) -> (Ptr -> Ptr -> Bool) -> Eq Ptr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ptr -> Ptr -> Bool
$c/= :: Ptr -> Ptr -> Bool
== :: Ptr -> Ptr -> Bool
$c== :: Ptr -> Ptr -> Bool
Eq)
data ElementSize
= Sz0
| Sz1
| Sz8
| Sz16
| Sz32
| Sz64
| SzPtr
deriving(Int -> ElementSize -> ShowS
[ElementSize] -> ShowS
ElementSize -> String
(Int -> ElementSize -> ShowS)
-> (ElementSize -> String)
-> ([ElementSize] -> ShowS)
-> Show ElementSize
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ElementSize] -> ShowS
$cshowList :: [ElementSize] -> ShowS
show :: ElementSize -> String
$cshow :: ElementSize -> String
showsPrec :: Int -> ElementSize -> ShowS
$cshowsPrec :: Int -> ElementSize -> ShowS
Show, ElementSize -> ElementSize -> Bool
(ElementSize -> ElementSize -> Bool)
-> (ElementSize -> ElementSize -> Bool) -> Eq ElementSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ElementSize -> ElementSize -> Bool
$c/= :: ElementSize -> ElementSize -> Bool
== :: ElementSize -> ElementSize -> Bool
$c== :: ElementSize -> ElementSize -> Bool
Eq, Int -> ElementSize
ElementSize -> Int
ElementSize -> [ElementSize]
ElementSize -> ElementSize
ElementSize -> ElementSize -> [ElementSize]
ElementSize -> ElementSize -> ElementSize -> [ElementSize]
(ElementSize -> ElementSize)
-> (ElementSize -> ElementSize)
-> (Int -> ElementSize)
-> (ElementSize -> Int)
-> (ElementSize -> [ElementSize])
-> (ElementSize -> ElementSize -> [ElementSize])
-> (ElementSize -> ElementSize -> [ElementSize])
-> (ElementSize -> ElementSize -> ElementSize -> [ElementSize])
-> Enum ElementSize
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ElementSize -> ElementSize -> ElementSize -> [ElementSize]
$cenumFromThenTo :: ElementSize -> ElementSize -> ElementSize -> [ElementSize]
enumFromTo :: ElementSize -> ElementSize -> [ElementSize]
$cenumFromTo :: ElementSize -> ElementSize -> [ElementSize]
enumFromThen :: ElementSize -> ElementSize -> [ElementSize]
$cenumFromThen :: ElementSize -> ElementSize -> [ElementSize]
enumFrom :: ElementSize -> [ElementSize]
$cenumFrom :: ElementSize -> [ElementSize]
fromEnum :: ElementSize -> Int
$cfromEnum :: ElementSize -> Int
toEnum :: Int -> ElementSize
$ctoEnum :: Int -> ElementSize
pred :: ElementSize -> ElementSize
$cpred :: ElementSize -> ElementSize
succ :: ElementSize -> ElementSize
$csucc :: ElementSize -> ElementSize
Enum)
data EltSpec
= EltNormal !ElementSize !Word32
| EltComposite !Int32
deriving(Int -> EltSpec -> ShowS
[EltSpec] -> ShowS
EltSpec -> String
(Int -> EltSpec -> ShowS)
-> (EltSpec -> String) -> ([EltSpec] -> ShowS) -> Show EltSpec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EltSpec] -> ShowS
$cshowList :: [EltSpec] -> ShowS
show :: EltSpec -> String
$cshow :: EltSpec -> String
showsPrec :: Int -> EltSpec -> ShowS
$cshowsPrec :: Int -> EltSpec -> ShowS
Show, EltSpec -> EltSpec -> Bool
(EltSpec -> EltSpec -> Bool)
-> (EltSpec -> EltSpec -> Bool) -> Eq EltSpec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EltSpec -> EltSpec -> Bool
$c/= :: EltSpec -> EltSpec -> Bool
== :: EltSpec -> EltSpec -> Bool
$c== :: EltSpec -> EltSpec -> Bool
Eq)
parsePtr :: Word64 -> Maybe Ptr
parsePtr :: Word64 -> Maybe Ptr
parsePtr Word64
0 = Maybe Ptr
forall a. Maybe a
Nothing
parsePtr Word64
p = Ptr -> Maybe Ptr
forall a. a -> Maybe a
Just (Word64 -> Ptr
parsePtr' Word64
p)
parsePtr' :: Word64 -> Ptr
parsePtr' :: Word64 -> Ptr
parsePtr' Word64
word =
case Word64 -> Int -> Int -> Word64
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
0 Int
2 :: Word64 of
Word64
0 -> Int32 -> Word16 -> Word16 -> Ptr
StructPtr
(Word32 -> Int32
i30 (Word64 -> Word32
lo Word64
word))
(Word64 -> Int -> Int -> Word16
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
32 Int
48)
(Word64 -> Int -> Int -> Word16
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
48 Int
64)
Word64
1 -> Int32 -> EltSpec -> Ptr
ListPtr
(Word32 -> Int32
i30 (Word64 -> Word32
lo Word64
word))
(Word64 -> EltSpec
parseEltSpec Word64
word)
Word64
2 -> Bool -> Word32 -> Word32 -> Ptr
FarPtr
(Int -> Bool
forall a. Enum a => Int -> a
toEnum (Word64 -> Int -> Int -> Int
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
2 Int
3))
(Word64 -> Int -> Int -> Word32
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
3 Int
32)
(Word64 -> Int -> Int -> Word32
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
32 Int
64)
Word64
3 -> Word32 -> Ptr
CapPtr (Word64 -> Int -> Int -> Word32
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
32 Int
64)
Word64
_ -> String -> Ptr
forall a. HasCallStack => String -> a
error String
"unreachable"
serializePtr :: Maybe Ptr -> Word64
serializePtr :: Maybe Ptr -> Word64
serializePtr Maybe Ptr
Nothing = Word64
0
serializePtr (Just p :: Ptr
p@(StructPtr (-1) Word16
0 Word16
0)) =
Ptr -> Word64
serializePtr' Ptr
p
serializePtr (Just (StructPtr Int32
_ Word16
0 Word16
0)) =
Ptr -> Word64
serializePtr' (Int32 -> Word16 -> Word16 -> Ptr
StructPtr (-Int32
1) Word16
0 Word16
0)
serializePtr (Just Ptr
p) =
Ptr -> Word64
serializePtr' Ptr
p
serializePtr' :: Ptr -> Word64
serializePtr' :: Ptr -> Word64
serializePtr' (StructPtr Int32
off Word16
dataSz Word16
ptrSz) =
Word32 -> Word64
fromLo (Int32 -> Word32
fromI30 Int32
off) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
dataSz Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
ptrSz Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
48)
serializePtr' (ListPtr Int32
off EltSpec
eltSpec) =
Word64
1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
Word32 -> Word64
fromLo (Int32 -> Word32
fromI30 Int32
off) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
EltSpec -> Word64
serializeEltSpec EltSpec
eltSpec
serializePtr' (FarPtr Bool
twoWords Word32
off Word32
segId) =
Word64
2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Bool -> Int
forall a. Enum a => a -> Int
fromEnum Bool
twoWords) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
2) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
off Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
3) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
segId Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32)
serializePtr' (CapPtr Word32
index) =
Word64
3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
index Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32)
parseEltSpec :: Word64 -> EltSpec
parseEltSpec :: Word64 -> EltSpec
parseEltSpec Word64
word = case Word64 -> Int -> Int -> Int
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
32 Int
35 of
Int
7 -> Int32 -> EltSpec
EltComposite (Word32 -> Int32
i29 (Word64 -> Word32
hi Word64
word))
Int
sz -> ElementSize -> Word32 -> EltSpec
EltNormal (Int -> ElementSize
forall a. Enum a => Int -> a
toEnum Int
sz) (Word64 -> Int -> Int -> Word32
forall a. Integral a => Word64 -> Int -> Int -> a
bitRange Word64
word Int
35 Int
64)
serializeEltSpec :: EltSpec -> Word64
serializeEltSpec :: EltSpec -> Word64
serializeEltSpec (EltNormal ElementSize
sz Word32
len) =
(Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ElementSize -> Int
forall a. Enum a => a -> Int
fromEnum ElementSize
sz) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
len Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
35)
serializeEltSpec (EltComposite Int32
words) =
(Word64
7 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
Word32 -> Word64
fromHi (Int32 -> Word32
fromI29 Int32
words)