forked from purescript-contrib/purescript-arraybuffer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDataView.purs
146 lines (115 loc) · 7.7 KB
/
DataView.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
-- | This module represents the functional bindings to JavaScript's `DataView`
-- | objects. See [MDN's spec](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) for details.
module Data.ArrayBuffer.DataView
( whole
, remainder
, part
, buffer
, byteOffset
, byteLength
, AProxy (..)
, class DataView
, getBE, getLE, setBE, setLE
) where
import Data.ArrayBuffer.Types (ByteOffset, DataView, ByteLength, ArrayBuffer, kind ArrayViewType, Int32, Int16, Int8, Uint32, Uint16, Uint8, Float32, Float64)
import Data.ArrayBuffer.ValueMapping (class BinaryValue, class BytesPerValue)
import Data.Maybe (Maybe(..))
import Data.Typelevel.Num (toInt', class Nat)
import Data.UInt (UInt)
import Effect (Effect)
import Effect.Uncurried (EffectFn2, EffectFn3, EffectFn4, runEffectFn2, runEffectFn3, runEffectFn4)
import Type.Proxy (Proxy(..))
-- | View mapping the whole `ArrayBuffer`.
foreign import whole :: ArrayBuffer -> DataView
foreign import remainderImpl :: EffectFn2 ArrayBuffer ByteOffset DataView
-- | View mapping the rest of an `ArrayBuffer` after an index.
remainder :: ArrayBuffer -> ByteOffset -> Effect DataView
remainder = runEffectFn2 remainderImpl
foreign import partImpl :: EffectFn3 ArrayBuffer ByteOffset ByteLength DataView
-- | View mapping a region of the `ArrayBuffer`.
part :: ArrayBuffer -> ByteOffset -> ByteLength -> Effect DataView
part = runEffectFn3 partImpl
-- | `ArrayBuffer` being mapped by the view.
foreign import buffer :: DataView -> ArrayBuffer
-- | Represents the offset of this view from the start of its `ArrayBuffer`.
foreign import byteOffset :: DataView -> ByteOffset
-- | Represents the length of this view.
foreign import byteLength :: DataView -> ByteLength
data AProxy (a :: ArrayViewType) = AProxy
class BinaryValue a t <= DataView (a :: ArrayViewType) t | a -> t where
getLE :: AProxy a -> DataView -> ByteOffset -> Effect (Maybe t)
getBE :: AProxy a -> DataView -> ByteOffset -> Effect (Maybe t)
setBE :: AProxy a -> DataView -> t -> ByteOffset -> Effect Boolean
setLE :: AProxy a -> DataView -> t -> ByteOffset -> Effect Boolean
foreign import getterImpl :: forall t
. EffectFn3 { just :: t -> Maybe t
, nothing :: Maybe t
, functionName :: String
, littleEndian :: Boolean
, bytesPerValue :: ByteLength
} DataView ByteOffset (Maybe t)
getter :: forall t
. { functionName :: String
, bytesPerValue :: ByteLength
, littleEndian :: Boolean
}
-> DataView -> ByteOffset -> Effect (Maybe t)
getter data' =
runEffectFn3 getterImpl
{ just: Just
, nothing: Nothing
, functionName: data'.functionName
, littleEndian: data'.littleEndian
, bytesPerValue: data'.bytesPerValue
}
foreign import setterImpl :: forall t
. EffectFn4 { functionName :: String
, littleEndian :: Boolean
, bytesPerValue :: ByteLength
} DataView t ByteOffset Boolean
setter :: forall t
. { functionName :: String
, bytesPerValue :: ByteLength
, littleEndian :: Boolean
} -> DataView -> t -> ByteOffset -> Effect Boolean
setter = runEffectFn4 setterImpl
instance dataViewInt8 :: (BytesPerValue Int8 b, Nat b) => DataView Int8 Int where
getBE AProxy = getter {functionName: "getInt8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setInt8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getInt8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setInt8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewInt16 :: (BytesPerValue Int16 b, Nat b) => DataView Int16 Int where
getBE AProxy = getter {functionName: "getInt16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setInt16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getInt16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setInt16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewInt32 :: (BytesPerValue Int32 b, Nat b) => DataView Int32 Int where
getBE AProxy = getter {functionName: "getInt32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setInt32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getInt32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setInt32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewUint8 :: (BytesPerValue Uint8 b, Nat b) => DataView Uint8 UInt where
getBE AProxy = getter {functionName: "getUint8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setUint8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getUint8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setUint8", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewUint16 :: (BytesPerValue Uint16 b, Nat b) => DataView Uint16 UInt where
getBE AProxy = getter {functionName: "getUint16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setUint16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getUint16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setUint16", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewUint32 :: (BytesPerValue Uint32 b, Nat b) => DataView Uint32 UInt where
getBE AProxy = getter {functionName: "getUint32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setUint32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getUint32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setUint32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewFloat32 :: (BytesPerValue Float32 b, Nat b) => DataView Float32 Number where
getBE AProxy = getter {functionName: "getFloat32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setFloat32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getFloat32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setFloat32", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
instance dataViewFloat64 :: (BytesPerValue Float64 b, Nat b) => DataView Float64 Number where
getBE AProxy = getter {functionName: "getFloat64", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
setBE AProxy = setter {functionName: "setFloat64", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: false}
getLE AProxy = getter {functionName: "getFloat64", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}
setLE AProxy = setter {functionName: "setFloat64", bytesPerValue: toInt' (Proxy :: Proxy b), littleEndian: true}