diff --git a/src/Data/ArrayBuffer/ArrayBuffer.js b/src/Data/ArrayBuffer/ArrayBuffer.js index da7a25d..cbc82e3 100644 --- a/src/Data/ArrayBuffer/ArrayBuffer.js +++ b/src/Data/ArrayBuffer/ArrayBuffer.js @@ -6,31 +6,40 @@ exports.create = function(s) { return function () { return new ArrayBuffer(s); }; -} +}; exports.byteLength = function(a) { return a.byteLength; -} +}; exports.sliceImpl = function(s, e, a) { return function () { return a.slice(s, e); }; -} +}; exports.fromArray = function(s) { return (new Uint8Array(s)).buffer; -} +}; exports.fromIntArray = function(s) { return (new Uint8Array(s)).buffer; -} +}; exports.fromString = function(s) { - var l = s.length; - var ab = new ArrayBuffer(l * 2); - var a = new Uint16Array(ab); - for (var i = 0; i < l; i++) - a[i] = s.charCodeAt(i); - return a.buffer; -} + var buf = new ArrayBuffer(s.length*2); + var bufView = new Uint16Array(buf); + for (var i=0, strLen=s.length; i ArrayBuffer -- | Convert a string into an `ArrayBuffer` representation. foreign import fromString :: String -> ArrayBuffer + +foreign import decodeToStringImpl :: Fn3 (String -> Maybe String) (Maybe String) ArrayBuffer (Maybe String) + +-- | Convert an ArrayBuffer into a string. Uses fromCharCode and thus does not support full utf-16 +-- | Is currently only defined for ArrayBuffers with even numbers of bytes, as it assumes the ArrayBuffer encodes string data. +-- | For more general string-encoding forms of data, use a base64 or other encoding scheme. +decodeToString :: ArrayBuffer -> Maybe String +decodeToString = runFn3 decodeToStringImpl Just Nothing diff --git a/test/Main.purs b/test/Main.purs index 9a660d7..66247f4 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -8,7 +8,7 @@ import Data.ArrayBuffer.DataView as DV import Data.ArrayBuffer.Typed as TA import Data.Maybe (Maybe(..), isNothing) import Data.UInt (fromInt, pow) -import Test.QuickCheck (quickCheck', ()) +import Test.QuickCheck (quickCheck', (), quickCheck) assertEffEquals :: forall a. Eq a => Show a => a -> Effect a -> Effect Unit assertEffEquals expectedValue computation = do @@ -36,6 +36,8 @@ main = do assertEquals 4 $ AB.byteLength $ AB.fromArray [1.0, 2.0, 3.0, 4.0] assertEquals 4 $ AB.byteLength $ AB.fromIntArray [1, 2, 3, 4] assertEquals 8 $ AB.byteLength $ AB.fromString "hola" + assertEquals 8 $ AB.byteLength $ AB.fromString "hóla" + assertEquals 10 $ AB.byteLength $ AB.fromString "hóla¡" assertEquals 8 $ AB.byteLength $ DV.buffer $ DV.whole ab8 assertEquals 8 $ AB.byteLength $ DV.buffer $ TA.dataView $ TA.asInt8Array $ DV.whole ab8 @@ -47,6 +49,12 @@ main = do assertEffEquals Nothing $ TA.at fourElementInt8Array 4 assertEffEquals Nothing $ TA.at fourElementInt8Array (-1) + quickCheck + \(s) -> + Just s == (AB.decodeToString $ AB.fromString s) + "Isormorphic arraybuffer conversion with string failed for input " + <> s + assertEquals [1.0, 2.0, 3.0] $ TA.toArray <<< TA.asInt8Array <<< DV.whole $ AB.fromArray [1.0, 2.0, 3.0] twoElementDataView <- do @@ -66,3 +74,4 @@ main = do DV.setUint8 dv t 2 DV.setUint8 dv t 3 DV.getUint32be dv 0 +