packages feed

hs-opentelemetry-propagator-datadog-0.0.1.0: old-src/String.hs

module String where

import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Short as SB
import Data.Word (Word64)


newTraceIdFromHeader :: ByteString -> SB.ShortByteString
newTraceIdFromHeader = SB.toShort . fillLeadingZeros 16 . convertWord64ToBinaryByteString . read . BC.unpack


newSpanIdFromHeader :: ByteString -> SB.ShortByteString
newSpanIdFromHeader = SB.toShort . fillLeadingZeros 8 . convertWord64ToBinaryByteString . read . BC.unpack


newHeaderFromTraceId :: SB.ShortByteString -> ByteString
newHeaderFromTraceId = BC.pack . show . convertBinaryByteStringToWord64 . SB.fromShort


newHeaderFromSpanId :: SB.ShortByteString -> ByteString
newHeaderFromSpanId = BC.pack . show . convertBinaryByteStringToWord64 . SB.fromShort


convertWord64ToBinaryByteString :: Word64 -> ByteString
convertWord64ToBinaryByteString =
  B.pack . toWord8s []
  where
    toWord8s acc 0 = acc
    toWord8s acc n =
      let (p, q) = n `divMod` (2 ^ (8 :: Int))
      in toWord8s (fromIntegral q : acc) p


fillLeadingZeros :: Word -> ByteString -> ByteString
fillLeadingZeros len bs = B.replicate (fromIntegral len - B.length bs) 0 <> bs


convertBinaryByteStringToWord64 :: ByteString -> Word64
convertBinaryByteStringToWord64 = B.foldl (\acc b -> (2 ^ (8 :: Int)) * acc + fromIntegral b) 0 -- GHC.Prim.indexWord8ArrayAsWord64# とか駆使すると早くなりそう