language-asn-0.1.0.0: src/Language/Asn/ObjectIdentifier.hs
{-# language BangPatterns #-}
module Language.Asn.ObjectIdentifier
( fromList
, suffixSingleton
, appendSuffix
, isPrefixOf
, stripPrefix
, encodeString
, encodeByteString
, encodeText
)
where
import Control.Monad.ST (runST)
import Language.Asn.Types
import Data.Maybe (isJust)
import Data.Text (Text)
import Data.ByteString (ByteString)
import Data.Word (Word32)
import Data.Primitive (PrimArray(..))
import qualified Data.Text as Text
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Char8 as BC8
import qualified Data.Vector.Primitive as PV
import qualified Data.List as List
import qualified Data.Primitive as PM
import qualified GHC.Exts as E
fromList :: [Word] -> ObjectIdentifier
fromList = ObjectIdentifier . E.fromList
suffixSingleton :: Word -> ObjectIdentifierSuffix
suffixSingleton = ObjectIdentifierSuffix . singletonPrimArray
appendSuffix :: ObjectIdentifier -> ObjectIdentifierSuffix -> ObjectIdentifier
appendSuffix (ObjectIdentifier a) (ObjectIdentifierSuffix b) = ObjectIdentifier (mappend a b)
isPrefixOf :: ObjectIdentifier -> ObjectIdentifier -> Bool
isPrefixOf a b = isJust (stripPrefix a b)
stripPrefix :: ObjectIdentifier -> ObjectIdentifier -> Maybe ObjectIdentifierSuffix
stripPrefix (ObjectIdentifier a) (ObjectIdentifier b) =
let lenA = PM.sizeofPrimArray a
in if (lenA <= PM.sizeofPrimArray b) && (upgradeArray a == PV.take lenA (upgradeArray b))
then Just (ObjectIdentifierSuffix (unsafeDropPrimArray lenA b))
else Nothing
upgradeArray :: PM.Prim a => PrimArray a -> PV.Vector a
upgradeArray b@(PrimArray a) = PV.Vector 0 (PM.sizeofPrimArray b) (PM.ByteArray a)
singletonPrimArray :: PM.Prim a => a -> PrimArray a
singletonPrimArray a = runST $ do
m <- PM.newPrimArray 1
PM.writePrimArray m 0 a
PM.unsafeFreezePrimArray m
unsafeDropPrimArray :: PM.Prim a => Int -> PrimArray a -> PrimArray a
unsafeDropPrimArray !n !xs = runST $ do
m <- PM.newPrimArray (PM.sizeofPrimArray xs - n)
PM.copyPrimArray m 0 xs n (PM.sizeofPrimArray xs - n)
PM.unsafeFreezePrimArray m
encodeString :: ObjectIdentifier -> String
encodeString = List.intercalate "." . map show . E.toList . getObjectIdentifier
encodeByteString :: ObjectIdentifier -> ByteString
encodeByteString = BC8.pack . encodeString
encodeText :: ObjectIdentifier -> Text
encodeText = Text.pack . encodeString