author | wenzelm |
Tue, 26 Mar 2024 21:44:18 +0100 | |
changeset 80018 | ac4412562c7b |
parent 77847 | 3bb6468d202e |
child 80565 | 2acdaa0a7d29 |
permissions | -rw-r--r-- |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/General/bytes.ML |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
2 |
Author: Makarius |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
3 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
4 |
Scalable byte strings, with incremental construction (add content to the |
75572 | 5 |
end). |
6 |
||
7 |
Note: type string is implicitly limited by String.maxSize (approx. 64 MB on |
|
8 |
64_32 architecture). |
|
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
9 |
*) |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
10 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
11 |
signature BYTES = |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
12 |
sig |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
13 |
val chunk_size: int |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
14 |
type T |
75603 | 15 |
val eq: T * T -> bool |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
16 |
val length: T -> int |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
17 |
val contents: T -> string list |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
18 |
val contents_blob: T -> XML.body |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
19 |
val content: T -> string |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
20 |
val is_empty: T -> bool |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
21 |
val empty: T |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
22 |
val build: (T -> T) -> T |
75568
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
23 |
val add_substring: substring -> T -> T |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
24 |
val add: string -> T -> T |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
25 |
val beginning: int -> T -> string |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
26 |
val exists_string: (string -> bool) -> T -> bool |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
27 |
val forall_string: (string -> bool) -> T -> bool |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
28 |
val last_string: T -> string option |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
29 |
val trim_line: T -> T |
75574 | 30 |
val append: T -> T -> T |
75603 | 31 |
val appends: T list -> T |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
32 |
val string: string -> T |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
33 |
val newline: T |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
34 |
val buffer: Buffer.T -> T |
75594 | 35 |
val space_explode: string -> T -> string list |
36 |
val split_lines: T -> string list |
|
75596 | 37 |
val trim_split_lines: T -> string list |
75594 | 38 |
val cat_lines: string list -> T |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
39 |
val read_block: int -> BinIO.instream -> string |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
40 |
val read_stream: int -> BinIO.instream -> T |
75570 | 41 |
val write_stream: BinIO.outstream -> T -> unit |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
42 |
val read: Path.T -> T |
75570 | 43 |
val write: Path.T -> T -> unit |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
44 |
end; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
45 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
46 |
structure Bytes: BYTES = |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
47 |
struct |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
48 |
|
75576 | 49 |
(* primitive operations *) |
50 |
||
76277
f0d8f659b19a
less ambitious Bytes.chunk_size, which is presumably more stable with memory management under heavy load;
wenzelm
parents:
75640
diff
changeset
|
51 |
val chunk_size = 65000; |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
52 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
53 |
abstype T = Bytes of |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
54 |
{buffer: string list, chunks: string list, m: int (*buffer size*), n: int (*chunks size*)} |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
55 |
with |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
56 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
57 |
fun length (Bytes {m, n, ...}) = m + n; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
58 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
59 |
val compact = implode o rev; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
60 |
|
75603 | 61 |
fun eq (Bytes {buffer, chunks, m, n}, Bytes {buffer = buffer', chunks = chunks', m = m', n = n'}) = |
62 |
m = m' andalso n = n' andalso chunks = chunks' andalso |
|
63 |
(buffer = buffer' orelse compact buffer = compact buffer); |
|
64 |
||
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
65 |
fun contents (Bytes {buffer, chunks, ...}) = |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
66 |
rev (chunks |> not (null buffer) ? cons (compact buffer)); |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
67 |
|
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
68 |
val contents_blob = contents #> XML.blob; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
69 |
|
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
70 |
val content = implode o contents; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
71 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
72 |
fun is_empty bytes = length bytes = 0; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
73 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
74 |
val empty = Bytes {buffer = [], chunks = [], m = 0, n = 0}; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
75 |
|
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
76 |
fun build (f: T -> T) = f empty; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
77 |
|
75568
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
78 |
fun add_substring s (bytes as Bytes {buffer, chunks, m, n}) = |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
79 |
if Substring.isEmpty s then bytes |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
80 |
else |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
81 |
let val l = Substring.size s in |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
82 |
if l + m < chunk_size |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
83 |
then Bytes {buffer = Substring.string s :: buffer, chunks = chunks, m = l + m, n = n} |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
84 |
else |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
85 |
let |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
86 |
val k = chunk_size - m; |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
87 |
val chunk = compact (Substring.string (Substring.slice (s, 0, SOME k)) :: buffer); |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
88 |
val s' = Substring.slice (s, k, SOME (l - k)); |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
89 |
val bytes' = Bytes {buffer = [], chunks = chunk :: chunks, m = 0, n = chunk_size + n}; |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
90 |
in add_substring s' bytes' end |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
91 |
end; |
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
92 |
|
a8539b1c8775
clarified signature: avoid repeated string copying via Substring.slice;
wenzelm
parents:
75567
diff
changeset
|
93 |
val add = add_substring o Substring.full; |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
94 |
|
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
95 |
fun exists_string pred (Bytes {buffer, chunks, ...}) = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
96 |
let val ex = (exists o Library.exists_string) pred |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
97 |
in ex buffer orelse ex chunks end; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
98 |
|
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
99 |
fun forall_string pred = not o exists_string (not o pred); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
100 |
|
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
101 |
fun last_string (Bytes {buffer, chunks, ...}) = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
102 |
(case buffer of |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
103 |
s :: _ => Library.last_string s |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
104 |
| [] => |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
105 |
(case chunks of |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
106 |
s :: _ => Library.last_string s |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
107 |
| [] => NONE)); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
108 |
|
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
109 |
fun trim_line (bytes as Bytes {buffer, chunks, ...}) = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
110 |
let |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
111 |
val is_line = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
112 |
(case last_string bytes of |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
113 |
SOME s => Symbol.is_ascii_line_terminator s |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
114 |
| NONE => false); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
115 |
in |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
116 |
if is_line then |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
117 |
let |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
118 |
val (last_chunk, chunks') = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
119 |
(case chunks of |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
120 |
[] => ("", []) |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
121 |
| c :: cs => (c, cs)); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
122 |
val trimed = Library.trim_line (last_chunk ^ compact buffer); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
123 |
in build (fold_rev add chunks' #> add trimed) end |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
124 |
else bytes |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
125 |
end; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
126 |
|
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
127 |
end; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
128 |
|
75576 | 129 |
|
130 |
(* derived operations *) |
|
131 |
||
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
132 |
fun beginning n bytes = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
133 |
let |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
134 |
val dots = " ..."; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
135 |
val m = (String.maxSize - size dots) div chunk_size; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
136 |
val a = implode (take m (contents bytes)); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
137 |
val b = String.substring (a, 0, Int.min (n, size a)); |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
138 |
in if size b < length bytes then b ^ dots else b end; |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
139 |
|
75574 | 140 |
fun append bytes1 bytes2 = (*left-associative*) |
141 |
if is_empty bytes1 then bytes2 |
|
142 |
else if is_empty bytes2 then bytes1 |
|
143 |
else bytes1 |> fold add (contents bytes2); |
|
144 |
||
75603 | 145 |
val appends = build o fold (fn b => fn a => append a b); |
146 |
||
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
147 |
val string = build o add; |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
148 |
|
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
149 |
val newline = string "\n"; |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
150 |
|
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
151 |
val buffer = build o fold add o Buffer.contents; |
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
152 |
|
75592 | 153 |
|
75594 | 154 |
(* space_explode *) |
155 |
||
156 |
fun space_explode sep bytes = |
|
157 |
if is_empty bytes then [] |
|
158 |
else if size sep <> 1 then [content bytes] |
|
159 |
else |
|
160 |
let |
|
77847
3bb6468d202e
more operations, following Isabelle/ML conventions;
wenzelm
parents:
76277
diff
changeset
|
161 |
val sep_char = String.nth sep 0; |
75594 | 162 |
|
163 |
fun add_part s part = |
|
164 |
Buffer.add (Substring.string s) (the_default Buffer.empty part); |
|
165 |
||
166 |
fun explode head tail part res = |
|
167 |
if Substring.isEmpty head then |
|
168 |
(case tail of |
|
169 |
[] => |
|
170 |
(case part of |
|
171 |
NONE => rev res |
|
172 |
| SOME buf => rev (Buffer.content buf :: res)) |
|
173 |
| chunk :: chunks => explode (Substring.full chunk) chunks part res) |
|
174 |
else |
|
175 |
(case Substring.fields (fn c => c = sep_char) head of |
|
176 |
[a] => explode Substring.empty tail (SOME (add_part a part)) res |
|
177 |
| a :: rest => |
|
178 |
let |
|
179 |
val (bs, c) = split_last rest; |
|
180 |
val res' = res |
|
181 |
|> cons (Buffer.content (add_part a part)) |
|
182 |
|> fold (cons o Substring.string) bs; |
|
183 |
val part' = SOME (add_part c NONE); |
|
184 |
in explode Substring.empty tail part' res' end) |
|
185 |
in explode Substring.empty (contents bytes) NONE [] end; |
|
186 |
||
187 |
val split_lines = space_explode "\n"; |
|
188 |
||
75596 | 189 |
val trim_split_lines = trim_line #> split_lines #> map Library.trim_line; |
190 |
||
75594 | 191 |
fun cat_lines lines = build (fold add (separate "\n" lines)); |
192 |
||
193 |
||
75592 | 194 |
(* IO *) |
195 |
||
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
196 |
fun read_block limit = |
75615 | 197 |
File_Stream.input_size (if limit < 0 then chunk_size else Int.min (chunk_size, limit)); |
75573 | 198 |
|
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
199 |
fun read_stream limit stream = |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
200 |
let |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
201 |
fun read bytes = |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
202 |
(case read_block (limit - length bytes) stream of |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
203 |
"" => bytes |
75577
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
204 |
| s => read (add s bytes)) |
c51e1cef1eae
more scalable byte messages, notably for Scala functions in ML;
wenzelm
parents:
75576
diff
changeset
|
205 |
in read empty end; |
75570 | 206 |
|
75602 | 207 |
fun write_stream stream bytes = |
75615 | 208 |
File_Stream.outputs stream (contents bytes); |
75570 | 209 |
|
75615 | 210 |
fun read path = File_Stream.open_input (fn stream => read_stream ~1 stream) path; |
75602 | 211 |
|
75615 | 212 |
fun write path bytes = File_Stream.open_output (fn stream => write_stream stream bytes) path; |
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
213 |
|
75576 | 214 |
|
215 |
(* ML pretty printing *) |
|
216 |
||
75575 | 217 |
val _ = |
218 |
ML_system_pp (fn _ => fn _ => fn bytes => |
|
219 |
PolyML.PrettyString ("Bytes {length = " ^ string_of_int (length bytes) ^ "}")) |
|
220 |
||
75567
94321fd25c8a
support for scalable byte strings, with incremental construction;
wenzelm
parents:
diff
changeset
|
221 |
end; |