# Data.ArrayBuffer.Builder

- Package
- purescript-arraybuffer-builder
- Repository
- jamesdbrock/purescript-arraybuffer-builder

This module provides a `Builder`

monoid and a `PutM`

monad
for serializing `Data.ArrayBuffer.Types.ArrayBuffer`

s.
See the package README for usage examples.

Writing to an `ArrayBuffer`

is an `Effect`

ful activity, so most
functions in this module must be run in a `MonadEffect`

context.

For other operations for working with `ArrayBuffer`

, see
module
`Data.ArrayBuffer.ArrayBuffer`

in package **arraybuffer**.

### #PutM Source

`type PutM :: (Type -> Type) -> Type -> Type`

`type PutM = WriterT Builder`

The `PutM`

monad is a `WriterT Builder`

transformer monad which
gives us do-notation for the `Builder`

monoid. The base monad must be
a `MonadEffect`

.

To append `Builder`

s in this monad call `tell`

, or any of the `put*`

functions in this module.

### #execPutM Source

`execPutM :: forall m. MonadEffect m => MonadRec m => PutM m Unit -> m ArrayBuffer`

Build an `ArrayBuffer`

with do-notation in any `MonadEffect`

. *O(n)* Stack-safe.

### #execPut Source

`execPut :: Put Unit -> Effect ArrayBuffer`

Build an `ArrayBuffer`

with do-notation in `Effect`

. *O(n)* Stack-safe.

### #subBuilder Source

`subBuilder :: forall m. Monad m => PutM m Unit -> PutM m Builder`

Build up a sub-`Builder`

without `tell`

ing it to the `Writer`

yet.

One case where we might want to call a `subBuilder`

is when
serializing length-prefixed messages in some protocol. In that case,
we must serialize the message first, calculate the message length,
append the message length, and then append the message.

In a `PutM`

monad do-block, we can

```
do
messageBuilder <- subBuilder $ do
putField1
putField2
putInt32be $ length messageBuilder
tell messageBuilder
```

### #putArrayBuffer Source

`putArrayBuffer :: forall m. Monad m => ArrayBuffer -> PutM m Unit`

Append an `ArrayBuffer`

to the builder.

### #putDataView Source

`putDataView :: forall m. Monad m => DataView -> PutM m Unit`

Append a `DataView`

to the builder.

### #putDataBuff Source

`putDataBuff :: forall m. Monad m => DataBuff -> PutM m Unit`

Append either an `ArrayBuffer`

or a `DataView`

to the builder.

### #putUint8 Source

`putUint8 :: forall m. MonadEffect m => UInt -> PutM m Unit`

Append an 8-bit unsigned integer (byte) to the builder.

### #putInt8 Source

`putInt8 :: forall m. MonadEffect m => Int -> PutM m Unit`

Append an 8-bit two’s-complement signed integer (char) to the builder.

### #putUint16be Source

`putUint16be :: forall m. MonadEffect m => UInt -> PutM m Unit`

Append a 16-bit big-endian unsigned integer to the builder.

### #putUint16le Source

`putUint16le :: forall m. MonadEffect m => UInt -> PutM m Unit`

Append a 16-bit little-endian unsigned integer to the builder.

### #putInt16be Source

`putInt16be :: forall m. MonadEffect m => Int -> PutM m Unit`

Append a 16-bit big-endian two’s-complement signed integer to the builder.

### #putInt16le Source

`putInt16le :: forall m. MonadEffect m => Int -> PutM m Unit`

Append a 16-bit little-endian two’s-complement signed integer to the builder.

### #putUint32be Source

`putUint32be :: forall m. MonadEffect m => UInt -> PutM m Unit`

Append a 32-bit big-endian unsigned integer to the builder.

### #putUint32le Source

`putUint32le :: forall m. MonadEffect m => UInt -> PutM m Unit`

Append a 32-bit little-endian unsigned integer to the builder.

### #putInt32be Source

`putInt32be :: forall m. MonadEffect m => Int -> PutM m Unit`

Append a 32-bit big-endian two’s-complement signed integer to the builder.

### #putInt32le Source

`putInt32le :: forall m. MonadEffect m => Int -> PutM m Unit`

Append a 32-bit little-endian two’s-complement signed integer to the builder.

### #putFloat32be Source

`putFloat32be :: forall m. MonadEffect m => Float32 -> PutM m Unit`

Append a 32-bit big-endian IEEE single-precision float to the builder.

### #putFloat32le Source

`putFloat32le :: forall m. MonadEffect m => Float32 -> PutM m Unit`

Append a 32-bit little-endian IEEE single-precision float to the builder.

### #putFloat64be Source

`putFloat64be :: forall m. MonadEffect m => Number -> PutM m Unit`

Append a 64-bit big-endian IEEE double-precision float to the builder.

### #putFloat64le Source

`putFloat64le :: forall m. MonadEffect m => Number -> PutM m Unit`

Append a 64-bit little-endian IEEE double-precision float to the builder.

## Re-exports from **Data.**ArrayBuffer.Builder.Internal

### #Builder Source

`data Builder`

Monoidal builder for `ArrayBuffer`

s.

We can add two types of things to the `Builder`

:

`ArrayBuffer`

`DataView`

We might prefer
to add a `DataView`

to a `Builder`

when we’re adding a large slice of data
from some other `ArrayBuffer`

, so that we don’t
need an extra intermediate copy of the slice.

#### Instances

### #length Source

`length :: Builder -> ByteLength`

Calculate the total byte length of the `Builder`

, without actually
building it yet. *O(n)*

## Left-associative

`<>>`

append operatorTL;DRYou probably don't want to use the`Builder`

monoid directly in your code, it’s better to use the`PutM`

monad with do-notation instead.The

`Builder`

monoid in this library is efficient when we`snoc`

single items onto the end of it, or when we only`cons`

single items to the beginning, but it can be less efficient when we are mixing`cons`

and`snoc`

. Most of the time we want to`snoc`

, but the`Semigroup`

append operator`<>`

is right-associative, which means it chains like`cons`

.To solve this, we provide an operator

`<>>`

for appending`Builders`

.`<>>`

is exactly the same as`<>`

, but left-associative, which means it chains like`snoc`

.This

only matterswhen we're chaining together three or more`Builder`

s in a single associative expression. Instead ofwe should always prefer to write

so that we get the efficient

`snoc`

ing of`Builder`

s.If we build our

`ArrayBuffer`

s with the`PutM`

monad instead of appending by using the`Semigroup`

instance of`Builder`

, then we always get the efficient`snoc`

case.