src/Tools/Haskell/Haskell.thy
changeset 69465 16fa609a62b1
parent 69463 6439c9024dcc
child 69466 796e01aba901
equal deleted inserted replaced
69464:2323dce4a0db 69465:16fa609a62b1
  1405 Universally unique identifiers.
  1405 Universally unique identifiers.
  1406 
  1406 
  1407 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/uuid.scala\<close>.
  1407 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/uuid.scala\<close>.
  1408 -}
  1408 -}
  1409 
  1409 
  1410 module Isabelle.UUID (T, random, random_string, parse)
  1410 module Isabelle.UUID (
       
  1411     T,
       
  1412     parse_string, parse_bytes,
       
  1413     string, bytes,
       
  1414     random, random_string, random_bytes
       
  1415   )
  1411 where
  1416 where
  1412 
  1417 
       
  1418 import Data.ByteString (ByteString)
       
  1419 import qualified Data.ByteString
  1413 import Data.UUID (UUID)
  1420 import Data.UUID (UUID)
  1414 import qualified Data.UUID as UUID
  1421 import qualified Data.UUID as UUID
  1415 import Data.UUID.V4 (nextRandom)
  1422 import Data.UUID.V4 (nextRandom)
  1416 
  1423 
  1417 
  1424 
  1418 type T = UUID
  1425 type T = UUID
  1419 
  1426 
       
  1427 
       
  1428 {- parse -}
       
  1429 
       
  1430 parse_string :: String -> Maybe T
       
  1431 parse_string = UUID.fromString
       
  1432 
       
  1433 parse_bytes :: ByteString -> Maybe T
       
  1434 parse_bytes = UUID.fromASCIIBytes
       
  1435 
       
  1436 
       
  1437 {- print -}
       
  1438 
       
  1439 string :: T -> String
       
  1440 string = UUID.toString
       
  1441 
       
  1442 bytes :: T -> ByteString
       
  1443 bytes = UUID.toASCIIBytes
       
  1444 
       
  1445 
       
  1446 {- random id -}
       
  1447 
  1420 random :: IO T
  1448 random :: IO T
  1421 random = nextRandom
  1449 random = nextRandom
  1422 
  1450 
  1423 random_string :: IO String
  1451 random_string :: IO String
  1424 random_string = UUID.toString <$> random
  1452 random_string = string <$> random
  1425 
  1453 
  1426 parse :: String -> Maybe T
  1454 random_bytes :: IO ByteString
  1427 parse = UUID.fromString
  1455 random_bytes = bytes <$> random
  1428 \<close>
  1456 \<close>
  1429 
  1457 
  1430 generate_file "Isabelle/Byte_Message.hs" = \<open>
  1458 generate_file "Isabelle/Byte_Message.hs" = \<open>
  1431 {-  Title:      Isabelle/Byte_Message.hs
  1459 {-  Title:      Isabelle/Byte_Message.hs
  1432     Author:     Makarius
  1460     Author:     Makarius
  1587     LICENSE:    BSD 3-clause (Isabelle)
  1615     LICENSE:    BSD 3-clause (Isabelle)
  1588 
  1616 
  1589 TCP server on localhost.
  1617 TCP server on localhost.
  1590 -}
  1618 -}
  1591 
  1619 
  1592 module Isabelle.Server (localhost_name, localhost, publish_text, publish_stdout, server) where
  1620 module Isabelle.Server (
  1593 
  1621   localhost_name, localhost, publish_text, publish_stdout,
  1594 import Control.Monad (forever)
  1622   server
       
  1623 )
       
  1624 where
       
  1625 
       
  1626 import Data.ByteString (ByteString)
       
  1627 import Control.Monad (forever, when)
  1595 import qualified Control.Exception as Exception
  1628 import qualified Control.Exception as Exception
  1596 import Network.Socket (Socket)
  1629 import Network.Socket (Socket)
  1597 import qualified Network.Socket as Socket
  1630 import qualified Network.Socket as Socket
  1598 import qualified Control.Concurrent as Concurrent
  1631 import qualified Control.Concurrent as Concurrent
  1599 
  1632 
  1600 import Isabelle.Library
  1633 import Isabelle.Library
  1601 import qualified Isabelle.UUID as UUID
  1634 import qualified Isabelle.UUID as UUID
       
  1635 import qualified Isabelle.Byte_Message as Byte_Message
  1602 
  1636 
  1603 
  1637 
  1604 {- server address -}
  1638 {- server address -}
  1605 
  1639 
  1606 localhost_name :: String
  1640 localhost_name :: String
  1621 
  1655 
  1622 server :: (String -> UUID.T -> IO ()) -> (Socket -> IO ()) -> IO ()
  1656 server :: (String -> UUID.T -> IO ()) -> (Socket -> IO ()) -> IO ()
  1623 server publish handle =
  1657 server publish handle =
  1624   Socket.withSocketsDo $ Exception.bracket open (Socket.close . fst) (uncurry loop)
  1658   Socket.withSocketsDo $ Exception.bracket open (Socket.close . fst) (uncurry loop)
  1625   where
  1659   where
  1626     open :: IO (Socket, UUID.T)
  1660     open :: IO (Socket, ByteString)
  1627     open = do
  1661     open = do
  1628       socket <- Socket.socket Socket.AF_INET Socket.Stream Socket.defaultProtocol
  1662       socket <- Socket.socket Socket.AF_INET Socket.Stream Socket.defaultProtocol
  1629       Socket.bind socket (Socket.SockAddrInet 0 localhost)
  1663       Socket.bind socket (Socket.SockAddrInet 0 localhost)
  1630       Socket.listen socket 50
  1664       Socket.listen socket 50
  1631 
  1665 
  1632       port <- Socket.socketPort socket
  1666       port <- Socket.socketPort socket
  1633       let address = localhost_name ++ ":" ++ show port
  1667       let address = localhost_name ++ ":" ++ show port
  1634       password <- UUID.random
  1668       password <- UUID.random
  1635       publish address password
  1669       publish address password
  1636 
  1670 
  1637       return (socket, password)
  1671       return (socket, UUID.bytes password)
  1638 
  1672 
  1639     loop :: Socket -> UUID.T -> IO ()
  1673     loop :: Socket -> ByteString -> IO ()
  1640     loop socket password = forever $ do
  1674     loop socket password = forever $ do
  1641       (connection, peer) <- Socket.accept socket
  1675       (connection, peer) <- Socket.accept socket
  1642       Concurrent.forkFinally
  1676       Concurrent.forkFinally
  1643         (handle connection)  -- FIXME check password
  1677         (do
       
  1678           line <- Byte_Message.read_line connection
       
  1679           when (line == Just password) $ handle connection)
  1644         (\_ -> Socket.close connection)
  1680         (\_ -> Socket.close connection)
  1645       return ()
  1681       return ()
  1646 \<close>
  1682 \<close>
  1647 
  1683 
  1648 end
  1684 end