141 lines
13 KiB
HTML
141 lines
13 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<!-- This manual documents Guile version 3.0.10.
|
||
|
|
||
|
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
|
||
|
Inc.
|
||
|
|
||
|
Copyright (C) 2021 Maxime Devos
|
||
|
|
||
|
Copyright (C) 2024 Tomas Volf
|
||
|
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document
|
||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||
|
any later version published by the Free Software Foundation; with no
|
||
|
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
||
|
copy of the license is included in the section entitled "GNU Free
|
||
|
Documentation License." -->
|
||
|
<title>Low-Level Custom Ports in C (Guile Reference Manual)</title>
|
||
|
|
||
|
<meta name="description" content="Low-Level Custom Ports in C (Guile Reference Manual)">
|
||
|
<meta name="keywords" content="Low-Level Custom Ports in C (Guile Reference Manual)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content=".texi2any-real">
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
||
|
<link href="index.html" rel="start" title="Top">
|
||
|
<link href="Concept-Index.html" rel="index" title="Concept Index">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="Port-Types.html" rel="up" title="Port Types">
|
||
|
<link href="Low_002dLevel-Custom-Ports.html" rel="prev" title="Low-Level Custom Ports">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
||
|
span:hover a.copiable-link {visibility: visible}
|
||
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
||
|
-->
|
||
|
</style>
|
||
|
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<div class="subsubsection-level-extent" id="Low_002dLevel-Custom-Ports-in-C">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="Low_002dLevel-Custom-Ports.html" accesskey="p" rel="prev">Low-Level Custom Ports</a>, Up: <a href="Port-Types.html" accesskey="u" rel="up">Types of Port</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<h4 class="subsubsection" id="Low_002dLevel-Custom-Ports-in-C-1"><span>6.12.10.8 Low-Level Custom Ports in C<a class="copiable-link" href="#Low_002dLevel-Custom-Ports-in-C-1"> ¶</a></span></h4>
|
||
|
|
||
|
<p>The <code class="code">make-custom-port</code> procedure described in the previous section
|
||
|
has similar functionality on the C level, though it is organized a bit
|
||
|
differently.
|
||
|
</p>
|
||
|
<p>In C, the mechanism is that one creates a new <em class="dfn">port type object</em>.
|
||
|
The methods are then associated with the port type object instead of the
|
||
|
port itself. The port type object is an opaque pointer allocated when
|
||
|
defining the port type, which serves as a key into the port API.
|
||
|
</p>
|
||
|
<p>Ports themselves have associated <em class="dfn">stream</em> values. The stream is a
|
||
|
pointer controlled by the user, which is set when the port is created.
|
||
|
Given a port, the <code class="code">SCM_STREAM</code> macro returns its associated stream
|
||
|
value, as a <code class="code">scm_t_bits</code>. Note that your port methods are only
|
||
|
ever called with ports of your type, so port methods can safely cast
|
||
|
this value to the expected type. Contrast this to Scheme, which doesn’t
|
||
|
need access to the stream because the <code class="code">make-custom-port</code> methods
|
||
|
can be closures that share port-specific data directly.
|
||
|
</p>
|
||
|
<p>A port type is created by calling <code class="code">scm_make_port_type</code>.
|
||
|
</p>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-scm_005fmake_005fport_005ftype"><span class="category-def">Function: </span><span><code class="def-type">scm_t_port_type*</code> <strong class="def-name">scm_make_port_type</strong> <code class="def-code-arguments">(char *name, size_t (*read) (SCM port, SCM dst, size_t start, size_t count), size_t (*write) (SCM port, SCM src, size_t start, size_t count))</code><a class="copiable-link" href="#index-scm_005fmake_005fport_005ftype"> ¶</a></span></dt>
|
||
|
<dd><p>Define a new port type. The <var class="var">name</var> parameter is like the
|
||
|
<code class="code">#:id</code> parameter to <code class="code">make-custom-port</code>; and <var class="var">read</var> and
|
||
|
<var class="var">write</var> are like <code class="code">make-custom-port</code>’s <code class="code">#:read</code> and
|
||
|
<code class="code">#:write</code>, except that they should return <code class="code">(size_t)-1</code> if the
|
||
|
read or write operation would block, instead of <code class="code">#f</code>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-scm_005fset_005fport_005fread_005fwait_005ffd"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_read_wait_fd</strong> <code class="def-code-arguments">(scm_t_port_type *type, int (*wait_fd) (SCM port))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fread_005fwait_005ffd"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fwrite_005fwait_005ffd"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_write_wait_fd</strong> <code class="def-code-arguments">(scm_t_port_type *type, int (*wait_fd) (SCM port))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fwrite_005fwait_005ffd"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fprint"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_print</strong> <code class="def-code-arguments">(scm_t_port_type *type, int (*print) (SCM port, SCM dest_port, scm_print_state *pstate))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fprint"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fclose"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_close</strong> <code class="def-code-arguments">(scm_t_port_type *type, void (*close) (SCM port))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fclose"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fneeds_005fclose_005fon_005fgc"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_needs_close_on_gc</strong> <code class="def-code-arguments">(scm_t_port_type *type, int needs_close_p)</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fneeds_005fclose_005fon_005fgc"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fseek"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_seek</strong> <code class="def-code-arguments">(scm_t_port_type *type, scm_t_off (*seek) (SCM port, scm_t_off offset, int whence))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fseek"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005ftruncate"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_truncate</strong> <code class="def-code-arguments">(scm_t_port_type *type, void (*truncate) (SCM port, scm_t_off length))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005ftruncate"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005frandom_005faccess_005fp"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_random_access_p</strong> <code class="def-code-arguments">(scm_t_port_type *type, int (*random_access_p) (SCM port));</code><a class="copiable-link" href="#index-scm_005fset_005fport_005frandom_005faccess_005fp"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005finput_005fwaiting"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_input_waiting</strong> <code class="def-code-arguments">(scm_t_port_type *type, int (*input_waiting) (SCM port));</code><a class="copiable-link" href="#index-scm_005fset_005fport_005finput_005fwaiting"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fset_005fport_005fget_005fnatural_005fbuffer_005fsizes"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">scm_set_port_get_natural_buffer_sizes</strong> <code class="def-code-arguments">(scm_t_port_type *type, void (*get_natural_buffer_sizes) (SCM, size_t *read_buf_size, size_t *write_buf_size))</code><a class="copiable-link" href="#index-scm_005fset_005fport_005fget_005fnatural_005fbuffer_005fsizes"> ¶</a></span></dt>
|
||
|
<dd><p>Port method definitions. See <a class="xref" href="Low_002dLevel-Custom-Ports.html">Low-Level Custom Ports</a>, for more
|
||
|
details on each of these methods.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>Once you have your port type, you can create ports with
|
||
|
<code class="code">scm_c_make_port</code>, or <code class="code">scm_c_make_port_with_encoding</code>.
|
||
|
</p>
|
||
|
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
|
||
|
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-scm_005fc_005fmake_005fport_005fwith_005fencoding"><span class="category-def">Function: </span><span><code class="def-type">SCM</code> <strong class="def-name">scm_c_make_port_with_encoding</strong> <code class="def-code-arguments">(scm_t_port_type *type, unsigned long mode_bits, SCM encoding, SCM conversion_strategy, scm_t_bits stream)</code><a class="copiable-link" href="#index-scm_005fc_005fmake_005fport_005fwith_005fencoding"> ¶</a></span></dt>
|
||
|
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-scm_005fc_005fmake_005fport"><span class="category-def">Function: </span><span><code class="def-type">SCM</code> <strong class="def-name">scm_c_make_port</strong> <code class="def-code-arguments">(scm_t_port_type *type, unsigned long mode_bits, scm_t_bits stream)</code><a class="copiable-link" href="#index-scm_005fc_005fmake_005fport"> ¶</a></span></dt>
|
||
|
<dd><p>Make a port with the given <var class="var">type</var>. The <var class="var">stream</var> indicates the
|
||
|
private data associated with the port, which your port implementation
|
||
|
may later retrieve with <code class="code">SCM_STREAM</code>. The mode bits should include
|
||
|
one or more of the flags <code class="code">SCM_RDNG</code> or <code class="code">SCM_WRTNG</code>, indicating
|
||
|
that the port is an input and/or an output port, respectively. The mode
|
||
|
bits may also include <code class="code">SCM_BUF0</code> or <code class="code">SCM_BUFLINE</code>, indicating
|
||
|
that the port should be unbuffered or line-buffered, respectively. The
|
||
|
default is that the port will be block-buffered. See <a class="xref" href="Buffering.html">Buffering</a>.
|
||
|
</p>
|
||
|
<p>As you would imagine, <var class="var">encoding</var> and <var class="var">conversion_strategy</var>
|
||
|
specify the port’s initial textual encoding and conversion strategy.
|
||
|
Both are symbols. <code class="code">scm_c_make_port</code> is the same as
|
||
|
<code class="code">scm_c_make_port_with_encoding</code>, except it uses the default port
|
||
|
encoding and conversion strategy.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>At this point you may be wondering whether to implement your custom port
|
||
|
type in C or Scheme. The answer is that probably you want to use
|
||
|
Scheme’s <code class="code">make-custom-port</code>. The speed is similar between C and
|
||
|
Scheme, and ports implemented in C have the disadvantage of not being
|
||
|
suspendable. See <a class="xref" href="Non_002dBlocking-I_002fO.html">Non-Blocking I/O</a>.
|
||
|
</p>
|
||
|
|
||
|
</div>
|
||
|
<hr>
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="Low_002dLevel-Custom-Ports.html">Low-Level Custom Ports</a>, Up: <a href="Port-Types.html">Types of Port</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|