format(Stream, Fs, Args) :-
phrase(format_(Fs, Args), Cs),
( 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
% that uses only a single "write" operation for efficiency.
- '$put_bytes'(Stream, Bytes)
+ '$put_bytes'(Stream, Cs)
; maplist(put_char(Stream), Cs)
).
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
- let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
- let bytes = self.integers_to_bytevec(temp_v!(2), stub);
+ let mut iter = self.heap_pstr_iter(self[temp_v!(2)]);
+ 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) {
Ok(_) => {