structured_io v0.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 StructuredIO.start/2 and StructuredIO.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

An error result

A mode of operation for the process: either binary or Unicode

Functions

Gets the mode of the specified structured_io

Reads data from the specified structured_io beginning with the specified from and ending with the specified through, inclusive, using the specified timeout (defaults to 5,000 milliseconds)

Reads data from the specified structured_io beginning with the specified after_data and ending with the specified before_data, exclusive, using the specified timeout (defaults to 5,000 milliseconds)

Reads data from the specified structured_io if and until the specified through is encountered, including through, using the specified timeout (defaults to 5,000 milliseconds)

Reads data from the specified structured_io if and until the specified to is encountered, excluding to, using the specified timeout (defaults to 5,000 milliseconds)

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

Synchronously stops the specified structured_io process with the specified reason (defaults to :normal) and timeout (defaults to infinity)

Asynchronously writes the specified data as a binary to the specified structured_io

Link to this section Types

Link to this type error() View Source
error() :: {:error, atom() | binary()}

An error result.

Link to this type mode() View Source
mode() :: :binary | :unicode

A mode of operation for the process: either binary or Unicode.

See StructuredIO.start/2 and StructuredIO.start_link/2.

Link to this section Functions

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
Link to this function read_across(structured_io, from, through, timeout \\ 5000) View Source
read_across(GenServer.server(), binary(), binary(), timeout()) ::
  binary() |
  error()

Reads data from the specified structured_io beginning with the specified from and ending with the specified through, inclusive, using the specified timeout (defaults to 5,000 milliseconds).

If the data read does not begin with from, the result is an empty binary (""). Likewise, if through is not encountered, 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, 255, 255>>
:ok
iex> StructuredIO.read_across structured_io,
...>                          <<0, 0, 0>>,
...>                          <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...>                    <<255, 0, 0, 0, 4, 5, 6, 255, 255, 255>>
:ok
iex> StructuredIO.read_across structured_io,
...>                          <<0, 0, 0>>,
...>                          <<255, 255, 255>>
<<0, 0, 0, 1, 2, 3, 255, 255, 255>>
iex> StructuredIO.read_across structured_io,
...>                          <<0, 0, 0>>,
...>                          <<255, 255, 255>>
<<0, 0, 0, 4, 5, 6, 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"
:ok
iex> StructuredIO.read_across structured_io,
...>                          "<elem>",
...>                          "</elem>"
""
iex> StructuredIO.write structured_io,
...>                    "><elem>bar</elem>"
:ok
iex> StructuredIO.read_across structured_io,
...>                          "<elem>",
...>                          "</elem>"
"<elem>foo</elem>"
iex> StructuredIO.read_across structured_io,
...>                          "<elem>",
...>                          "</elem>"
"<elem>bar</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>"
""
Link to this function read_between(structured_io, after_data, before_data, timeout \\ 5000) View Source
read_between(GenServer.server(), binary(), binary(), timeout()) ::
  binary() |
  error()

Reads data from the specified structured_io beginning with the specified after_data and ending with the specified before_data, exclusive, using the specified timeout (defaults to 5,000 milliseconds).

If the data read does not begin with after_data, the result is an empty binary (""). Likewise, if before_data is not encountered, 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, 255, 255>>
:ok
iex> StructuredIO.read_between structured_io,
...>                           <<0, 0, 0>>,
...>                           <<255, 255, 255>>
""
iex> StructuredIO.write structured_io,
...>                    <<255, 0, 0, 0, 4, 5, 6, 255, 255, 255>>
:ok
iex> StructuredIO.read_between structured_io,
...>                           <<0, 0, 0>>,
...>                           <<255, 255, 255>>
<<1, 2, 3>>
iex> StructuredIO.read_between structured_io,
...>                           <<0, 0, 0>>,
...>                           <<255, 255, 255>>
<<4, 5, 6>>
iex> StructuredIO.read_between structured_io,
...>                           <<0, 0, 0>>,
...>                           <<255, 255, 255>>
""

iex> {:ok,
...>  structured_io} = StructuredIO.start_link(:unicode)
iex> StructuredIO.write structured_io,
...>                    "<elem>foo</elem"
:ok
iex> StructuredIO.read_between structured_io,
...>                           "<elem>",
...>                           "</elem>"
""
iex> StructuredIO.write structured_io,
...>                    "><elem>bar</elem>"
:ok
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>"
""

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>"
""
Link to this function read_through(structured_io, through, timeout \\ 5000) View Source
read_through(GenServer.server(), binary(), timeout()) ::
  binary() |
  error()

Reads data from the specified structured_io if and until the specified through is encountered, including through, using the specified timeout (defaults to 5,000 milliseconds).

If through 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/>"
""
Link to this function read_to(structured_io, to, timeout \\ 5000) View Source
read_to(GenServer.server(), binary(), timeout()) :: binary() | error()

Reads data from the specified structured_io if and until the specified to is encountered, excluding to, using the specified timeout (defaults to 5,000 milliseconds).

If to 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/>"
""

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 StructuredIO.start_link/2.

Link to this function start_link(mode, options \\ []) View Source
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 StructuredIO.mode/1, StructuredIO.read_across/3, StructuredIO.read_between/3, StructuredIO.read_through/2, and StructuredIO.read_to/2 for more examples.

Link to this function stop(structured_io, reason \\ :normal, timeout \\ :infinity) View Source
stop(GenServer.server(), term(), timeout()) :: :ok

Synchronously stops the specified structured_io process with the specified reason (defaults to :normal) and timeout (defaults to infinity).

Link to this function write(structured_io, data) View Source
write(GenServer.server(), iodata() | IO.chardata() | String.Chars.t()) ::
  :ok |
  error()

Asynchronously writes the specified data as a binary to the specified structured_io.

See StructuredIO.read_across/3, StructuredIO.read_between/3, StructuredIO.read_through/2, and StructuredIO.read_to/2 for examples.