{-# LANGUAGE BangPatterns, OverloadedStrings #-} -- | LDIF serializers module Text.LDIF.Printer ( ldif2str, ver2str, dn2str, record2str ) where import Prelude import Text.LDIF.Types import Text.LDIF.Consts import qualified Data.ByteString.Char8 as BC import Data.List as L import Data.Char import Numeric (showHex) -- | Serialize LDIF in LDIF Format ldif2str :: LDIF -> BC.ByteString ldif2str (LDIF v xs) = BC.unlines $ (ver2str v) ++ (map (record2str) xs) -- | Serialize version to LDIF Format Lines ver2str :: Maybe BC.ByteString -> [BC.ByteString] ver2str Nothing = [] ver2str (Just v) = ["version: " `BC.append` v] -- | Serialize DN to LDIF Format dn2str :: DN -> BC.ByteString dn2str xs = BC.intercalate "," $ map (\((Attribute n),v) -> n `BC.append` "=" `BC.append` (escapeDNVals $ aVal v)) (dnAttrVals xs) where escapeDNVals :: BC.ByteString -> BC.ByteString escapeDNVals vs = BC.concat $ map escapeDNVal (BC.unpack vs) where escapeDNVal x | not $ isPrint x = BC.pack $ '\\':(showHex (ord x) "") | elem x escapedDNChars = BC.pack $ '\\':[x] | otherwise = BC.pack $ [x] -- | Serialize Content Record in LDIF Format record2str :: LDIFRecord -> BC.ByteString record2str (ContentRecord dn xs) = BC.unlines $ [ "dn: " `BC.append` (dn2str dn) ] ++ (attrVals2Ln xs) record2str (ChangeRecord dn (ChangeDelete)) = BC.unlines [ "dn: " `BC.append` (dn2str dn), "changetype: delete" ] record2str (ChangeRecord dn (ChangeAdd xs)) = BC.unlines $ [ "dn: " `BC.append` (dn2str dn), "changetype: add" ] ++ (attrVals2Ln xs) record2str (ChangeRecord dn (ChangeModify xs)) = BC.unlines $ [ "dn: " `BC.append` (dn2str dn), "changetype: modify" ] ++ (mods2Ln xs) record2str (ChangeRecord dn (ChangeModDN)) = BC.unlines $ [ "dn: " `BC.append` (dn2str dn), "changetype: moddn" ] attrVals2Ln :: [AttrValue] -> [BC.ByteString] attrVals2Ln xs = map (attrVal2Ln) xs attrVal2Ln :: AttrValue -> BC.ByteString attrVal2Ln ((Attribute n),v) = BC.concat [ n,": ", aVal v ] mods2Ln :: [Modify] -> [BC.ByteString] mods2Ln xs = L.intercalate ["-"] $ map (mod2Ln) xs where mod2Ln :: Modify -> [BC.ByteString] mod2Ln (ModAdd a zs) = [ attrVal2Ln ((Attribute "add"),Value $ aName a) ] ++ (map (\v -> attrVal2Ln (a,v)) zs) mod2Ln (ModDelete a zs) = [ attrVal2Ln ((Attribute "delete"),Value $ aName a) ] ++ (map (\v -> attrVal2Ln (a,v)) zs) mod2Ln (ModReplace a zs) = [ attrVal2Ln ((Attribute "replace"),Value $ aName a) ] ++ (map (\v -> attrVal2Ln (a,v)) zs)