24 module Isabelle.Bytes ( |
24 module Isabelle.Bytes ( |
25 Bytes, |
25 Bytes, |
26 make, unmake, pack, unpack, |
26 make, unmake, pack, unpack, |
27 empty, null, length, index, all, any, |
27 empty, null, length, index, all, any, |
28 head, last, take, drop, isPrefixOf, isSuffixOf, |
28 head, last, take, drop, isPrefixOf, isSuffixOf, |
29 concat, space, spaces, char, byte, max_byte, max_char, singleton |
29 concat, space, spaces, char, all_char, any_char, byte, max_byte, max_char, singleton |
30 ) |
30 ) |
31 where |
31 where |
32 |
32 |
33 import Prelude hiding (null, length, all, any, head, last, take, drop, concat) |
33 import Prelude hiding (null, length, all, any, head, last, take, drop, concat) |
34 |
34 |
109 if n < 64 then small_spaces ! n |
109 if n < 64 then small_spaces ! n |
110 else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64)) |
110 else concat ((small_spaces ! (n `mod` 64)) : replicate (n `div` 64) (small_spaces ! 64)) |
111 |
111 |
112 char :: Word8 -> Char |
112 char :: Word8 -> Char |
113 char = toEnum . fromEnum |
113 char = toEnum . fromEnum |
|
114 |
|
115 all_char :: (Char -> Bool) -> Bytes -> Bool |
|
116 all_char pred = all (pred . char) |
|
117 |
|
118 any_char :: (Char -> Bool) -> Bytes -> Bool |
|
119 any_char pred = any (pred . char) |
114 |
120 |
115 byte :: Char -> Word8 |
121 byte :: Char -> Word8 |
116 byte = toEnum . fromEnum |
122 byte = toEnum . fromEnum |
117 |
123 |
118 max_byte :: Word8 |
124 max_byte :: Word8 |
347 |
353 |
348 instance StringLike Bytes where |
354 instance StringLike Bytes where |
349 space_explode :: Char -> Bytes -> [Bytes] |
355 space_explode :: Char -> Bytes -> [Bytes] |
350 space_explode c str = |
356 space_explode c str = |
351 if Bytes.null str then [] |
357 if Bytes.null str then [] |
352 else if c > Bytes.max_char || Bytes.all (/= (Bytes.byte c)) str then [str] |
358 else if Bytes.all_char (/= c) str then [str] |
353 else |
359 else |
354 explode (Bytes.unpack str) |
360 explode (Bytes.unpack str) |
355 where |
361 where |
356 explode rest = |
362 explode rest = |
357 case span (/= (Bytes.byte c)) rest of |
363 case span (/= (Bytes.byte c)) rest of |
2426 import Prelude hiding (read) |
2432 import Prelude hiding (read) |
2427 import Data.Maybe |
2433 import Data.Maybe |
2428 import qualified Data.ByteString as ByteString |
2434 import qualified Data.ByteString as ByteString |
2429 import qualified Isabelle.Bytes as Bytes |
2435 import qualified Isabelle.Bytes as Bytes |
2430 import Isabelle.Bytes (Bytes) |
2436 import Isabelle.Bytes (Bytes) |
|
2437 import qualified Isabelle.Symbol as Symbol |
2431 import qualified Isabelle.UTF8 as UTF8 |
2438 import qualified Isabelle.UTF8 as UTF8 |
2432 import qualified Isabelle.XML as XML |
2439 import qualified Isabelle.XML as XML |
2433 import qualified Isabelle.YXML as YXML |
2440 import qualified Isabelle.YXML as YXML |
2434 |
2441 |
2435 import Network.Socket (Socket) |
2442 import Network.Socket (Socket) |
2522 |
2529 |
2523 -- hybrid messages: line or length+block (with content restriction) |
2530 -- hybrid messages: line or length+block (with content restriction) |
2524 |
2531 |
2525 is_length :: Bytes -> Bool |
2532 is_length :: Bytes -> Bool |
2526 is_length msg = |
2533 is_length msg = |
2527 not (Bytes.null msg) && Bytes.all (\b -> 48 <= b && b <= 57) msg |
2534 not (Bytes.null msg) && Bytes.all_char (\c -> '0' <= c && c <= '9') msg |
2528 |
2535 |
2529 is_terminated :: Bytes -> Bool |
2536 is_terminated :: Bytes -> Bool |
2530 is_terminated msg = |
2537 is_terminated msg = |
2531 not (Bytes.null msg) && (Bytes.last msg == 13 || Bytes.last msg == 10) |
2538 not (Bytes.null msg) && Symbol.is_ascii_line_terminator (Bytes.char $ Bytes.last msg) |
2532 |
2539 |
2533 make_line_message :: Bytes -> [Bytes] |
2540 make_line_message :: Bytes -> [Bytes] |
2534 make_line_message msg = |
2541 make_line_message msg = |
2535 let n = Bytes.length msg in |
2542 let n = Bytes.length msg in |
2536 if is_length msg || is_terminated msg then |
2543 if is_length msg || is_terminated msg then |
2537 error ("Bad content for line message:\n" <> take 100 (UTF8.decode msg)) |
2544 error ("Bad content for line message:\n" <> take 100 (UTF8.decode msg)) |
2538 else |
2545 else |
2539 (if n > 100 || Bytes.any (== 10) msg then make_header [n + 1] else []) <> [msg, "\n"] |
2546 (if n > 100 || Bytes.any_char (== '\n') msg then make_header [n + 1] else []) <> [msg, "\n"] |
2540 |
2547 |
2541 write_line_message :: Socket -> Bytes -> IO () |
2548 write_line_message :: Socket -> Bytes -> IO () |
2542 write_line_message socket = write socket . make_line_message |
2549 write_line_message socket = write socket . make_line_message |
2543 |
2550 |
2544 read_line_message :: Socket -> IO (Maybe Bytes) |
2551 read_line_message :: Socket -> IO (Maybe Bytes) |