structured_io v1.5.0 StructuredIO View Source
A process for performing I/O of structured data, such as markup or binary-encoded data.
Encoding
The process operates in either binary mode or Unicode mode (see
start/2
and start_link/2
). When in binary mode, the result of a read
operation is a binary, regardless of whether the data read is
String.valid?/1
. In Unicode mode, the result of a read operation is an
error/0
if the data read is not properly encoded Unicode data.
Link to this section Summary
Types
A number of bytes or graphemes in a measured data element
An error result
A binary value which marks the beginning of an enclosed data element
The portion of a binary value matched in a read operation
A mode of operation for the process: either binary or Unicode
A function around which read_complex/3
behavior will be
wrapped
A binary value which marks the end of an enclosed or terminated data element
Functions
Returns a specification to start this module under a supervisor
Returns a value that can be passed to Enum.into/2
or Enum.into/3
for
writing data to the specified structured_io
Returns a value that can be passed to functions such as Enum.map/2
for
reading data elements from the specified structured_io
, using the specified
StructuredIO
function
, and the specified left
and/or
right
/operation
Gets the mode of the specified structured_io
Reads data from the specified structured_io
in the specified quantity, or
beginning with the specified binary value. In binary mode, a numeric
count_or_match
denotes a number of bytes; in Unicode mode, a numeric
count_or_match
denotes a number of graphemes
Reads data from the specified structured_io
beginning with the specified
left
and ending with the occurrence of the specified right
that
corresponds to it, inclusive
Reads data from the specified structured_io
beginning with the specified
left
and ending with the first occurrence of the specified right
,
inclusive
Reads data from the specified structured_io
beginning with the specified
left
and ending with the occurrence of the specified right
that
corresponds to it, exclusive
Reads data from the specified structured_io
beginning with the specified
left
and ending with the first occurrence of the specified right
,
exclusive
Invokes the specified operation
, changing the state of the specified
structured_io
only if the operation
is successful. Success is indicated
when the operation
returns {:ok, term}
, in
which case only the term
is returned
Reads data from the specified structured_io
if and until the specified
right
is encountered, including right
Reads data from the specified structured_io
if and until the specified
right
is encountered, excluding right
Starts a StructuredIO
process without links (outside a supervision
tree) with the specified mode
and options
Starts a StructuredIO
process linked to the current process with
the specified mode
and options
Stops the specified structured_io
process
Writes the specified data
to the specified structured_io
Link to this section Types
A number of bytes or graphemes in a measured data element.
An error result.
A binary value which marks the beginning of an enclosed data element.
The portion of a binary value matched in a read operation.
A mode of operation for the process: either binary or Unicode.
operation() :: (GenServer.server() -> {:ok, any()} | any())
A function around which read_complex/3
behavior will be
wrapped.
A binary value which marks the end of an enclosed or terminated data element.
Link to this section Functions
Returns a specification to start this module under a supervisor.
See Supervisor
.
collect(GenServer.server()) :: StructuredIO.Collector.t()
Returns a value that can be passed to Enum.into/2
or Enum.into/3
for
writing data to the specified structured_io
.
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
iex> collector = StructuredIO.collect(structured_io)
iex> ["<elem>foo</elem>",
...> "<elem>bar</elem>",
...> "<elem>baz</elem>"]
iex> |> Enum.into(collector)
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"foo"
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"bar"
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"baz"
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
enumerate_with( GenServer.server(), :read_across | :read_across_ignoring_overlap | :read_between | :read_between_ignoring_overlap, left(), right() ) :: StructuredIO.Enumerator.t()
Returns a value that can be passed to functions such as Enum.map/2
for
reading data elements from the specified structured_io
, using the specified
StructuredIO
function
, and the specified left
and/or
right
/operation
.
Note that enumeration is not a purely functional operation; it consumes data
elements from the underlying StructuredIO
process.
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>foo</elem>"
:ok
iex> StructuredIO.write structured_io,
...> "<elem>bar</elem>"
:ok
iex> StructuredIO.write structured_io,
...> "<elem>baz</elem>"
:ok
iex> structured_io
...> |> StructuredIO.enumerate_with(:read_between,
...> "<elem>",
...> "</elem>")
...> |> StructuredIO.Enumerator.timeout(60_000)
...> |> Enum.map(&String.upcase/1)
["FOO",
"BAR",
"BAZ"]
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "foo<br/>"
:ok
iex> StructuredIO.write structured_io,
...> "bar<br/>"
:ok
iex> StructuredIO.write structured_io,
...> "baz<br/>"
:ok
iex> structured_io
...> |> StructuredIO.enumerate_with(:read_through,
...> "<br/>")
...> |> StructuredIO.Enumerator.timeout(:infinity)
...> |> Enum.map(&String.upcase/1)
["FOO<BR/>",
"BAR<BR/>",
"BAZ<BR/>"]
iex> StructuredIO.read_through structured_io,
...> "<br />"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> read_tag_length_value = fn s ->
...> with tag
...> when not (tag in ["", <<0>>])
...> <- StructuredIO.read(s, 1),
...> <<length::size(8)>>
...> <- StructuredIO.read(s, 1),
...> value
...> when (length == 0) or
...> (value != "")
...> <- StructuredIO.read(s, length) do
...> {:ok,
...> %{tag: tag,
...> length: length,
...> value: value}}
...> end
...> end
iex> StructuredIO.write structured_io,
...> <<111, 0, 222, 3, "foo">>
:ok
iex> structured_io
...> |> StructuredIO.enumerate_with(:read_complex,
...> read_tag_length_value)
...> |> Enum.into([])
[%{tag: <<111>>,
length: 0,
value: ""},
%{tag: <<222>>,
length: 3,
value: "foo"}]
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
""
To override the default per-element timeout of a read*
function, call
StructuredIO.Enumerator.timeout/2
as shown above.
Gets the mode of the specified structured_io
.
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.mode structured_io
:binary
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.mode structured_io
:unicode
Reads data from the specified structured_io
in the specified quantity, or
beginning with the specified binary value. In binary mode, a numeric
count_or_match
denotes a number of bytes; in Unicode mode, a numeric
count_or_match
denotes a number of graphemes.
If the data in the process does not contain at least the expected (quantity of)
data, the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<23, 45>>
:ok
iex> StructuredIO.read structured_io,
...> 3
""
iex> StructuredIO.write structured_io,
...> <<67>>
:ok
iex> StructuredIO.read structured_io,
...> 3
<<23, 45, 67>>
iex> StructuredIO.read structured_io,
...> 3
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "\r\nfo"
:ok
iex> StructuredIO.read structured_io,
...> 4
""
iex> StructuredIO.write structured_io,
...> "o"
:ok
iex> StructuredIO.read structured_io,
...> 4
"\r\nfoo"
iex> StructuredIO.read structured_io,
...> 4
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "fo"
:ok
iex> StructuredIO.read structured_io,
...> "foo"
""
iex> StructuredIO.write structured_io,
...> "obar"
:ok
iex> StructuredIO.read structured_io,
...> "foo"
"foo"
iex> StructuredIO.read structured_io,
...> "foo"
""
iex> StructuredIO.read structured_io,
...> "bar"
"bar"
iex> StructuredIO.read structured_io,
...> "bar"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read structured_io,
...> 4
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.read structured_io,
...> 4
"😕"
iex> StructuredIO.read structured_io,
...> 4
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read structured_io,
...> "😕"
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.read structured_io,
...> "😕"
"😕"
iex> StructuredIO.read structured_io,
...> "😕"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read structured_io,
...> 1
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.read structured_io,
...> 1
"😕"
iex> StructuredIO.read structured_io,
...> 1
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read structured_io,
...> "😕"
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.read structured_io,
...> "😕"
"😕"
iex> StructuredIO.read structured_io,
...> "😕"
""
See mode/1
.
Reads data from the specified structured_io
beginning with the specified
left
and ending with the occurrence of the specified right
that
corresponds to it, inclusive.
If the data in the process does not both begin with left
and contain a
corresponding right
, the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255, 255, 255, 255>>
:ok
iex> StructuredIO.read_across structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255, 0, 0, 0, 7, 8, 9, 255, 255, 255>>
:ok
iex> StructuredIO.read_across structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
<<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255, 255, 255, 255, 255>>
iex> StructuredIO.read_across structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
<<0, 0, 0, 7, 8, 9, 255, 255, 255>>
iex> StructuredIO.read_across structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>foo<elem>bar</elem></elem"
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> "><elem>baz</elem>"
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
"<elem>foo<elem>bar</elem></elem>"
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
"<elem>baz</elem>"
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> "<elem>"
:ok
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "</elem>"
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
"<elem>😕</elem>"
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>"
:ok
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "</elem>"
:ok
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
"<elem>😕</elem>"
iex> StructuredIO.read_across structured_io,
...> "<elem>",
...> "</elem>"
""
Reads data from the specified structured_io
beginning with the specified
left
and ending with the first occurrence of the specified right
,
inclusive.
If the data in the process does not both begin with left
and contain right
,
the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255>>
:ok
iex> StructuredIO.read_across_ignoring_overlap structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255>>
:ok
iex> StructuredIO.read_across_ignoring_overlap structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
<<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255, 255>>
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>foo<elem>bar</elem"
:ok
iex> StructuredIO.read_across_ignoring_overlap structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> ">"
:ok
iex> StructuredIO.read_across_ignoring_overlap structured_io,
...> "<elem>",
...> "</elem>"
"<elem>foo<elem>bar</elem>"
Reads data from the specified structured_io
beginning with the specified
left
and ending with the occurrence of the specified right
that
corresponds to it, exclusive.
If the data in the process does not both begin with left
and contain a
corresponding right
, the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255, 255, 255, 255>>
:ok
iex> StructuredIO.read_between structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255>>
:ok
iex> StructuredIO.read_between structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
<<1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255, 255>>
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>foo<elem>bar</elem></elem"
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> ">"
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"foo<elem>bar</elem>"
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> "<elem>"
:ok
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "</elem>"
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"😕"
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>"
:ok
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "</elem>"
:ok
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
"😕"
iex> StructuredIO.read_between structured_io,
...> "<elem>",
...> "</elem>"
""
Reads data from the specified structured_io
beginning with the specified
left
and ending with the first occurrence of the specified right
,
exclusive.
If the data in the process does not both begin with left
and contain right
,
the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 255, 255>>
:ok
iex> StructuredIO.read_between_ignoring_overlap structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255>>
:ok
iex> StructuredIO.read_between_ignoring_overlap structured_io,
...> <<0, 0, 0>>,
...> <<255, 255, 255>>
<<1, 2, 3, 0, 0, 0, 4, 5, 6>>
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "<elem>foo<elem>bar</elem"
:ok
iex> StructuredIO.read_between_ignoring_overlap structured_io,
...> "<elem>",
...> "</elem>"
""
iex> StructuredIO.write structured_io,
...> ">"
:ok
iex> StructuredIO.read_between_ignoring_overlap structured_io,
...> "<elem>",
...> "</elem>"
"foo<elem>bar"
read_complex(GenServer.server(), operation(), timeout()) :: any()
Invokes the specified operation
, changing the state of the specified
structured_io
only if the operation
is successful. Success is indicated
when the operation
returns {:ok, term}
, in
which case only the term
is returned.
Note: Within the operation
, you must not send messages to the
structured_io
. Send messages instead to the GenServer.server/0
which
is an argument to the operation
.
Examples
In the following example, a Tag-Length-Value data element is composed of:
- A fixed-length Tag expression between
<<1>>
and<<255>>
(one byte) - A fixed-length Length expression between 0 and 255 (one byte)
- A variable-length Value expression whose length is the Length
Following the convention of built-in functions such as read_across/4
, if the
whole element is not present then the result of the operation is an empty
binary (""
).
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> read_tag_length_value = fn s ->
...> with tag
...> when not (tag in ["", <<0>>])
...> <- StructuredIO.read(s, 1),
...> <<length::size(8)>>
...> <- StructuredIO.read(s, 1),
...> value
...> when (length == 0) or
...> (value != "")
...> <- StructuredIO.read(s, length) do
...> {:ok,
...> %{tag: tag,
...> length: length,
...> value: value}}
...> end
...> end
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
""
iex> StructuredIO.write structured_io,
...> <<111>>
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
""
iex> StructuredIO.write structured_io,
...> 0
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
%{tag: <<111>>,
length: 0,
value: ""}
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
""
iex> StructuredIO.write structured_io,
...> <<222>>
iex> StructuredIO.write structured_io,
...> byte_size("foo")
iex> StructuredIO.write structured_io,
...> "foo"
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
%{tag: <<222>>,
length: 3,
value: "foo"}
iex> StructuredIO.read_complex structured_io,
...> read_tag_length_value
""
read_through(GenServer.server(), right(), timeout()) :: match() | error()
Reads data from the specified structured_io
if and until the specified
right
is encountered, including right
.
If right
is not encountered, the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<1, 2, 3, 255, 255>>
:ok
iex> StructuredIO.read_through structured_io,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255, 4, 5, 6, 255, 255, 255>>
:ok
iex> StructuredIO.read_through structured_io,
...> <<255, 255, 255>>
<<1, 2, 3, 255, 255, 255>>
iex> StructuredIO.read_through structured_io,
...> <<255, 255, 255>>
<<4, 5, 6, 255, 255, 255>>
iex> StructuredIO.read_through structured_io,
...> <<255, 255, 255>>
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "foo<br/"
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
""
iex> StructuredIO.write structured_io,
...> ">bar<br/>"
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
"foo<br/>"
iex> StructuredIO.read_through structured_io,
...> "<br/>"
"bar<br/>"
iex> StructuredIO.read_through structured_io,
...> "<br/>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "<br/>"
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
"😕<br/>"
iex> StructuredIO.read_through structured_io,
...> "<br/>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "<br/>"
:ok
iex> StructuredIO.read_through structured_io,
...> "<br/>"
"😕<br/>"
iex> StructuredIO.read_through structured_io,
...> "<br/>"
""
read_to(GenServer.server(), right(), timeout()) :: match() | error()
Reads data from the specified structured_io
if and until the specified
right
is encountered, excluding right
.
If right
is not encountered, the result is an empty binary (""
).
Examples
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> StructuredIO.write structured_io,
...> <<1, 2, 3, 255, 255>>
:ok
iex> StructuredIO.read_to structured_io,
...> <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...> <<255, 4, 5, 6, 255, 255, 255>>
:ok
iex> StructuredIO.read_to structured_io,
...> <<255, 255, 255>>
<<1, 2, 3>>
iex> StructuredIO.read_through structured_io,
...> <<255, 255, 255>>
<<255, 255, 255>>
iex> StructuredIO.read_to structured_io,
...> <<255, 255, 255>>
<<4, 5, 6>>
iex> StructuredIO.read_to structured_io,
...> <<255, 255, 255>>
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...> "foo<br/"
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
""
iex> StructuredIO.write structured_io,
...> ">bar<br/>"
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
"foo"
iex> StructuredIO.read_through structured_io,
...> "<br/>"
"<br/>"
iex> StructuredIO.read_to structured_io,
...> "<br/>"
"bar"
iex> StructuredIO.read_to structured_io,
...> "<br/>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:binary)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
""
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "<br/>"
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
"😕"
iex> StructuredIO.read_to structured_io,
...> "<br/>"
""
iex> {:ok,
...> structured_io} = StructuredIO.start_link(:unicode)
iex> <<fragment1::binary-size(3), fragment2::binary>> = "😕"
iex> StructuredIO.write structured_io,
...> fragment1
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
{:error,
"UnicodeConversionError: incomplete encoding starting at #{inspect fragment1}"}
iex> StructuredIO.write structured_io,
...> fragment2
:ok
iex> StructuredIO.write structured_io,
...> "<br/>"
:ok
iex> StructuredIO.read_to structured_io,
...> "<br/>"
"😕"
iex> StructuredIO.read_to structured_io,
...> "<br/>"
""
start(mode(), GenServer.options()) :: GenServer.on_start()
Starts a StructuredIO
process without links (outside a supervision
tree) with the specified mode
and options
.
Examples
iex> StructuredIO.start :super_pursuit_mode
{:error,
"invalid mode :super_pursuit_mode"}
See start_link/2
.
start_link(mode(), GenServer.options()) :: GenServer.on_start()
Starts a StructuredIO
process linked to the current process with
the specified mode
and options
.
Examples
iex> StructuredIO.start_link :super_pursuit_mode
{:error,
"invalid mode :super_pursuit_mode"}
See mode/1
and the read*
functions for more examples.
stop(GenServer.server(), term(), timeout()) :: :ok
Stops the specified structured_io
process.
write(GenServer.server(), iodata() | IO.chardata() | String.Chars.t()) :: :ok | error()
Writes the specified data
to the specified structured_io
.
No timeout is available because the operation is performed asynchronously.
See the read*
functions for examples.