putHeader :: ASN1Header -> B.ByteString
putHeader (ASN1Header cl tag pc len) = B.concat
    [ B.singleton word1
    , if tag < 0x1f then B.empty else tagBS
    , lenBS]
  where cli   = shiftL (fromIntegral $ fromEnum cl) 6
        pcval = shiftL (if pc then 0x1 else 0x0) 5
        tag0  = if tag < 0x1f then fromIntegral tag else 0x1f
        word1 = cli .|. pcval .|. tag0
        lenBS = B.pack $ putLength len
        tagBS = putVarEncodingIntegral tag

{- | putLength encode a length into a ASN1 length.
 - see getLength for the encoding rules -}
putHeader :: ASN1Header -> B.ByteString
putHeader (ASN1Header cl tag pc len) = B.concat
    [ B.singleton word1
    , if tag < 0x1f then B.empty else tagBS
    , lenBS]
  where cli   = shiftL (fromIntegral $ fromEnum cl) 6
        pcval = shiftL (if pc then 0x1 else 0x0) 5
        tag0  = if tag < 0x1f then fromIntegral tag else 0x1f
        word1 = cli .|. pcval .|. tag0
        lenBS = B.pack $ putLength len
        tagBS = putVarEncodingIntegral tag

{- | putLength encode a length into a ASN1 length.
 - see getLength for the encoding rules -}
putHeader (ASN1Header cl tag pc len) = B.concat
    [ B.singleton word1
    , if tag < 0x1f then B.empty else tagBS
    , lenBS]
  where cli   = shiftL (fromIntegral $ fromEnum cl) 6
        pcval = shiftL (if pc then 0x1 else 0x0) 5
        tag0  = if tag < 0x1f then fromIntegral tag else 0x1f
        word1 = cli .|. pcval .|. tag0
        lenBS = B.pack $ putLength len
        tagBS = putVarEncodingIntegral tag

{- | putLength encode a length into a ASN1 length.
 - see getLength for the encoding rules -}