module System.USB.IDDB.UsbDotOrg
( parseDb
, staticDb
, fromFile
, fromWeb
) where
import Control.Monad (liftM)
import Data.Maybe (fromJust)
import Data.String.UTF8 (UTF8, fromRep)
import Network.Download (openURI)
import Parsimony
import Parsimony.Char (char, digit)
import System.IO (FilePath)
import System.USB.IDDB.Base ( IDDB(..)
, VendorID, VendorName
, getDataFileName
)
import System.USB.IDDB.Misc (BSParser, eitherMaybe, restOfLine)
import qualified Codec.Binary.UTF8.String as UTF8 (encode)
import qualified Data.Bimap as BM (fromList)
import qualified Data.ByteString as BS (ByteString, pack, readFile)
import qualified Data.Map as MP (empty)
parseDb :: UTF8 BS.ByteString -> Maybe IDDB
parseDb = eitherMaybe . parse staticDbParser
staticDbParser :: BSParser IDDB
staticDbParser = do vendors <- many vendorParser
return IDDB { dbVendors = BM.fromList vendors
, dbProducts = MP.empty
}
where
vendorParser :: BSParser (VendorID, VendorName)
vendorParser = do vid <- many1 digit
char '|'
name <- restOfLine
return (read vid, BS.pack $ UTF8.encode name)
fromFile :: FilePath -> IO (Maybe IDDB)
fromFile = liftM (parseDb . fromRep) . BS.readFile
fromWeb :: IO (Maybe IDDB)
fromWeb = liftM ( either (const Nothing)
(parseDb . fromRep)
) $ openURI dbURL
staticDbPath :: FilePath
staticDbPath = "usb_dot_org_db.txt"
dbURL :: String
dbURL = "http://www.usb.org/developers/tools/comp_dump"
staticDb :: IO IDDB
staticDb = getDataFileName staticDbPath >>= liftM fromJust . fromFile