purescript-parsing-dataview/README.md

112 lines
3.6 KiB
Markdown
Raw Normal View History

2020-02-26 05:30:28 +03:00
# purescript-parsing-dataview
2020-02-28 15:00:45 +03:00
[![CI](https://github.com/jamesdbrock/purescript-parsing-dataview/workflows/CI/badge.svg?branch=master)](https://github.com/jamesdbrock/purescript-parsing-dataview/actions)
2020-02-26 05:01:10 +03:00
[![Pursuit](http://pursuit.purescript.org/packages/purescript-parsing-dataview/badge)](http://pursuit.purescript.org/packages/purescript-parsing-dataview/)
2022-05-07 09:56:31 +03:00
Primitive parsers for
`DataView`s on JavaScript `ArrayBuffer`s with the package
2020-07-27 16:28:59 +03:00
[__purescript-parsing__](https://pursuit.purescript.org/packages/purescript-parsing/).
2020-07-27 17:58:17 +03:00
With this package, the input stream support of __purescript-parsing__
2022-05-07 09:56:31 +03:00
is similar to the built-in stream support of [__Megaparsec__](https://hackage.haskell.org/package/megaparsec):
2020-02-26 05:34:10 +03:00
| Stream type | purescript-parsing | Megaparsec |
2020-02-26 05:01:10 +03:00
|----|-----|----|
2022-05-07 09:56:31 +03:00
| UTF-16 strings | String | Text < v2.0|
2022-05-09 04:39:29 +03:00
| UTF-8 strings | | Text ≥ v2.0 |
2020-02-26 05:01:10 +03:00
| Listy strings | Token | String |
2020-07-28 14:10:03 +03:00
| Binary blobs | __DataView__ | ByteString |
2020-07-27 16:28:59 +03:00
## Usage examples
2020-07-27 16:28:59 +03:00
Parse values out of a `dataview :: Data.ArrayBuffer.Types.DataView`. All
`DataView` parsing must be done in an `Effect` context. The `result` will be
`Either` a parse error or the parsed value.
### Parse two numbers
2022-05-07 09:56:31 +03:00
Parse two big-endian IEEE 754 double-precision `Number`s.
2020-07-27 16:28:59 +03:00
```purescript
2021-07-21 14:28:10 +03:00
import Text.Parsing.Parser (runParserT)
import Text.Parsing.Parser.DataView (anyFloat64be)
2020-07-27 16:28:59 +03:00
do
2022-05-07 09:56:31 +03:00
result <- runParserT dataview do
2020-07-27 16:28:59 +03:00
float1 <- anyFloat64be
float2 <- anyFloat64be
pure $ Tuple float1 float2
2020-02-26 05:54:03 +03:00
```
2020-07-27 16:28:59 +03:00
### Parse an array
2022-05-07 09:56:31 +03:00
Parse an array of `n` 32-bit big-endian signed `Int`s.
2020-07-27 16:28:59 +03:00
```purescript
2021-07-21 14:28:10 +03:00
import Text.Parsing.Parser (runParserT)
import Text.Parsing.Parser.DataView (anyUint32be)
import Data.Unfoldable (replicateA)
2020-07-27 16:28:59 +03:00
do
2021-07-21 14:28:10 +03:00
result <- runParserT dataview $ replicateA n anyInt32be
2020-07-27 16:28:59 +03:00
```
2022-05-09 04:39:29 +03:00
### Parse UTF-8
2020-07-27 16:28:59 +03:00
2022-05-07 09:56:31 +03:00
Parse a UTF-8 `String` with a length prefix.
2020-07-27 16:51:03 +03:00
2020-07-27 16:28:59 +03:00
We give this as an example, rather than supporting it in the library, because
it depends on
[`Data.TextDecoding.decodeUtf8`](https://pursuit.purescript.org/packages/purescript-text-encoding/docs/Data.TextDecoding#v:decodeUtf8).
```purescript
2020-09-07 11:07:46 +03:00
import Control.Monad.Trans.Class (lift)
2021-07-21 14:28:10 +03:00
import Data.ArrayBuffer.Types (DataView, Uint8Array)
import Data.ArrayBuffer.DataView (buffer, byteOffset, byteLength)
import Data.ArrayBuffer.Typed (part)
import Effect (Effect, liftEffect)
import Text.Parsing.Parser (runParserT, fail)
import Text.Parsing.Parser.DataView (anyUint32be, takeN)
import Data.UInt (toInt)
import Data.Text.Decoding (decodeUtf8)
2020-09-07 11:07:46 +03:00
2022-05-07 09:56:31 +03:00
-- Make a `Uint8Array` Typed Array from a `DataView`. We can do this
-- for the case of `Uint8` because byte arrays are always aligned.
2021-07-21 14:28:10 +03:00
mkUint8Array :: DataView -> Effect Uint8Array
mkUint8Array dv = part (buffer dv) (byteOffset dv) (byteLength dv)
2020-07-28 09:25:22 +03:00
2020-07-27 16:28:59 +03:00
do
2022-05-07 09:56:31 +03:00
result <- runParserT dataview do
-- Parse a 32-bit big-endian length prefix for the length
-- of the UTF-8 string in bytes.
2020-07-27 17:45:05 +03:00
length <- anyUint32be
2021-07-21 14:28:10 +03:00
stringview <- takeN $ toInt length
stringarray <- lift $ liftEffect $ mkUint8Array stringview
case decodeUtf8 stringarray of
Left err -> fail $ show err
2020-07-27 16:51:03 +03:00
Right s -> pure s
2020-02-26 05:54:03 +03:00
```
2020-07-27 17:45:05 +03:00
## Serialization
2020-07-27 17:45:05 +03:00
This package is for reading (`DataView`s on) `ArrayBuffer`s, not writing
them. See the package
2021-07-21 14:28:10 +03:00
[__arraybuffer-builder__](https://pursuit.purescript.org/packages/purescript-arraybuffer-builder/)
2020-07-27 17:45:05 +03:00
for a way to
serialize and build `ArrayBuffer`s.
## References
* [MDN `ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
2020-07-29 02:58:20 +03:00
* [MDN `DataView`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView)
2022-05-07 08:59:47 +03:00
## Development
Run the tests with the development `spago` file:
```
spago -x spago-dev.dhall test
```