Skip to content

Commit

Permalink
Add Error module.
Browse files Browse the repository at this point in the history
Also add the importCFString/importCFStringAs functions.
  • Loading branch information
judah committed Aug 21, 2011
1 parent e09fa8f commit d0e186b
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions CoreFoundation/CoreFoundation.cabal
Expand Up @@ -41,6 +41,7 @@ Library
System.CoreFoundation.Base
System.CoreFoundation.Array
System.CoreFoundation.Data
System.CoreFoundation.Error
System.CoreFoundation.Dictionary
System.CoreFoundation.Number
System.CoreFoundation.RunLoop
Expand Down
2 changes: 2 additions & 0 deletions CoreFoundation/System/CoreFoundation.hs
Expand Up @@ -2,6 +2,7 @@ module System.CoreFoundation(
module System.CoreFoundation.Base,
module System.CoreFoundation.Array,
module System.CoreFoundation.Data,
module System.CoreFoundation.Error,
module System.CoreFoundation.Dictionary,
module System.CoreFoundation.Number,
module System.CoreFoundation.RunLoop,
Expand All @@ -12,6 +13,7 @@ module System.CoreFoundation(
import System.CoreFoundation.Base
import System.CoreFoundation.Array
import System.CoreFoundation.Data
import System.CoreFoundation.Error
import System.CoreFoundation.Dictionary
import System.CoreFoundation.Number
import System.CoreFoundation.RunLoop
Expand Down
82 changes: 82 additions & 0 deletions CoreFoundation/System/CoreFoundation/Error.chs
@@ -0,0 +1,82 @@
-- | Interface to CoreFoundation's @CFError@ C type.
-- It is toll-free bridged with the @NSData@ type.
module System.CoreFoundation.Error (
-- * The Error type
Error,
ErrorRef,
newError,
-- * Error properties
errorDescription,
errorFailureReason,
errorRecoverySuggestion,
userInfo,
errorDomain,
errorCode,
-- * Error domains
domainPOSIX,
domainOSStatus,
domainMach,
domainCocoa,
-- * User info keys
localizedDescriptionKey,
localizedFailureReasonKey,
localizedRecoverySuggestionKey,
descriptionKey,
underlyingErrorKey,
) where

import Foreign
import Foreign.C

import Prelude hiding (String)

import System.CoreFoundation.Base
import System.CoreFoundation.Dictionary
import System.CoreFoundation.String as CF
import System.CoreFoundation.Internal.TH

#include <CoreFoundation/CoreFoundation.h>

declareCFType "Error"

importCFStringAs "kCFErrorLocalizedDescriptionKey" "localizedDescriptionKey"
importCFStringAs "kCFErrorLocalizedFailureReasonKey" "localizedFailureReasonKey"
importCFStringAs "kCFErrorLocalizedRecoverySuggestionKey" "localizedRecoverySuggestionKey"
importCFStringAs "kCFErrorDescriptionKey" "descriptionKey"
importCFStringAs "kCFErrorUnderlyingErrorKey" "underlyingErrorKey"

importCFStringAs "kCFErrorDomainPOSIX" "domainPOSIX"
importCFStringAs "kCFErrorDomainOSStatus" "domainOSStatus"
importCFStringAs "kCFErrorDomainMach" "domainMach"
importCFStringAs "kCFErrorDomainCocoa" "domainCocoa"

{#fun CFErrorCreate as newError
{ withDefaultAllocator- `AllocatorPtr'
, withObject* `String'
, `Int'
, maybeWithObject* `Maybe Dictionary'
} -> `Error' getOwned* #}

maybeWithObject Nothing = ($ nullPtr)
maybeWithObject (Just o) = withObject o

{#fun pure CFErrorCopyDescription as errorDescription
{ withObject* `Error' } -> `String' getAndRetain* #}
-- The docs say that the CFErrorCopyDescription will never return NULL.

{#fun pure CFErrorCopyFailureReason as errorFailureReason
{ withObject* `Error' } -> `Maybe String' maybeGetAndRetain* #}

{#fun pure CFErrorCopyRecoverySuggestion as errorRecoverySuggestion
{ withObject* `Error' } -> `Maybe String' maybeGetAndRetain* #}

{#fun pure CFErrorCopyUserInfo as userInfo
{ withObject* `Error' } -> `Maybe Dictionary' maybeGetAndRetain* #}

{#fun pure CFErrorGetDomain as errorDomain
{ withObject* `Error' } -> `String' getAndRetain* #}

{#fun pure CFErrorGetCode as errorCode
{ withObject* `Error' } -> `CFIndex' id #}


21 changes: 21 additions & 0 deletions CoreFoundation/System/CoreFoundation/String.chs
Expand Up @@ -12,6 +12,9 @@ module System.CoreFoundation.String(
-- * Conversion to/from 'Text'
newStringFromText,
getText,
-- * Foreign import of string constants
importCFString,
importCFStringAs,
) where

-- TODO:
Expand All @@ -38,6 +41,7 @@ import qualified Prelude
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Encoding
import Data.Text.Foreign (useAsPtr, fromPtr)
import Language.Haskell.TH

#include <CoreFoundation/CoreFoundation.h>

Expand Down Expand Up @@ -102,3 +106,20 @@ getText s = do
-- | Extract a 'Prelude.String' copy of the given @CoreFoundation.String@.
getChars :: String -> IO Prelude.String
getChars = fmap Text.unpack . getText


importCFStringAs :: Prelude.String -> Prelude.String -> Q [Dec]
importCFStringAs foreignStr nameStr = do
ptrName <- newName (nameStr ++ "Ptr")
let name = mkName nameStr
ptrType <- [t| Ptr CFTypeRef |]
expr <- [| unsafePerformIO $ peek $(varE ptrName) >>= getAndRetain |]
return
[ ForeignD $ ImportF CCall Safe ("&" ++ foreignStr) ptrName ptrType
, SigD name (ConT ''String)
, FunD name [Clause [] (NormalB expr) []]
]


importCFString :: Prelude.String -> Q [Dec]
importCFString s = importCFStringAs s s

0 comments on commit d0e186b

Please sign in to comment.