Skip to content

Commit b69f853

Browse files
committed
adding and fixing existing safe get-functions
1 parent 446e210 commit b69f853

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

Foreign/Matlab/Array.hsc

+25-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ module Foreign.Matlab.Array (
3030
mxArrayGet, mxArraySet,
3131
-- | array list access
3232
mxArrayGetList, mxArraySetList,
33-
mxArrayGetAll, mxArraySetAll, mxArrayGetFirst,
33+
mxArrayGetAll, mxArraySetAll,
34+
mxArrayGetSafe, mxArrayGetFirst, mxArrayGetLast,
3435
fromListIO, cellFromListsIO,
3536
isMNull,
3637

@@ -127,7 +128,9 @@ copyMXArray a = withMXArray a mxDuplicateArray >>= mkMXArray
127128
foreign import ccall unsafe mxDestroyArray :: MXArrayPtr -> IO ()
128129
-- |Destroy an array and all of its contents.
129130
freeMXArray :: MXArray a -> MIO ()
130-
freeMXArray a = withMXArray a mxDestroyArray
131+
freeMXArray a = do
132+
withMXArray a mxDestroyArray
133+
mxArraySetSize a [0, 0]
131134

132135
-- | Create and populate an MXArray in one go. Named without 'mx' due to possible
133136
-- | conformity to a typeclass function.
@@ -228,9 +231,26 @@ mxArraySetAll :: MXArrayComponent a => MXArray a -> [a] -> IO ()
228231
mxArraySetAll a = mxArraySetList a mStart
229232

230233
mxArrayGetFirst :: MXArrayComponent a => MXArray a -> MIO (Either String a)
231-
mxArrayGetFirst arr
232-
| isMNull arr = pure $ Left "Couldn't get first element of null array"
233-
| otherwise = Right <$> mxArrayGetOffset arr 0
234+
mxArrayGetFirst arr = mxArrayGetSafe arr 0
235+
236+
mxArrayGetLast :: MXArrayComponent a => MXArray a -> MIO (Either String a)
237+
mxArrayGetLast arr = do
238+
arrLen <- mxArrayLength arr
239+
mxArrayGetSafe arr (arrLen - 1)
240+
241+
-- |Like mxArrayGetOffset but safe.
242+
mxArrayGetSafe :: forall a. MXArrayComponent a => MXArray a -> Int -> MIO (Either String a)
243+
mxArrayGetSafe arr ix
244+
| isMNull arr = pure $ Left "Couldn't get element of null array"
245+
| otherwise = do
246+
arrLen <- mxArrayLength arr
247+
safeGetElem arrLen ix
248+
where
249+
safeGetElem :: Int -> Int -> MIO (Either String a)
250+
safeGetElem aLen aIx
251+
| aIx < aLen = Right <$> mxArrayGetOffset arr aIx
252+
| otherwise = pure $ Left $ "Couldn't get element at index "
253+
<> (show aIx) <> " of " <> (show aLen) <> "-length array"
234254

235255
-- |Safely cast a generic array to a type, or return Nothing if the array does not have the proper type
236256
castMXArray :: forall a. MXArrayComponent a => MAnyArray -> MIO (Maybe (MXArray a))

test/Test/Engine.hs

+21-12
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ runEngineTests host = do
2626
runLocalMatFun eng
2727
cosOfPi eng
2828
testIsMNull eng
29-
testGetFirst eng
29+
testGetFirstLast eng
3030
testAbstractValueUse eng
3131
testTypedAbstractValueUse eng
3232
testGetByteStreamFromArray eng
@@ -60,23 +60,32 @@ testIsMNull eng = do
6060
xa <- createMXScalar (1.0 :: MDouble)
6161
let xaRes = assert (isMNull xa == False) xa
6262
xaResEi <- mxArrayGetFirst xaRes
63-
putStrLn $ " xaResEi is Right: " <> (show $ isRight xaResEi)
63+
putStrLn $ " xaResEi is Right: " <> (show xaResEi)
6464
xae :: MXArray MChar <- createMXArray []
6565
freeMXArray xae
6666
mxLen <- mxArrayLength xae
67-
putStrLn $ "length is " <> (show mxLen)
68-
-- This is a bit surprising, but ok
67+
mxDims <- mxArraySize xae
68+
putStrLn $ "length is " <> (show mxLen) <> " dims are " <> (show $ mxDims)
6969
let xaeRes = assert (isMNull xae == False) xae
7070
xaeResEi <- mxArrayGetFirst xaeRes
71-
putStrLn $ " xaeResEi is Right: " <> (show $ isRight xaeResEi)
72-
73-
testGetFirst :: Engine -> IO ()
74-
testGetFirst eng = do
75-
putStrLn $ "\n-- testGetFirst --"
76-
xa <- createMXScalar (1.0 :: MDouble)
77-
xEi <- mxArrayGetFirst xa
78-
let xRes = assert (xEi == Right 1.0) xEi
71+
putStrLn $ " xaeResEi is Left: " <> (show xaeResEi)
72+
73+
testGetFirstLast :: Engine -> IO ()
74+
testGetFirstLast eng = do
75+
putStrLn $ "\n-- testGetFirstLast --"
76+
let testVal :: MDouble = 1.0
77+
xa <- createMXScalar testVal
78+
xfEi <- mxArrayGetFirst xa
79+
xlEi <- mxArrayGetLast xa
80+
let xRes = assert (xlEi == Right 1.0 && xfEi == xlEi) xfEi
7981
putStrLn $ " xRes is : " <> (show xRes)
82+
threeArray :: MXArray MDouble <- fromListIO [5.0, 6.0, 7.0]
83+
txfEi <- mxArrayGetFirst threeArray
84+
txlEi <- mxArrayGetLast threeArray
85+
let txfRes = assert (txfEi == Right 5.0) txfEi
86+
putStrLn $ " txfRes is : " <> (show txfRes)
87+
let txlRes = assert (txlEi == Right 7.0) txlEi
88+
putStrLn $ " txlRes is : " <> (show txlRes)
8089

8190
testAbstractValueUse :: Engine -> IO ()
8291
testAbstractValueUse eng = do

0 commit comments

Comments
 (0)