packages feed

xcodec-1.0.0.0: README.md

xcodec
------

<!-- TODO: replace header with this to get badges
xcodec [![hackage.haskell.org](
https://img.shields.io/badge/hackage%2Ehaskell%2Eorg-5C5181?logo=haskell)](
https://hackage.haskell.org/package/xcodec)[![builds.sr.ht status](
https://builds.sr.ht/~z0/xcodec/commits/main/xcodec-testing.yml.svg)](
https://builds.sr.ht/~z0/xcodec/commits/main/xcodec-testing.yml?)
-----------------------------------------------------------------
-->

The `XCodec` Haskell library provides a type-class for generic programming on
bit data for writing encoders and decoders for codecs. The `BinaryTranscoder`
class provides a common interface of methods for processing binary data, and
default instances for the `bytestring` types: `ByteString`, `ShortByteString`,
and `LazyByteString`. The `StreamTranscoder` class then provides the abstract
methods for a generic function encoding from and a generic function decoding to
the types implementing `BinaryTranscoder`.

Why?
----

`XCodec` exists to abstract common patterns that arise when writting code with
the `bytestring` library in Haskell:
- Reusing code for `ShortByteString`, `ByteString` and `LazyByteString`.
- Having common interface for transfering into the bytestring `Builder` type.
- Reading to and from numeric values for bitwise manipulation or initializing
from constant values.

Making bytestring code generic, can also make code more memory efficient; for
example, we can write functions for `BinaryTranscoder` and apply them to
`LazyByteString` when reading large files and to `ShortByteString` when working
on smaller internal structures.

Examples
--------

Using `XCodec` we can easily read numeric bit data to binary formats,
programmatically:

```haskell
import Data.ByteString (ByteString)
import Data.ByteString.Short (ShortByteString)
import Data.ByteString.Lazy (LazyByteString)
import Data.Word (Word16)
import Data.XCodec.BinaryTranscoder (packValue)

-- Infers: packValue :: Int -> ByteString
exStrict :: ByteString
exStrict = packValue (0xdeadbeef :: Int)

-- Infers: packValue :: Integer -> LazyByteString
exLazy :: LazyByteString
exLazy = packValue (0xf000000000000000000000000000000000000000000d :: Integer)

-- Infers: packValue :: Word16 -> ShortByteString
exShort :: ShortByteString
exShort = packValue (0xcafe :: Word16)
```

And then serialize them through a common interface:

```haskell
import Data.ByteString.Builder (toLazyByteString, string8)
import Data.XCodec.BinaryTranscoder (serializeValue)

deadbeefThreeTimes :: LazyByteString
deadbeefThreeTimes =
  toLazyByteString . mconcat $
    [ serializeValue exLazy,
      serializeValue exStrict,
      serializeValue exShort,
      string8 "Hello, World!"
    ]
```

It also enables extracting binary data into `Integer` format so that bitwise
transformations can be performed on large sets of binary data in *O(n)* time:

```haskell
import Data.Bits ((.<<.), (.&.))
import Data.Word (Word8)
import Data.XCodec.BinaryTranscoder (unpackValue)

-- Extracts the byte at the bit number (LSB=0).
byteWindowAt :: (BinaryTranscoder bxc) => bxc -> Int -> Word8
byteWindowAt bxc idx = fromIntegral $ (unpackValue bxc .>>. idx) .&. 0xFF
```

<!-- TODO: add unit testing for xcodec

Development
-----------

Unit tests are provided on the main [ipfshs repo](https://git.sr.ht/~z0/ipfshs),
and bugs can be reported on [ipfshs ticket tracker](
https://todo.sr.ht/~z0/ipfshs).

-->

Licensing
---------

The `xcodec` project and its modules are free software and licensed under the
BSD 3-clause license. See [LICENSE.txt](LICENSE.txt).

Copyright © 2026 Zoey McBride | [zoeymcbride@mailbox.org](
mailto:zoeymcbride@mailbox.org)