----------------------------------------------------------------------------- -- | -- Module : ByteFields -- Copyright : (c) Conrad Parker 2006 -- License : BSD-style -- -- Maintainer : conradp@cse.unsw.edu.au -- Stability : experimental -- Portability : portable -- -- Utilities for handling byte-aligned fields -- ----------------------------------------------------------------------------- module Codec.Container.Ogg.ByteFields ( be64At, be32At, be16At, le64At, le32At, le16At, u8At, le64Fill, le32Fill, le16Fill, u8Fill ) where import Data.Int (Int64) import Data.Word import qualified Data.ByteString.Lazy as L beNAt :: Integral a => Int64 -> Int64 -> L.ByteString -> a beNAt len off s = fromTwosComp $ reverse $ L.unpack (L.take len (L.drop off s)) be64At :: Integral a => Int64 -> L.ByteString -> a be64At = beNAt 8 be32At :: Integral a => Int64 -> L.ByteString -> a be32At = beNAt 4 be16At :: Integral a => Int64 -> L.ByteString -> a be16At = beNAt 2 leNAt :: Integral a => Int64 -> Int64 -> L.ByteString -> a leNAt len off s = fromTwosComp $ L.unpack (L.take len (L.drop off s)) le64At :: Integral a => Int64 -> L.ByteString -> a le64At = leNAt 8 le32At :: Integral a => Int64 -> L.ByteString -> a le32At = leNAt 4 le16At :: Integral a => Int64 -> L.ByteString -> a le16At = leNAt 2 u8At :: Integral a => Int64 -> L.ByteString -> a u8At = leNAt 1 -- Generate a ByteString containing the given number leNFill :: Integral a => Int -> a -> L.ByteString leNFill n x | l < n = L.pack $ (i ++ (take (n-l) $ repeat 0x00)) | l > n = error "leNFill too short" | otherwise = L.pack $ i where l = length i i = toTwosComp x le64Fill :: Integral a => a -> L.ByteString le64Fill = leNFill 8 le32Fill :: Integral a => a -> L.ByteString le32Fill = leNFill 4 le16Fill :: Integral a => a -> L.ByteString le16Fill = leNFill 2 u8Fill :: Integral a => a -> L.ByteString u8Fill = leNFill 1 -- | Convert to twos complement, unsigned, little endian toTwosComp :: Integral a => a -> [Word8] toTwosComp x = g $ f x where f y = (fromIntegral y) `divMod` 256 :: (Integer, Integer) g (0,b) = [fromIntegral b] g (a,b) = [fromIntegral b] ++ (g $ f a) -- | Convert from twos complement, unsigned, little endian fromTwosComp :: Integral a => [Word8] -> a fromTwosComp x = foldr (\a b -> fromIntegral a + b*256) 0 x