module Print ( doPrint ) where import Data.Bits (testBit) import Data.Maybe (isJust, fromJust) import Control.Monad (unless, liftM) import Control.Monad.IO.Class(liftIO, MonadIO) import App (App) import Proto (getFrame, getField, getProp) import IMsg (AMF(..), AMFValue(..), amfUndecoratedName) -- | Print variable doPrint :: MonadIO m => [String] -> App m () doPrint v = do vs <- getFrame let vs' = filter (\a -> amfUndecoratedName a == head v) vs unless (null vs') (doPrintProps (tail v) (head vs')) -- | Print object properties as requested doPrintProps :: MonadIO m => [String] -> AMF -> App m () doPrintProps [] v = callGetter v >>= liftIO . putStrLn . prettyAMF doPrintProps (name:ns) (AMF _ _ _ (AMFObject ptr _ _ _ _)) = do vs <- liftM (filter notTrails) $ getField ptr "" if name == "" then printAll vs else find' vs where notTrails (AMF _ _ _ AMFTrails) = False notTrails _ = True printAll vs = mapM callGetter vs >>= liftIO . mapM_ (putStrLn . prettyAMF) find' vs = let vs' = filter (\a -> amfUndecoratedName a == name) vs in case vs' of [] -> liftIO $ putStrLn "Not found" [v] -> if null ns then callGetter v >>= (liftIO . putStrLn . prettyAMF) else callGetter v >>= doPrintProps ns _ -> liftIO $ putStrLn "Multiple" doPrintProps _ _ = liftIO $ putStrLn "Not found" -- | Check wether AMF value has getter hasGetter :: AMF -> Bool hasGetter amf = amfFlags amf `testBit` 19 -- | Call getter if exists callGetter :: MonadIO m => AMF -> App m AMF callGetter amf = if hasGetter amf then call amf else return amf where call a@(AMF ptr _ _ _) = do res <- getProp ptr (amfUndecoratedName a) if isJust res then return $ fromJust res else return a -- | Show AMF for user prettyAMF :: AMF -> String prettyAMF amf@(AMF _ _ _ v) = amfUndecoratedName amf ++ " = " ++ prettyAMVValue v -- | Show AMF value for user prettyAMVValue :: AMFValue -> String prettyAMVValue (AMFDouble v) = show v prettyAMVValue (AMFBool v) = show v prettyAMVValue (AMFString v) = show v prettyAMVValue (AMFObject _ _ _ _ n) = n prettyAMVValue AMFNull = "null" prettyAMVValue AMFUndefined = "undefined" prettyAMVValue v = show v