Module

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.ArrayBuffers. See the package README for usage examples.

Writing to an ArrayBuffer is an Effectful 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 -> Typetype 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 Builders in this monad call tell, or any of the put* functions in this module.

#Put Source

type Put = PutM Effect

The PutM type reified to Effect, in other words WriterT Builder Effect.

#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 telling 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

#DataBuff Source

data DataBuff

For distinguishing between ArrayBuffer and DataView.

Constructors

#Builder Source

data Builder

Monoidal builder for ArrayBuffers.

We can add two types of things to the Builder:

  1. ArrayBuffer
  2. 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

  • Semigroup Builder

    Left-associative <>> append operator

    TL;DR You 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 matters when we're chaining together three or more Builders in a single associative expression. Instead of

    builder₁ <> builder₂ <> builder₃
    

    we should always prefer to write

    builder₁ <>> builder₂ <>> builder₃
    

    so that we get the efficient snocing of Builders.

    If we build our ArrayBuffers with the PutM monad instead of appending by using the Semigroup instance of Builder, then we always get the efficient snoc case.

  • Monoid Builder

#toView Source

toView :: DataBuff -> DataView

View the contents of DataBuff as a DataView.

#length Source

length :: Builder -> ByteLength

Calculate the total byte length of the Builder, without actually building it yet. O(n)

#(<>>) Source

Operator alias for Data.Semigroup.append (left-associative / precedence 5)