This commit is contained in:
Mark Thom
2020-06-16 18:47:53 -06:00
3 changed files with 32 additions and 15 deletions

View File

@@ -1,6 +1,7 @@
:- module(charsio, [char_type/2, :- module(charsio, [char_type/2,
chars_utf8bytes/2, chars_utf8bytes/2,
get_single_char/1, get_single_char/1,
read_line_to_chars/3,
read_term_from_chars/2, read_term_from_chars/2,
write_term_to_chars/3]). write_term_to_chars/3]).
@@ -182,3 +183,14 @@ continuation(Code, Chars, Nb) --> [Byte],
% invalid continuation byte % invalid continuation byte
% each remaining continuation byte (if any) will raise 0xFFFD too % each remaining continuation byte (if any) will raise 0xFFFD too
continuation(_, ['\xFFFD\'|T], _) --> [_], decode_utf8(T). continuation(_, ['\xFFFD\'|T], _) --> [_], decode_utf8(T).
read_line_to_chars(Stream, Cs0, Cs) :-
'$get_n_chars'(Stream, 1, Char), % this also works for binary streams
( Char == [] -> Cs0 = Cs
; Char = [C],
Cs0 = [C|Rest],
( C == '\n' -> Rest = Cs
; read_line_to_chars(Stream, Rest, Cs)
)
).

View File

@@ -375,20 +375,9 @@ format(Fs, Args) :-
format(Stream, Fs, Args) :- format(Stream, Fs, Args) :-
phrase(format_(Fs, Args), Cs), phrase(format_(Fs, Args), Cs),
( stream_property(Stream, type(binary)) -> ( stream_property(Stream, type(binary)) ->
% maplist(char_code, Cs, Bytes) is currently a lot slower
% than first converting Cs to an atom, and then to codes.
% In the future, we can ideally avoid creating an atom here,
% since an atom leaves traces in the system.
atom_chars(A, Cs),
atom_codes(A, Bytes),
( member(NonByte, Bytes), NonByte > 255 ->
char_code(Char, NonByte),
throw(error(representation_error(Char), format/3))
; true
),
% For binary streams, we use a specialised internal predicate % For binary streams, we use a specialised internal predicate
% that uses only a single "write" operation for efficiency. % that uses only a single "write" operation for efficiency.
'$put_bytes'(Stream, Bytes) '$put_bytes'(Stream, Cs)
; maplist(put_char(Stream), Cs) ; maplist(put_char(Stream), Cs)
). ).
@@ -471,7 +460,7 @@ portray_clause(Term) :-
portray_clause(Stream, Term) :- portray_clause(Stream, Term) :-
phrase(portray_clause_(Term), Ls), phrase(portray_clause_(Term), Ls),
maplist(put_char(Stream), Ls). format(Stream, "~s", [Ls]).
portray_clause_(Term) --> portray_clause_(Term) -->
{ term_variables(Term, Vs), { term_variables(Term, Vs),

View File

@@ -2022,8 +2022,24 @@ impl MachineState {
let mut stream = let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?; self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2); let mut iter = self.heap_pstr_iter(self[temp_v!(2)]);
let bytes = self.integers_to_bytevec(temp_v!(2), stub); let mut bytes = Vec::new();
for c in iter.to_string().chars() {
if c as u32 > 255 {
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
let err = MachineError::type_error(
self.heap.h(),
ValidType::Byte,
Addr::Char(c),
);
return Err(self.error_form(err, stub));
}
bytes.push(c as u8);
}
match stream.write(&bytes) { match stream.write(&bytes) {
Ok(_) => { Ok(_) => {