------------------------------------------------------------------------------- |-- Module : Data.Binary.BitPut-- Copyright : Dominic Steinitz-- License : BSD3-style (see LICENSE)---- Maintainer : Dominic Steinitz <dominic.steinitz@blueyonder.co.uk>-- Stability : experimental---- This is the writer dual to BitGet. It allows one to append bits in a monad-- and get a strict ByteString as a result. Bits are appended from the MSB of-- the first byte towards the LSB of the last byte.---- This is best suited to small bit-fields because it accumulates bytes using-- snoc, so large results will cause a lot of copying. It would be possible-- to switch to using something similar to the Builder monad if need arises.-- However, since most protocols only have small bit fields, this should-- suffice for many cases.-----------------------------------------------------------------------------moduleData.Binary.BitPut(BitPut,runBitPut,putBit,putNBits,putBits,putByteString,putLeftByteString)whereimportData.Bits(bitSize,Bits)importControl.MonadimportqualifiedData.ByteStringasBimportqualifiedData.ByteString.LazyasBLimportqualifiedData.Binary.BitBuilderasBBnewtypeBitPut'a=BitPut'{unPut::(a,BB.BitBuilder)}typeBitPut=BitPut'()instanceFunctorBitPut'wherefmapfm=BitPut'(let(a,w)=unPutmin(fa,w))instanceMonadBitPut'wherereturna=BitPut'(a,BB.empty)m>>=k=BitPut'(let(a,w)=unPutm(b,w')=unPut(ka)in(b,w`BB.append`w'))m>>k=BitPut'(let(_,w)=unPutm(b,w')=unPutkin(b,w`BB.append`w')){-# INLINE (>>) #-}-- | Append a single bitputBit::Bool->BitPutputBitbit=BitPut'((),BB.singletonbit)-- | Append the bottom n bits of the given bits value. In the case that more-- bits are requested than the value provides, this acts as if the value-- has as unlimited number of leading 0 bits.putNBits::(Integrala,Bitsa)=>Int->a->BitPutputNBitsnv=BitPut'((),BB.fromBitsnv)-- | Append a value. Note that this function is undefined for instances of Bits-- which have no fixed bitsize (like Integer)putBits::(Integrala,Bitsa)=>a->BitPutputBitsv=putNBits(bitSizev)v-- | Append a ByteStringputByteString::B.ByteString->BitPutputByteStringbs=BitPut'((),BB.fromByteString(bs,0))-- | Append a left aligned ByteString where ByteString has a partial byte-- with the given number of valid bits, from the MSB downwards. The number-- of such bits must be 0..7. (A normal ByteString, which all bytes full-- would use 0)putLeftByteString::(B.ByteString,Int)->BitPutputLeftByteStringbs=BitPut'((),BB.fromByteStringbs)runBitPut::BitPut->BL.ByteStringrunBitPutm=let(_,w)=unPutminBB.toLazyByteStringw