Skip to content

Commit c4c149e

Browse files
ugly, but does read/write bytes
1 parent 69718b3 commit c4c149e

File tree

2 files changed

+106
-3
lines changed

2 files changed

+106
-3
lines changed

src/lib/charsio.pl

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,85 @@
423423
% Stream = stream('$memory_stream'(2048)).
424424
% ```
425425

426-
chars_to_stream(Chars, Stream, _) :-
427-
must_be(chars, Chars),
426+
chars_to_stream(Chars, Stream, StreamOpts) :-
427+
parse_stream_options(StreamOpts, [Alias, EOFAction, Reposition, Type]),
428428
'$memory_stream'(Stream),
429-
maplist(put_char(Stream), Chars).
429+
'$set_stream_options'(Stream, Alias ,EOFAction, Reposition, Type),
430+
( Type=binary
431+
-> maplist(put_byte(Stream), Chars)
432+
; maplist(put_char(Stream), Chars)
433+
).
434+
435+
%% ugly ripoff of parser from library(builtins).
436+
437+
:- meta_predicate parse_options_list(?, 2, ?, ?, ?).
438+
439+
parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :-
440+
'$skip_max_list'(_, _, Options, Tail),
441+
( Tail == [] ->
442+
true
443+
; var(Tail) ->
444+
throw(error(instantiation_error, Stub)) % 8.11.5.3c)
445+
; Tail \== [] ->
446+
throw(error(type_error(list, Options), Stub)) % 8.11.5.3e)
447+
),
448+
( lists:maplist('$call'(nonvar), Options), % need '$call' because
449+
% maplist isn't
450+
% declared as a
451+
% meta-predicate yet
452+
catch(lists:maplist(Selector, Options, OptionPairs0),
453+
error(E, _),
454+
builtins:throw(error(E, Stub))) ->
455+
lists:append(DefaultPairs, OptionPairs0, OptionPairs1),
456+
keysort(OptionPairs1, OptionPairs),
457+
select_rightmost_options(OptionPairs, OptionValues)
458+
;
459+
throw(error(instantiation_error, Stub)) % 8.11.5.3c)
460+
).
461+
462+
parse_stream_options_(type(Type), type-Type) :-
463+
( var(Type) ->
464+
throw(error(instantiation_error, open/4)) % 8.1.3 7)
465+
;
466+
lists:member(Type, [text, binary]), !
467+
;
468+
throw(error(domain_error(stream_option, type(Type)), _))
469+
).
470+
parse_stream_options_(reposition(Bool), reposition-Bool) :-
471+
( nonvar(Bool), lists:member(Bool, [true, false]), !
472+
;
473+
throw(error(domain_error(stream_option, reposition(Bool)), _))
474+
).
475+
476+
parse_stream_options_(alias(A), alias-A) :-
477+
478+
( var(A) ->
479+
throw(error(instantiation_error, open/4)) % 8.1.3 7)
480+
;
481+
atom(A), A \== [] -> true
482+
;
483+
throw(error(domain_error(stream_option, alias(A)), _))
484+
).
485+
parse_stream_options_(eof_action(Action), eof_action-Action) :-
486+
( nonvar(Action), lists:member(Action, [eof_code, error, reset]), !
487+
;
488+
throw(error(domain_error(stream_option, eof_action(Action)), _))
489+
).
490+
parse_stream_options_(E, _) :-
491+
throw(error(domain_error(stream_option, E), _)). % 8.11.5.3i) %
492+
493+
parse_stream_options(Options, OptionValues) :-
494+
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, type-text],
495+
parse_options_list(Options, parse_stream_options_, DefaultOptions, OptionValues, chars_to_stream/3).
496+
497+
498+
select_rightmost_options([Option-Value | OptionPairs], OptionValues) :-
499+
( pairs:same_key(Option, OptionPairs, OtherValues, _),
500+
OtherValues == [] ->
501+
OptionValues = [Value | OptionValues0],
502+
select_rightmost_options(OptionPairs, OptionValues0)
503+
;
504+
select_rightmost_options(OptionPairs, OptionValues)
505+
).
506+
507+
select_rightmost_options([], []).

src/tests/charsio.pl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
:- module(charsio_tests, []).
2+
:- use_module(library(os)).
3+
:- use_module(library(iso_ext)).
24
:- use_module(library(debug)).
35
:- use_module(library(lists)).
46
:- use_module(library(charsio)).
@@ -56,3 +58,26 @@
5658
get_n_chars(Stream, N, Chars),
5759
Phrase=Chars
5860
)).
61+
62+
63+
test("can read/write bytes",
64+
(
65+
A=97,
66+
B=98,
67+
C=99,
68+
chars_to_stream([A,B,C], Stream, [type(binary)]),
69+
get_byte(Stream, A),
70+
get_byte(Stream, B),
71+
get_byte(Stream, C),
72+
put_byte(Stream, A),
73+
put_byte(Stream, B),
74+
put_byte(Stream, C),
75+
get_byte(Stream, A),
76+
get_byte(Stream, B),
77+
get_byte(Stream, C)
78+
)).
79+
80+
81+
82+
% ?- test_framework:main(charsio_tests).
83+

0 commit comments

Comments
 (0)