1377 |
1377 |
1378 See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.ML\<close> |
1378 See \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.ML\<close> |
1379 and \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.scala\<close>. |
1379 and \<^file>\<open>$ISABELLE_HOME/src/Pure/PIDE/byte_message.scala\<close>. |
1380 -} |
1380 -} |
1381 |
1381 |
1382 module Isabelle.Byte_Message (read_line, read_block, trim_line, read_line_message, write_line_message) |
1382 module Isabelle.Byte_Message |
|
1383 (read, read_block, read_line, trim_line, |
|
1384 read_line_message, write_line_message) |
1383 where |
1385 where |
1384 |
1386 |
|
1387 import Prelude hiding (read) |
1385 import Data.ByteString (ByteString) |
1388 import Data.ByteString (ByteString) |
1386 import qualified Data.ByteString as ByteString |
1389 import qualified Data.ByteString as ByteString |
1387 import qualified Data.ByteString.UTF8 as UTF8 |
1390 import qualified Data.ByteString.UTF8 as UTF8 |
1388 import Data.Word (Word8) |
1391 import Data.Word (Word8) |
1389 |
1392 |
1392 import qualified Network.Socket as Socket |
1395 import qualified Network.Socket as Socket |
1393 import qualified Network.Socket.ByteString as ByteString |
1396 import qualified Network.Socket.ByteString as ByteString |
1394 |
1397 |
1395 import qualified Isabelle.Value as Value |
1398 import qualified Isabelle.Value as Value |
1396 |
1399 |
|
1400 |
|
1401 read :: Socket -> Int -> IO ByteString |
|
1402 read socket n = read_bytes 0 [] |
|
1403 where |
|
1404 result :: [ByteString] -> ByteString |
|
1405 result = ByteString.concat . reverse |
|
1406 |
|
1407 read_bytes :: Int -> [ByteString] -> IO ByteString |
|
1408 read_bytes len ss = |
|
1409 if len >= n then return (result ss) |
|
1410 else |
|
1411 (do |
|
1412 s <- ByteString.recv socket (min (n - len) 8192) |
|
1413 case ByteString.length s of |
|
1414 0 -> return (result ss) |
|
1415 m -> read_bytes (len + m) (s : ss)) |
|
1416 |
|
1417 read_block :: Socket -> Int -> IO (Maybe ByteString) |
|
1418 read_block socket n = do |
|
1419 s <- read socket n |
|
1420 return (if ByteString.length s == n then Just s else Nothing) |
1397 |
1421 |
1398 read_line :: Socket -> IO (Maybe ByteString) |
1422 read_line :: Socket -> IO (Maybe ByteString) |
1399 read_line socket = read [] |
1423 read_line socket = read [] |
1400 where |
1424 where |
1401 result :: [Word8] -> ByteString |
1425 result :: [Word8] -> ByteString |
1411 1 -> |
1435 1 -> |
1412 case ByteString.head s of |
1436 case ByteString.head s of |
1413 10 -> return (Just (result bs)) |
1437 10 -> return (Just (result bs)) |
1414 b -> read (b : bs) |
1438 b -> read (b : bs) |
1415 |
1439 |
1416 read_block :: Socket -> Int -> IO (Maybe ByteString) |
|
1417 read_block socket n = read 0 [] |
|
1418 where |
|
1419 result :: [ByteString] -> Maybe ByteString |
|
1420 result ss = |
|
1421 if ByteString.length s == n then Just s else Nothing |
|
1422 where s = ByteString.concat (reverse ss) |
|
1423 |
|
1424 read :: Int -> [ByteString] -> IO (Maybe ByteString) |
|
1425 read len ss = |
|
1426 if len >= n then return (result ss) |
|
1427 else |
|
1428 (do |
|
1429 s <- ByteString.recv socket (min (n - len) 8192) |
|
1430 case ByteString.length s of |
|
1431 0 -> return (result ss) |
|
1432 m -> read (len + m) (s : ss)) |
|
1433 |
|
1434 trim_line :: ByteString -> ByteString |
1440 trim_line :: ByteString -> ByteString |
1435 trim_line s = |
1441 trim_line s = |
1436 if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s |
1442 if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s |
1437 else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s |
1443 else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s |
1438 else s |
1444 else s |
1439 where |
1445 where |
1440 n = ByteString.length s |
1446 n = ByteString.length s |
1441 at = ByteString.index s |
1447 at = ByteString.index s |
1442 |
|
1443 |
1448 |
1444 |
1449 |
1445 -- hybrid messages: line or length+block (with content restriction) |
1450 -- hybrid messages: line or length+block (with content restriction) |
1446 |
1451 |
1447 is_length :: ByteString -> Bool |
1452 is_length :: ByteString -> Bool |