src/Tools/Haskell/Haskell.thy
changeset 69476 d93fe3557a98
parent 69474 2633cf136335
child 69477 1690ba936016
equal deleted inserted replaced
69475:b3628ee55f28 69476:d93fe3557a98
  1469 -}
  1469 -}
  1470 
  1470 
  1471 module Isabelle.Byte_Message (
  1471 module Isabelle.Byte_Message (
  1472     write, write_line,
  1472     write, write_line,
  1473     read, read_block, trim_line, read_line,
  1473     read, read_block, trim_line, read_line,
  1474     write_message, read_message,
  1474     make_message, write_message, read_message,
  1475     write_line_message, read_line_message
  1475     make_line_message, write_line_message, read_line_message
  1476   )
  1476   )
  1477 where
  1477 where
  1478 
  1478 
  1479 import Prelude hiding (read)
  1479 import Prelude hiding (read)
  1480 import Data.Maybe
  1480 import Data.Maybe
  1552 
  1552 
  1553 make_header :: [Int] -> [ByteString]
  1553 make_header :: [Int] -> [ByteString]
  1554 make_header ns =
  1554 make_header ns =
  1555   [UTF8.fromString (space_implode "," (map Value.print_int ns)), newline]
  1555   [UTF8.fromString (space_implode "," (map Value.print_int ns)), newline]
  1556 
  1556 
       
  1557 make_message :: [ByteString] -> [ByteString]
       
  1558 make_message chunks = make_header (map ByteString.length chunks) ++ chunks
       
  1559 
  1557 write_message :: Socket -> [ByteString] -> IO ()
  1560 write_message :: Socket -> [ByteString] -> IO ()
  1558 write_message socket chunks =
  1561 write_message socket = write socket . make_message
  1559   write socket (make_header (map ByteString.length chunks) ++ chunks)
       
  1560 
  1562 
  1561 parse_header :: ByteString -> [Int]
  1563 parse_header :: ByteString -> [Int]
  1562 parse_header line =
  1564 parse_header line =
  1563   let
  1565   let
  1564     res = map Value.parse_nat (space_explode ',' (UTF8.toString line))
  1566     res = map Value.parse_nat (space_explode ',' (UTF8.toString line))
  1592 
  1594 
  1593 is_terminated :: ByteString -> Bool
  1595 is_terminated :: ByteString -> Bool
  1594 is_terminated msg =
  1596 is_terminated msg =
  1595   not (ByteString.null msg) && (ByteString.last msg == 13 || ByteString.last msg == 10)
  1597   not (ByteString.null msg) && (ByteString.last msg == 13 || ByteString.last msg == 10)
  1596 
  1598 
       
  1599 make_line_message :: ByteString -> [ByteString]
       
  1600 make_line_message msg =
       
  1601   let n = ByteString.length msg in
       
  1602     if is_length msg || is_terminated msg then
       
  1603       error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg))
       
  1604     else
       
  1605       (if n > 100 || ByteString.any (== 10) msg then make_header [n + 1] else []) ++
       
  1606       [msg, newline]
       
  1607 
  1597 write_line_message :: Socket -> ByteString -> IO ()
  1608 write_line_message :: Socket -> ByteString -> IO ()
  1598 write_line_message socket msg = do
  1609 write_line_message socket = write socket . make_line_message
  1599   when (is_length msg || is_terminated msg) $
       
  1600     error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg))
       
  1601 
       
  1602   let n = ByteString.length msg
       
  1603   write socket $
       
  1604     (if n > 100 || ByteString.any (== 10) msg then make_header [n + 1] else []) ++
       
  1605     [msg, newline]
       
  1606 
  1610 
  1607 read_line_message :: Socket -> IO (Maybe ByteString)
  1611 read_line_message :: Socket -> IO (Maybe ByteString)
  1608 read_line_message socket = do
  1612 read_line_message socket = do
  1609   opt_line <- read_line socket
  1613   opt_line <- read_line socket
  1610   case opt_line of
  1614   case opt_line of