1396 import qualified Network.Socket.ByteString as ByteString |
1407 import qualified Network.Socket.ByteString as ByteString |
1397 |
1408 |
1398 import qualified Isabelle.Value as Value |
1409 import qualified Isabelle.Value as Value |
1399 |
1410 |
1400 |
1411 |
|
1412 {- output operations -} |
|
1413 |
|
1414 write :: Socket -> [ByteString] -> IO () |
|
1415 write = ByteString.sendMany |
|
1416 |
|
1417 newline :: ByteString |
|
1418 newline = ByteString.singleton 10 |
|
1419 |
|
1420 |
|
1421 {- input operations -} |
|
1422 |
1401 read :: Socket -> Int -> IO ByteString |
1423 read :: Socket -> Int -> IO ByteString |
1402 read socket n = read_bytes 0 [] |
1424 read socket n = read_body 0 [] |
1403 where |
1425 where |
1404 result :: [ByteString] -> ByteString |
|
1405 result = ByteString.concat . reverse |
1426 result = ByteString.concat . reverse |
1406 |
1427 read_body len ss = |
1407 read_bytes :: Int -> [ByteString] -> IO ByteString |
|
1408 read_bytes len ss = |
|
1409 if len >= n then return (result ss) |
1428 if len >= n then return (result ss) |
1410 else |
1429 else |
1411 (do |
1430 (do |
1412 s <- ByteString.recv socket (min (n - len) 8192) |
1431 s <- ByteString.recv socket (min (n - len) 8192) |
1413 case ByteString.length s of |
1432 case ByteString.length s of |
1414 0 -> return (result ss) |
1433 0 -> return (result ss) |
1415 m -> read_bytes (len + m) (s : ss)) |
1434 m -> read_body (len + m) (s : ss)) |
1416 |
1435 |
1417 read_block :: Socket -> Int -> IO (Maybe ByteString) |
1436 read_block :: Socket -> Int -> IO (Maybe ByteString, Int) |
1418 read_block socket n = do |
1437 read_block socket n = do |
1419 s <- read socket n |
1438 msg <- read socket n |
1420 return (if ByteString.length s == n then Just s else Nothing) |
1439 let len = ByteString.length msg |
|
1440 return (if len == n then Just msg else Nothing, len) |
|
1441 |
|
1442 trim_line :: ByteString -> ByteString |
|
1443 trim_line s = |
|
1444 if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s |
|
1445 else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s |
|
1446 else s |
|
1447 where |
|
1448 n = ByteString.length s |
|
1449 at = ByteString.index s |
1421 |
1450 |
1422 read_line :: Socket -> IO (Maybe ByteString) |
1451 read_line :: Socket -> IO (Maybe ByteString) |
1423 read_line socket = read [] |
1452 read_line socket = read_body [] |
1424 where |
1453 where |
1425 result :: [Word8] -> ByteString |
1454 result = trim_line . ByteString.pack . reverse |
1426 result bs = |
1455 read_body bs = do |
1427 ByteString.pack $ reverse $ |
|
1428 if not (null bs) && head bs == 13 then tail bs else bs |
|
1429 |
|
1430 read :: [Word8] -> IO (Maybe ByteString) |
|
1431 read bs = do |
|
1432 s <- ByteString.recv socket 1 |
1456 s <- ByteString.recv socket 1 |
1433 case ByteString.length s of |
1457 case ByteString.length s of |
1434 0 -> return (if null bs then Nothing else Just (result bs)) |
1458 0 -> return (if null bs then Nothing else Just (result bs)) |
1435 1 -> |
1459 1 -> |
1436 case ByteString.head s of |
1460 case ByteString.head s of |
1437 10 -> return (Just (result bs)) |
1461 10 -> return (Just (result bs)) |
1438 b -> read (b : bs) |
1462 b -> read_body (b : bs) |
1439 |
|
1440 trim_line :: ByteString -> ByteString |
|
1441 trim_line s = |
|
1442 if n >= 2 && at (n - 2) == 13 && at (n - 1) == 10 then ByteString.take (n - 2) s |
|
1443 else if n >= 1 && (at (n - 1) == 13 || at (n - 1) == 10) then ByteString.take (n - 1) s |
|
1444 else s |
|
1445 where |
|
1446 n = ByteString.length s |
|
1447 at = ByteString.index s |
|
1448 |
1463 |
1449 |
1464 |
1450 -- hybrid messages: line or length+block (with content restriction) |
1465 -- hybrid messages: line or length+block (with content restriction) |
1451 |
1466 |
1452 is_length :: ByteString -> Bool |
1467 is_length :: ByteString -> Bool |
1453 is_length s = |
1468 is_length msg = |
1454 not (ByteString.null s) && ByteString.all (\b -> 48 <= b && b <= 57) s |
1469 not (ByteString.null msg) && ByteString.all (\b -> 48 <= b && b <= 57) msg |
1455 |
1470 |
1456 has_line_terminator :: ByteString -> Bool |
1471 is_terminated :: ByteString -> Bool |
1457 has_line_terminator s = |
1472 is_terminated msg = |
1458 not (ByteString.null s) && (ByteString.last s == 13 || ByteString.last s == 10) |
1473 not (ByteString.null msg) && (ByteString.last msg == 13 || ByteString.last msg == 10) |
1459 |
1474 |
1460 write_line_message :: Socket -> ByteString -> IO () |
1475 write_line_message :: Socket -> ByteString -> IO () |
1461 write_line_message socket msg = do |
1476 write_line_message socket msg = do |
1462 when (is_length msg || has_line_terminator msg) $ |
1477 when (is_length msg || is_terminated msg) $ |
1463 error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg)) |
1478 error ("Bad content for line message:\n" ++ take 100 (UTF8.toString msg)) |
1464 |
1479 |
1465 let newline = ByteString.singleton 10 |
|
1466 let n = ByteString.length msg |
1480 let n = ByteString.length msg |
1467 ByteString.sendMany socket |
1481 write socket |
1468 (if n > 100 || ByteString.any (== 10) msg then |
1482 (if n > 100 || ByteString.any (== 10) msg then |
1469 [UTF8.fromString (Value.print_int (n + 1)), newline, msg, newline] |
1483 [UTF8.fromString (Value.print_int (n + 1)), newline, msg, newline] |
1470 else [msg, newline]) |
1484 else [msg, newline]) |
1471 |
1485 |
1472 read_line_message :: Socket -> IO (Maybe ByteString) |
1486 read_line_message :: Socket -> IO (Maybe ByteString) |
1473 read_line_message socket = do |
1487 read_line_message socket = do |
1474 opt_line <- read_line socket |
1488 opt_line <- read_line socket |
1475 case opt_line of |
1489 case opt_line of |
1476 Nothing -> return Nothing |
1490 Nothing -> return Nothing |
1477 Just line -> |
1491 Just line -> |
1478 case Value.parse_int (UTF8.toString line) of |
1492 case Value.parse_nat (UTF8.toString line) of |
1479 Nothing -> return $ Just line |
1493 Nothing -> return $ Just line |
1480 Just n -> fmap trim_line <$> read_block socket n |
1494 Just n -> fmap trim_line . fst <$> read_block socket n |
1481 \<close> |
1495 \<close> |
1482 |
1496 |
1483 end |
1497 end |