xcodec: Type-class for working with generically typed codecs.

[ bsd3, data, library, numeric, serialization ] [ Propose Tags ] [ Report a vulnerability ]

This module provides a generic interface for working with binary codecs. It provides a type-class for manipulating bit data and instances for the bytestring package types (ByteString, ShortByteString, and LazyByteString).


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
ci

CI Build options

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 1.0.0.0, 1.1.0.0, 2.0.0.0
Change log CHANGELOG.md
Dependencies array (>=0.5 && <0.6), base (>=4.18 && <5), bytestring (>=0.12 && <0.13), containers (>=0.7 && <8), text (>=2.1 && <2.2) [details]
Tested with ghc ==9.6.7
License BSD-3-Clause
Author Zoey McBride
Maintainer zoeymcbride@mailbox.org
Uploaded by z0 at 2026-07-21T11:46:23Z
Revised Revision 1 made by z0 at 2026-07-21T12:13:50Z
Category Numeric, Data, Serialization
Source repo head: git clone https://git.sr.ht/~z0/xcodec
Distributions
Reverse Dependencies 3 direct, 0 indirect [details]
Downloads 19 total (10 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for xcodec-2.0.0.0

[back to package description]

xcodec hackage.haskell.orgbuilds.sr.ht status

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:

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:

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:

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; unit tests are provided on the main page and bugs can be reported on its ticket tracker. Patches and pull requests can be submitted with git send-email. To build and test this project against all of ipfshs read this section on setting up an ipfshs development environment.

This project can also be built as a standalone library with cabal.

$ 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.

Copyright © 2026 Zoey McBride | zoeymcbride@mailbox.org