packages feed

xcodec-2.0.0.0: README.md

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/ipfshs-ci.yml.svg)](
https://builds.sr.ht/~z0/xcodec/commits/main/ipfshs-ci.yml?)
------------------------------------------------------------

The xcodec Haskell library provides a type-class for generic programming on
bit data for writing encoders and decoders for codecs. The `Transcoder`
class provides a common interface of methods for processing binary data, and
default instances for the `bytestring` types: `ByteString`, `ShortByteString`,
and `LazyByteString`.

Why?
----

xcodec exists to abstract common patterns that arise when writing code with
the `bytestring` library in Haskell:
- Reusing code for `ShortByteString`, `ByteString` and `LazyByteString`.
- Having common interface for transferring 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 `Transcoder` 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 XCodec.Transcoder (packValue)

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

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

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

And then serialize them through a common interface which makes it easy to
intersperse data from different formats:

```haskell
import Data.ByteString.Builder qualified as Builder
import Data.ByteString.Lazy (LazyByteString)
import XCodec.Transcoder (unpackBuilder)

-- We can join several BXCs and Builders into a single unit of data.
exBuilder :: LazyByteString
exBuilder =
  Builder.toLazyByteString . mconcat $
    [ unpackBuilder exLazy, -- unpackBuilder :: LazyByteString -> Builder
      unpackBuilder exStrict, -- unpackBuilder :: ByteString -> Builder
      unpackBuilder exShort, -- unpackBuilder :: ShortByteString -> Builder
      Builder.string8 "Hello, World!" -- string8 :: String -> Builder
    ]
```

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
with a specified [byte order](https://en.wikipedia.org/wiki/Endianness):

```haskell
import Data.Bits ((.>>.), (.&.))
import Data.Word (Word32)
import XCodec.Transcoder (unpackValueBE, unpackValueLE)

-- We can easily read an entire bit-set representation of transcoder data,
-- directly from LazyByteString because it derives Transcoder. This
-- function produces its big-endian representation
largeBitSet :: Integer
largeBitSet = unpackValueBE exBuilder

-- Now, we can perform bitwise operations on the value, for instance, extracting
-- the lower bits 32nd-63rd bits from a little-endian value
extract32bits :: Word32
extract32bits = fromIntegral ((unpackValueLE exBuilder .>>. 32) .&. 0xFFFFFFFF)
```

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

This project is part of [ipfshs](https://sr.ht/~z0/ipfshs); unit tests are
provided on the main page and bugs can be reported on its [ticket tracker](
https://todo.sr.ht/~z0/ipfshs). Patches and pull requests can be submitted with
[`git send-email`](https://git-send-email.io/). To build and test this project
against all of ipfshs read [this](https://sr.ht/~z0/ipfshs/#development)
section on setting up an ipfshs development environment.

This project can also be built as a standalone library with [`cabal`](
https://github.com/haskell/cabal#ways-to-get-the-cabal-install-binary).

```shell
$ git clone https://git.sr.ht/~z0/xcodec
$ cd ipldm
$ cabal build
```

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)