ghcjs / ghcjs-base

base library for GHCJS for JavaScript interaction and marshalling, used by higher level libraries like JSC
MIT License
45 stars 67 forks source link

ByteString <=> ArrayBuffer conversion seems extremely difficult #59

Open stepcut opened 8 years ago

stepcut commented 8 years ago

Libraries like aeson use ByteString and things like JavaScript.Web.WebSocket use ArrayBuffer. Converting from one to the other seems unduly difficult.

For example, I can used, fromByteString :: ByteString -> (Buffer, Int, Int) to get a Buffer from a ByteString and getArrayBuffer :: SomeBuffer any -> SomeArrayBuffer any to convert the Buffer to an ArrayBuffer. Except, that is not good enough because it does not use the offset and length values that fromByteString returns. And I can not seem to find a way to use them. I thought maybe I could use ArrayBuffer.slice except it is not exported.

It seems to me that ByteString <=> ArrayBuffer conversion might common enough that helper functions should provided that do it in a single step?

patrickmn commented 5 years ago

Ran into this as well.

Servant converts from ByteString to ArrayBuffer like this:

    mBody :: BS.ByteString -> ArrayBuffer
    mBody bs = js_bufferSlice offset len $ Buffer.getArrayBuffer buffer
      where
        (buffer, offset, len) = Buffer.fromByteString bs

foreign import javascript unsafe "$3.slice($1, $1 + $2)"
  js_bufferSlice :: Int -> Int -> ArrayBuffer -> ArrayBuffer

and from ArrayBuffer to ByteString like this:

getResponse :: JSXMLHttpRequest -> IO BL.ByteString
getResponse xhr =
    BL.fromStrict
  . Buffer.toByteString 0 Nothing
  . Buffer.createFromArrayBuffer
  <$> js_response xhr