autodoc.git/
traditional_manual/
chapter_9.html
Branch:
Tag:
Non-build tags
All tags
No tags
2014-10-01
2014-10-01 14:34:26 by Martin Nilsson <nilsson@opera.com>
f3d0cc173b07b7d18bdce84586cb5ebf66af2a61 (
3241
lines) (+
1621
/-
1620
)
[
Show
|
Annotate
]
Branch:
8.0
Stdio.IOBuffer -> Stdio.Buffer (part 1)
508:
<dt class='head--type'><span class='homogen--type'>Typedef</span> <span class='homogen--name'><b>read_callback_t</b></span> </dt>
-
<dd><p><code><code class='datatype'>typedef</code> <code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='datatype'>string</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='object unresolved'>
IOBuffer
</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>) Stdio.File.<code class='typedef'>read_callback_t</code></code></p></dd>
+
<dd><p><code><code class='datatype'>typedef</code> <code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='datatype'>string</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='object unresolved'>
Buffer
</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>) Stdio.File.<code class='typedef'>read_callback_t</code></code></p></dd>
<dt class='head--doc'>Description</dt> <dd class='body--doc'><p>The various read_callback signatures.</p> <p> The string (or void) version is used when buffer mode (see <code>set_buffer_mode</code>) has not been enabled for reading.</p>
-
<p> The
IOBuffer
version is used when an
IOBuffer
has been enabled
+
<p> The
Buffer
version is used when an
Buffer
has been enabled
for reading</p> <p> In both cases the data is the newly arrived data, but in buffered mode data you did not fully read in the last read callback is
598:
<dt class='head--type'><span class='homogen--type'>Method</span> <span class='homogen--name'><b>set_buffer_mode</b></span> </dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>set_buffer_mode</span>(</b><code class='object unresolved'>Stdio.
IOBuffer
</code>|<code class='datatype'>int(0..0)</code> <code class='argument'>in</code>, <code class='object unresolved'>Stdio.
IOBuffer
</code>|<code class='datatype'>int(0..0)</code> <code class='argument'>out</code><b>)</b></code></p></dd>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>set_buffer_mode</span>(</b><code class='object unresolved'>Stdio.
Buffer
</code>|<code class='datatype'>int(0..0)</code> <code class='argument'>in</code>, <code class='object unresolved'>Stdio.
Buffer
</code>|<code class='datatype'>int(0..0)</code> <code class='argument'>out</code><b>)</b></code></p></dd>
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Toggle the file to
IOBuffer
mode.</p>
-
<p> In this mode reading and writing will be done via
IOBuffer
+
<dd class='body--doc'><p>Toggle the file to
Buffer
mode.</p>
+
<p> In this mode reading and writing will be done via
Buffer
objects, in the directions you included buffers.</p> </dd> <dt class='head--doc'><span id='p-in'></span>Parameter <code class='parameter'>in</code></dt>
657:
<span class='homogen--name'><b>set_fs_event_callback</b></span><br> </dt> <dd><p><code><code class='datatype'>void</code> <b><span class='method'>set_read_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='datatype'>string</code>:<code class='datatype'>int</code>) <code class='argument'>read_cb</code><b>)</b></code><br>
-
<code><code class='datatype'>void</code> <b><span class='method'>set_read_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='object unresolved'>
IOBuffer
</code>:<code class='datatype'>int</code>) <code class='argument'>read_cb</code><b>)</b></code><br>
+
<code><code class='datatype'>void</code> <b><span class='method'>set_read_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='object unresolved'>
Buffer
</code>:<code class='datatype'>int</code>) <code class='argument'>read_cb</code><b>)</b></code><br>
<code><code class='datatype'>void</code> <b><span class='method'>set_write_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>:<code class='datatype'>int</code>) <code class='argument'>write_cb</code><b>)</b></code><br>
-
<code><code class='datatype'>void</code> <b><span class='method'>set_write_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='object unresolved'>
IOBuffer
</code>:<code class='datatype'>int</code>) <code class='argument'>write_cb</code><b>)</b></code><br>
+
<code><code class='datatype'>void</code> <b><span class='method'>set_write_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='object unresolved'>
Buffer
</code>:<code class='datatype'>int</code>) <code class='argument'>write_cb</code><b>)</b></code><br>
<code><code class='datatype'>void</code> <b><span class='method'>set_read_oob_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>, <code class='datatype'>string</code>:<code class='datatype'>int</code>) <code class='argument'>read_oob_cb</code><b>)</b></code><br> <code><code class='datatype'>void</code> <b><span class='method'>set_write_oob_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>:<code class='datatype'>int</code>) <code class='argument'>write_oob_cb</code><b>)</b></code><br> <code><code class='datatype'>void</code> <b><span class='method'>set_close_callback</span>(</b><code class='datatype'>function</code>(<code class='datatype'>mixed</code>:<code class='datatype'>int</code>) <code class='argument'>close_cb</code><b>)</b></code><br>
680:
<ul> <li><p>When data arrives on the stream, <code>read_cb</code> will be called with some or all of that data as the second argument.</p>
-
<p> If the file is in buffer mode, the second argument will be an
IOBuffer
.</p>
+
<p> If the file is in buffer mode, the second argument will be an
Buffer
.</p>
<p> This will always be the same buffer, so data you do not use in one read callback can be simply left in the buffer, when new data arrives it will be appended</p>
692:
If the remote end has closed both directions simultaneously (the usual case), Pike will first attempt to call <code>close_cb</code>, then this callback (unless <code>close_cb</code> has closed the stream).</p>
-
<p> If the file is in buffer mode, the second argument will be an
IOBuffer
.</p>
+
<p> If the file is in buffer mode, the second argument will be an
Buffer
.</p>
<p> You should add data to write to this buffer.</p> </li><li><p>When out-of-band data arrives on the stream, <code>read_oob_cb</code> will be called with some or all of that data as the second
925:
<dt class='head--type'><span class='homogen--type'>Typedef</span> <span class='homogen--name'><b>write_callback_t</b></span> </dt>
-
<dd><p><code><code class='datatype'>typedef</code> <code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='object unresolved'>
IOBuffer
</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>) Stdio.File.<code class='typedef'>write_callback_t</code></code></p></dd>
+
<dd><p><code><code class='datatype'>typedef</code> <code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>)|<code class='datatype'>function</code>(<code class='datatype'>mixed</code>|<code class='datatype'>void</code>, <code class='object unresolved'>
Buffer
</code>:<code class='datatype'>int</code>|<code class='datatype'>void</code>) Stdio.File.<code class='typedef'>write_callback_t</code></code></p></dd>
<dt class='head--doc'>Description</dt> <dd class='body--doc'><p>The various read_callback signatures.</p> <p> The void version is used when buffer mode (see <code>set_buffer_mode</code>) has not been enabled for writing.</p>
-
<p> The
IOBuffer
version is used when an
IOBuffer
has been enabled
+
<p> The
Buffer
version is used when an
Buffer
has been enabled
for reading, add data to that buffer to send it.</p> </dd></dl> </dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.FILE</b></h2>
4261:
</dt> <dd><p><code><code class='datatype'>int</code> <b><span class='method'>tell</span>(</b><b>)</b></code></p></dd> </dl>
-
</dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.
FakeFile
</b></h2>
+
</dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.
Buffer
</b></h2>
</dt><dd><dl class='group--doc'> <dt class='head--doc'>Description</dt>
-
+
<dd class='body--doc'><p>A buffer to use as input or buffering when doing I/O. It is
+
similar to <code>String.Buffer</code>, but can only contain 8bit data and is
+
designed for protocol parsing. It is optimized for reading from
+
the beginning and adding to the end, and will try to minimize the
+
amount of data copying that is done.</p>
+
<p> The class maintains two separate offsets, one for reading and one
+
for writing. The functions that add data all do so at the write
+
offset (the end of the buffer), and reading is done from the read
+
offset (the start of the buffer).</p>
+
<p> The class can also be used to directly read from and write to
+
filedescriptors if so desired. This eliminates at least one memory
+
copy.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>The "avoid copy" part means that a Buffer will never shrink
+
unless you call the <code>trim</code> function.</p>
+
</dd></dl>
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>__fd_set_output</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>__fd_set_output</span>(</b><code class='datatype'>object</code> <code class='argument'>f</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>This tells the buffer to trigger the write callback for the
+
specified filedescriptor when data is added to the buffer.</p>
+
<p> This is used internally by Stdio.File to handle nonblocking
+
buffered mode, and is not really intended to be used directly.</p>
+
<p> If f is 0 the state is cleared.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>_encode</b></span><br>
+
<span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>_decode</b></span><br>
+
</dt>
+
<dd><p><code><span class='datatype'>string(8bit)</span> <b><span class='method'>encode_value</span>(</b><span class='class'>Stdio.Buffer</span> <span class='argument'>data</span>)</b></code><br>
+
<code><span class='class'>Stdio.Buffer</span> <b><span class='method'>decode_value</span>(</b><span class='datatype'>string(8bit)</span> <span class='argument'>data</span>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Encode and decode Stdio.Buffer objects.
+
Only the buffer data is kept, no other state is saved.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>_sizeof</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>sizeof</span>(</b> <span class='class'>Stdio.Buffer</span> <span class='argument'>arg</span> <b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Returns the buffer size, in bytes.
+
This is how much you can read from the buffer until it runs out of data.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>`[]</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> res = <code class='class'>Stdio.Buffer()</code>[ <code class='class'>off</code> ]</code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Return the character at the specified offset.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>`[]=</b></span>
+
</dt>
+
<dd><p><code><code class='class'>Stdio.Buffer()</code>[ <code class='class'>off</code> ] = <code class='class'>char</code></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Set the character at the specified offset to <code>char</code>.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add</span>(</b><code class='object unresolved'>AddArgument</code> ... <code class='argument'>data</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><pre><code>private typedef System.Memory|Stdio.Buffer|String.Buffer BufferObject;
+
private typedef BufferObject|string(8bit)|int(8bit)|array(AddArgument) AddArgument;</code></pre><p>Add the items in data to the end of the buffer.</p>
+
<p> The supported argument types are:</p>
+
<table class='box'><tr><td><code><code class='datatype'>string(8bit)</code></code></td><td><p>An eight bit string.</p>
+
</td></tr>
+
<tr><td><code><code class='datatype'>int(8bit)</code></code></td><td><p>A single byte</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>System.Memory</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>Stdio.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>String.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='datatype'>array</code>(<code class='object unresolved'>AddArgument</code>)</code></td><td><p>Add all elements in the array individually. Each element may be
+
any one of the types listed here.</p>
+
</td></tr>
+
</table>
+
</dd>
+
<dt class='head--doc'>See also</dt>
+
<dd class='body--doc'><p><code>sprintf</code>, <code>add_int8</code>, <code>add_int16</code>, <code>add_int32</code>, <code>add_int</code>
+
and
+
<code>add_hstring</code></p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_hint</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hint</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code>, <code class='datatype'>int(0..)</code> <code class='argument'>size_width</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>First add the size of the integer when encoded to base 256 as a
+
<code>size_width</code> integer, then add the integer to the buffer, both
+
in network byte order.</p>
+
<p> <code>size_width</code> must be less than Int.NATIVE_MAX.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_hstring</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hstring</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>Stdio.Buffer</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>System.Memory</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>String.Buffer</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_hstring</span>(</b><code class='datatype'>array</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Adds length of data followed by <code>data</code> to the buffer.</p>
+
<p> This is identical to
+
<tt>sprintf("%"+size_size+"H",(string)Stdio.IObuffer(data))</tt> but
+
significantly faster.</p>
+
<p> <code>size_size</code> is the number of bytes used to represent the length of the data.
+
It must be less than Int.NATIVE_MAX.</p>
+
<p> The supported <code>data</code> argument types are</p>
+
<table class='box'><tr><td><code><code class='datatype'>string(8bit)</code></code></td><td><p>An eight bit string.</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>System.Memory</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>Stdio.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='object unresolved'>String.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
+
</td></tr>
+
<tr><td><code><code class='datatype'>array</code></code></td><td><p>Add all elements in the array individually. Each element may be
+
any one of the types listed here.</p>
+
</td></tr>
+
</table></dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_int</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_int</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code>, <code class='datatype'>int(0..)</code> <code class='argument'>width</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Adds a generic integer to the buffer as an (width*8)bit
+
network byteorder number.</p>
+
<p> <code>width</code> must be less than Int.NATIVE_MAX.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_int16</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_int16</span>(</b><code class='datatype'>int(16bit)</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Add a 16-bit network byte order value to the buffer</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_int32</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_int32</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Adds a 32 bit network byte order value to the buffer</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_int8</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_int8</span>(</b><code class='datatype'>int(8bit)</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Adds a single byte to the buffer.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_ints</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_ints</span>(</b><code class='datatype'>array</code>(<code class='datatype'>int</code>) <code class='argument'>integers</code>, <code class='datatype'>int(8bit)</code> <code class='argument'>len</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Add the integers in the specified array, <code>len</code> bytes per int.
+
Equivalent to calling <code>add_int</code> for each integer, but faster,
+
and if an error occurs the buffer will contain no new
+
data. Either all or none of the integers will be added.</p>
+
<p> Errors can occur if one of the elements in <code>integers</code> is not
+
actually an integer, if sizeof(integers)*len is bigger than can
+
be represented in a size_t, or if the buffer cannot grow due to
+
an out of memory condition.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>add_padding</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>add_padding</span>(</b><code class='datatype'>int</code> <code class='argument'>nbytes</code>, <code class='datatype'>int(8bit)</code>|<code class='datatype'>void</code> <code class='argument'>byte</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Add <code>nbytes</code> bytes of padding, if <code>byte</code> is not specified the
+
area will be filled with 0's, otherwise the specified byte will
+
be repeated.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>cast</b></span>
+
</dt>
+
<dd><p><code><b>(</b><span class='datatype'><code class='datatype'>string</code></span><b>)</b><span class='class'>Stdio.Buffer</span>()</code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Convert the buffer to a string.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>This only works for buffers whose length is less than 0x7fffffff.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>clear</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>clear</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Clear the buffer.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>consume</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(0..)</code>|<code class='datatype'>int(-1..-1)</code> <b><span class='method'>consume</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Discard the first <code>n</code> bytes from the buffer</p>
+
<p> Returns -1 on error and the amount of space still left otherwise.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>create</b></span>
+
</dt>
+
<dd><p><code><span class='object'>Stdio.Buffer</span> <span class='class'>Stdio.Buffer</span><b>(</b><code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>len</code><b>)</b></code><br>
+
<code><span class='object'>Stdio.Buffer</span> <span class='class'>Stdio.Buffer</span><b>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>contents</code><b>)</b></code><br>
+
<code><span class='object'>Stdio.Buffer</span> <span class='class'>Stdio.Buffer</span><b>(</b><code class='object unresolved'>System.Memory</code>|<code class='object unresolved'>String.Buffer</code> <code class='argument'>contents</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>If passed an integer or no argument, create a buffer of that
+
size, or if no argument is given, 226 bytes.</p>
+
<p> If <code>contents</code> are specified a new buffer with the contents of
+
the given string/System.Memory or String.Buffer will be created.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>In the <code>String.Buffer</code> case the data has to be copied unless
+
there is only one reference to the String.Buffer object, since
+
modifications of the String.Buffer would cause the Buffer to
+
point into invalid memory.</p>
+
<p> In all other cases this will not copy the string data, instead
+
data will be read from the source until it needs to be modified,
+
so the buffer creation is fast regardless of the length of the
+
string.</p>
+
<p> However, as an example, if the buffer is created with a 100Gb
+
<code>System.Memory</code> mmap:ed file as the <code>contents</code> and you later on
+
try to modify the buffer using one of the <code>add</code> functions (or
+
<code>sprintf</code> and similar) the old contents <b>will</b> be copied.</p>
+
<p> You can use <code>read_only()</code> to avoid accidents.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>input_from</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(-1..)</code> <b><span class='method'>input_from</span>(</b><code class='object unresolved'>Stdio.Stream</code> <code class='argument'>f</code>, <code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>nbytes</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read data from <code>f</code> into this buffer. If <code>nbytes</code> is not
+
specified, read until there is no more data to read (currently).</p>
+
<p> Returns the amount of data that was read, or <code class='expr'>-1</code> on
+
read error.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>Please note that this funcition will read all data from the
+
filedescriptor unless it's set to be non-blocking.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>lock</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>object</code> <b><span class='method'>lock</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Makes this buffer read only until the returned object is released.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>This currently simply returns a 0-length subbuffer.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>match</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>mixed</code> <b><span class='method'>match</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>format</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Reads data from the beginning of the buffer to match the
+
specifed format, then return the match.</p>
+
<p> The non-matching data will be left in the buffer.</p>
+
<p> This function is very similar to <code>sscanf</code>, but the
+
result is the sum of the matches. Most useful to match
+
a single value.</p>
+
</dd>
+
<dt class='head--doc'>Example</dt>
+
<dd class='example'><pre><pre><code><span class='comment'>// get the next whitespace separated word from the buffer.</span>
+
buffer->match<span class='delim'>(</span><span class='string'>"%*[ \t\r\n]%[^ \t\r\n]"</span><span class='delim'>)</span><span class='delim'>;</span>
+
</code></pre></pre></dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>output_to</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(-1..)</code> <b><span class='method'>output_to</span>(</b><code class='object unresolved'>Stdio.Stream</code> <code class='argument'>f</code>, <code class='datatype'>int(0..)</code>|<code class='datatype'>void</code> <code class='argument'>nbytes</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Write data from the buffer to the indicated file.</p>
+
</dd>
+
<dt class='head--doc'><span id='p-nbytes'></span>Parameter <code class='parameter'>nbytes</code></dt>
+
<dd></dd><dd class='body--doc'><p>If <code>nbytes</code> is not specified the whole buffer will be written
+
if possible. Otherwise at most <code>nbytes</code> will be written.</p>
+
</dd>
+
<dt class='head--doc'>Returns</dt>
+
<dd class='body--doc'><p>Will return the number of bytes that have been written successfully.</p>
+
<p> If no bytes have been written successfully and <code class='expr'>f->write()</code> failed
+
with an error, <code class='expr'>-1</code> will be returned.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>range_error</b></span>
+
</dt>
+
<dd><p><code><code class='modifier'>protected</code> <code class='object unresolved'>bool</code> <b><span class='method'>range_error</span>(</b><code class='datatype'>int</code> <code class='argument'>howmuch</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>This function is called when an attempt is made to read out of bounds.</p>
+
<p> The default implementation simply returns <code class='expr'>0</code> (zero).</p>
+
<p> Override this function to change the behavior.</p>
+
</dd>
+
<dt class='head--doc'><span id='p-howmuch'></span>Parameter <code class='parameter'>howmuch</code></dt>
+
<dd></dd><dd class='body--doc'><p>The argument <code>howmuch</code> indicates how much data is needed:</p>
+
<table class='box'><tr><td><code><code class='key'>(1..)</code></code></td><td><p>Need <code>howmuch</code> bytes more</p>
+
</td></tr>
+
<tr><td><code><code class='key'>0</code></code></td><td><p>The amount of data needed is not certain.
+
This most often happens when <code>sscanf</code> or <code>read_json</code> is used</p>
+
</td></tr>
+
<tr><td><code><code class='key'>(..-1)</code></code></td><td><p>Tried to <code>unread</code> -<code>howmuch</code> bytes. There is usually no way to satisfy
+
the requested range.</p>
+
<p> The only supported way is to extract the data from the buffer,
+
add the requested amount of "go backbuffer", add the data
+
back, and forward -<code>howmuch</code> bytes.</p>
+
</td></tr>
+
</table>
+
</dd>
+
<dt class='head--doc'>Returns</dt>
+
<dd class='body--doc'><p><code>true</code> if the operation should be retried, <code>false</code> otherwise.</p>
+
<p> Do not return true unless you have added data to the buffer,
+
doing so could result in an infinite loop (since no data is
+
added, the range_error will be called again immediately).</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read all data from the buffer.</p>
+
<p> If there is not enough data available this returns 0.</p>
+
<p> This is basically equivalent to (string)buffer, but it also
+
removes the data from the buffer.</p>
+
</dd>
+
<dt class='head--doc'>See also</dt>
+
<dd class='body--doc'><p><code>try_read()</code></p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read <code>bytes</code> bytes of data from the buffer.</p>
+
<p> If there is not enough data available this returns 0.</p>
+
</dd>
+
<dt class='head--doc'>See also</dt>
+
<dd class='body--doc'><p><code>try_read()</code></p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_buffer</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>read_buffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>read_buffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='object unresolved'>bool</code> <code class='argument'>copy</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Same as <code>read</code>, but returns the result as an Buffer.</p>
+
<p> No data is copied unless <code>copy</code> is specified and true, the new buffer
+
points into the old one.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>As long as the subbuffer exists no data can be added to the main buffer.</p>
+
<p> Usually this is OK, since it often represents something that
+
should be parsed before the next whatever is extracted from
+
the buffer, but do take care.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_cstring</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read_cstring</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Reads a \0 terminated C-string and returns the
+
string excluding the terminating \0.</p>
+
<p> If there is not enough data available return UNDEFINED.</p>
+
<p> Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_hbuffer</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>read_hbuffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>read_hbuffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='object unresolved'>bool</code> <code class='argument'>copy</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Same as <code>read_hstring</code>, but returns the result as an Buffer.</p>
+
<p> No data is copied unless <code>copy</code> is specified and true, the new
+
buffer points into the old one.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>As long as the subbuffer exists no data can be added to the
+
main buffer.</p>
+
<p> Usually this is OK, since it often represents something that
+
should be parsed before the next whatever is extracted from
+
the buffer, but do take care.</p>
+
<p> If you need to unlink the new buffer after it has been
+
created, call <code>trim</code> in it.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_hint</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_hint</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read a network byte order unsigned number of size n*8 bits, then
+
read another network byte order number of the size indicated by
+
the first size.</p>
+
<p> Will return -1 if there is not enough buffer space available
+
unless error mode is set to throw errors.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_hstring</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read_hstring</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Identical in functionality to <code>read</code>(<code>read_number</code>(<code>n</code>)) but
+
faster.</p>
+
<p> Read a network byte order number of size n*8 bits, then return the
+
indicated number of bytes as a string.</p>
+
<p> If there is not enough data available return 0.</p>
+
<p> Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_int</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_int</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read a network byte order unsigned number of size n*8 bits, then
+
return it.</p>
+
<p> Will return -1 if there is not enough buffer space available
+
unless error mode is set to throw errors.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_int16</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(16bit)</code> <b><span class='method'>read_int16</span>(</b><b>)</b></code></p></dd>
+
</dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_int24</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(24bit)</code> <b><span class='method'>read_int24</span>(</b><b>)</b></code></p></dd>
+
</dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_int32</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(32bit)</code> <b><span class='method'>read_int32</span>(</b><b>)</b></code></p></dd>
+
</dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_int8</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(8bit)</code> <b><span class='method'>read_int8</span>(</b><b>)</b></code></p></dd>
+
</dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_ints</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>array</code>(<code class='datatype'>int</code>) <b><span class='method'>read_ints</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='datatype'>int</code> <code class='argument'>width</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read a list of <code>n</code> network byte order unsigned numbers each of
+
size <code>width</code>*8 bits, then return it.</p>
+
<p> Will return 0 if there is not enough buffer space available
+
unless error mode is set to throw errors.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_json</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>mixed</code> <b><span class='method'>read_json</span>(</b><code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>require_whitespace_separator</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read a single JSON expression from the buffer and return it.</p>
+
<p> If <code>require_whitespace_separator</code> is true there must be a whitespace
+
after each json value (as an example, newline or space).</p>
+
<p> The JSON is assumed to be utf-8 encoded.</p>
+
</dd>
+
<dt class='head--doc'>Returns</dt>
+
<dd class='body--doc'><p>UNDEFINED if no data is available to read.
+
The read value otherwise.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>Unless whitespaces are required this function only really work correctly
+
with objects, arrays and strings.</p>
+
<p> There is really no way to see where one value starts and the other ends
+
for most other cases</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_only</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>read_only</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Make the buffer permanently read only.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>You can use lock() to do this temporarily.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>read_sint</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_sint</span>(</b><code class='datatype'>int</code> <code class='argument'>size</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Read a network byte order two:s complement signed number of size n*8 bits, then
+
return it.</p>
+
<p> Will return UNDEFINED if there is not enough buffer space
+
available unless error mode is set to throw errors.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>rewind_on_error</b></span><br>
+
<span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>rewind_key</b></span><br>
+
</dt>
+
<dd><p><code><code class='object unresolved'>RewindKey</code> <b><span class='method'>rewind_on_error</span>(</b><b>)</b></code><br>
+
<code><code class='object unresolved'>RewindKey</code> <b><span class='method'>rewind_key</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>These functions are very similar. The <code>rewind_on_error</code> edition
+
will create an object that, when it goes out of scope without
+
having been destructed explicitly, will cause the buffer to
+
rewind to the location it had when this function is called.</p>
+
<p> This will happen if you throw an error <i>or</i> otherwise let the
+
object fall out of scope.</p>
+
<p> Use <code>destruct(RewindKey)</code> or <code>RewindKey.release</code> to stop the
+
buffer from being rewound.</p>
+
<p> The second version (<code>rewind_key</code>) requires you to explicitly
+
call <code>RewindKey.rewind</code> to do the rewind.</p>
+
<p> Take some care with these objects, if you create multiple ones
+
at once the results might be somewhat confusing if you do not
+
release them in the reverse order they were created in (then
+
again, you almost certainly really only need one)</p>
+
<p> You can call <code>RewindKey.update</code> in the generated object to
+
change where it will be rewound to.</p>
+
<p> The typical use-case of this functionality is when parsing a
+
packet protocol with variable length packets where the lenght is
+
not immediately known. It saves you from keeping track of how
+
much to rewind if you had not actually gotten the whole packet
+
yet.</p>
+
</dd>
+
<dt class='head--doc'>Example</dt>
+
<dd class='example'><pre><pre><code><span class='type'>void</span> parse_packet<span class='delim'>(</span> <span class='ns'>Stdio</span><span class='delim'>.</span>Buffer b <span class='delim'>)</span>
+
<span class='delim'>{</span>
+
<span class='ns'>Stdio</span><span class='delim'>.</span>Buffer<span class='delim'>.</span>RewindKey rewind <span class='delim'>=</span> b->rewind_on_error<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
+
b->set_error_mode<span class='delim'>(</span>1<span class='delim'>)</span><span class='delim'>;</span>
+
+
<span class='lang'>switch</span><span class='delim'>(</span> b->read_int8<span class='delim'>(</span><span class='delim'>)</span> <span class='delim'>)</span> <span class='comment'>// packet type</span>
+
<span class='delim'>{</span>
+
<span class='lang'>case</span> DATA<span class='delim'>:</span>
+
<span class='type'>int</span> channel <span class='delim'>=</span> b->read_int8<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
+
<span class='ns'>Stdio</span><span class='delim'>.</span>Buffer data <span class='delim'>=</span> b->read_hbuffer<span class='delim'>(</span> 4 <span class='delim'>)</span><span class='delim'>;</span>
+
<span class='comment'>// we have read the whole packet, so no longer rewind on error.</span>
+
rewind->release<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
+
<span class='lang'>return</span> handle_data_packet<span class='delim'>(</span> chennel<span class='delim'>,</span> data <span class='delim'>)</span><span class='delim'>;</span>
+
<span class='delim'>}</span>
+
<span class='delim'>}</span>
+
</code></pre></pre></dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>Just calling <code>rewind_on_error</code> without assigning the return
+
value to something will not do anything. You need to keep the
+
object around while the rewind-to position is still valid.</p>
+
<p> Keeping the object around forbids the buffer from moving data
+
inside itself, this means that it can only grow. So do not keep
+
the rewind key when it is not needed.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>set_error_mode</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>set_error_mode</span>(</b><code class='datatype'>int</code> <code class='argument'>m</code><b>)</b></code><br>
+
<code><code class='object unresolved'>Buffer</code> <b><span class='method'>set_error_mode</span>(</b><code class='datatype'>program</code> <code class='argument'>m</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Set the error mode of this buffer to <code>m</code>.</p>
+
<p> If true operations that would normally return 0 (like trying to
+
read too much) will instead throw an error. If <code>m</code> is a program
+
a clone of it will be thrown on error.</p>
+
<p> This is useful when parsing received data, you do not have to
+
verify that each and every read operation suceeds.</p>
+
<p> However, the non-error mode is more useful when checking to see
+
if a packet/segment/whatever has arrived.</p>
+
<p> The thrown error object will have the constant buffer_error set
+
to a non-false value.</p>
+
</dd>
+
<dt class='head--doc'>Example</dt>
+
<dd class='example'><pre><pre><code><span class='type'>void</span> read_callback<span class='delim'>(</span><span class='type'>int</span> i<span class='delim'>,</span> <span class='type'>string</span> new_data<span class='delim'>)</span>
+
<span class='delim'>{</span>
+
inbuffer->add<span class='delim'>(</span> new_data <span class='delim'>)</span><span class='delim'>;</span>
+
+
<span class='lang'>while</span><span class='delim'>(</span> Buffer packet <span class='delim'>=</span> inbuffer->read_hbuffer<span class='delim'>(</span>2<span class='delim'>)</span> <span class='delim'>)</span>
+
<span class='delim'>{</span>
+
packet->set_error_mode<span class='delim'>(</span>Buffer<span class='delim'>.</span>THROW_ERROR<span class='delim'>)</span><span class='delim'>;</span>
+
<span class='lang'>if</span><span class='delim'>(</span> <span class='type'>mixed</span> e <span class='delim'>=</span> <span class='lang'>catch</span><span class='delim'>(</span> handle_packet<span class='delim'>(</span> packet <span class='delim'>)</span> <span class='delim'>)</span> <span class='delim'>)</span>
+
<span class='lang'>if</span><span class='delim'>(</span> e->buffer_error <span class='delim'>)</span>
+
protocol_error<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span> <span class='comment'>// illegal data in packet</span>
+
<span class='lang'>else</span>
+
throw<span class='delim'>(</span>e<span class='delim'>)</span><span class='delim'>;</span> <span class='comment'>// the other code did something bad</span>
+
<span class='delim'>}</span>
+
<span class='delim'>}</span>
+
+
<span class='type'>void</span> handle_packet<span class='delim'>(</span> Buffer pack <span class='delim'>)</span>
+
<span class='delim'>{</span>
+
<span class='lang'>switch</span><span class='delim'>(</span> pack->read_int8<span class='delim'>(</span><span class='delim'>)</span> <span class='delim'>)</span>
+
<span class='delim'>{</span>
+
...
+
<span class='lang'>case</span> HEADER_FRAME<span class='delim'>:</span>
+
<span class='type'>int</span> num_headers <span class='delim'>=</span> pack->read_int32<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
+
<span class='lang'>for</span><span class='delim'>(</span> <span class='type'>int</span> i <span class='delim'>=</span> 0<span class='delim'>;</span> i<span class='delim'><</span>num_headers<span class='delim'>;</span> i++ <span class='delim'>)</span>
+
headers<span class='delim'>[</span>pack->read_hstring<span class='delim'>(</span>2<span class='delim'>)</span><span class='delim'>]</span> <span class='delim'>=</span> pack->read_hstring<span class='delim'>(</span>2<span class='delim'>)</span><span class='delim'>;</span>
+
...
+
<span class='delim'>}</span>
+
<span class='delim'>}</span>
+
</code></pre></pre></dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>sprintf</b></span>
+
</dt>
+
<dd><p><code><code class='object unresolved'>Buffer</code> <b><span class='method'>sprintf</span>(</b><code class='object unresolved'>strict_sprintf_format</code> <code class='argument'>format</code>, <code class='object unresolved'>sprintf_args</code> ... <code class='argument'>args</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Appends the output from <code>sprintf</code> at the end of the buffer.</p>
+
<p> This is somewhat faster than add(sprintf(...)) since no
+
intermediate string is created.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>sscanf</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>array</code> <b><span class='method'>sscanf</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>format</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Reads data from the beginning of the buffer to match the
+
specifed format, then return an array with the matches.</p>
+
<p> The non-matching data will be left in the buffer.</p>
+
<p> See <code>array_sscanf</code> for more information.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>trim</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>trim</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Frees unused memory.</p>
+
<p> Note that calling this function excessively will slow things
+
down, since the data often has to be copied.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>This function could possibly throw an out-of-memory error
+
if the realloc fails to find a new (smaller) memory area.</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>try_read</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>try_read</span>(</b><code class='datatype'>int</code> <code class='argument'>len</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Attempt to read some data from the buffer.</p>
+
</dd>
+
<dt class='head--doc'><span id='p-len'></span>Parameter <code class='parameter'>len</code></dt>
+
<dd></dd><dd class='body--doc'><p>Read at most <code>len</code> bytes from the buffer.</p>
+
</dd>
+
<dt class='head--doc'>Returns</dt>
+
<dd class='body--doc'><p>If the buffer contains less than <code>len</code> bytes
+
of data, the entire buffer contents are returned.
+
Otherwise the first <code>len</code> bytes are returned.</p>
+
</dd>
+
<dt class='head--doc'>See also</dt>
+
<dd class='body--doc'><p><code>read()</code></p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>unread</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>int(0..)</code>|<code class='datatype'>int(-1..-1)</code> <b><span class='method'>unread</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Rewind the buffer <code>n</code> bytes.</p>
+
</dd>
+
<dt class='head--doc'>Returns</dt>
+
<dd class='body--doc'><p>This function returns how many more bytes of buffer is
+
available to rewind, or -1 on error.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>Unless you add new data to the buffer using any of the add
+
functions you can always rewind.</p>
+
<p> You can call <code>unread(0)</code> to see how much.</p>
+
</dd></dl>
+
<dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.Buffer.RewindKey</b></h2>
+
</dt><dd><dl class='group--doc'>
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>The return value of <code>Buffer.rewind_on_error()</code> and
+
<code>Buffer.rewind_key()</code></p>
+
<p> This object will cause the buffer to unwind to the position it was
+
at when the object was created either when it is released (when it
+
falls out of scope, explicit destruct does not count) or when
+
<code>rewind</code> is called, depending on which function was used to
+
create it.</p>
+
</dd></dl>
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>release</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>release</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Do not rewind if the object is released.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>This is equivalent to calling destruct() on the object</p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>rewind</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>rewind</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Rewinds the buffer explicitly.</p>
+
</dd>
+
<dt class='head--doc'>Note</dt>
+
<dd class='body--doc'><p>Destructs this <code>RewindKey</code></p>
+
</dd></dl>
+
+
+
<hr />
+
<dl class='group--doc'>
+
<dt class='head--type'><span class='homogen--type'>Method</span>
+
<span class='homogen--name'><b>update</b></span>
+
</dt>
+
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>update</span>(</b><b>)</b></code></p></dd>
+
+
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>Update the location the buffer will be rewound to to the current
+
position of the buffer.</p>
+
</dd></dl>
+
</dd></dl></dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.FakeFile</b></h2>
+
</dt><dd><dl class='group--doc'>
+
<dt class='head--doc'>Description</dt>
<dd class='body--doc'><p>A string wrapper that pretends to be a <code>Stdio.File</code> object in addition to some features of a <code>Stdio.FILE</code> object.</p> </dd></dl>
6147:
<dd class='body--doc'><p>Fake inherit to propagate the documentation from <code>_Stdio.Fd</code>.</p> </dd></dl>
-
</dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.
IOBuffer
</b></h2>
+
</dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.
NonblockingStream
</b></h2>
</dt><dd><dl class='group--doc'> <dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>A buffer to use as input or buffering when doing I/O. It is
-
similar to <code>String.Buffer</code>, but can only contain 8bit data and is
-
designed for protocol parsing. It is optimized for reading from
-
the beginning and adding to the end, and will try to minimize the
-
amount of data copying that is done.</p>
-
<p> The class maintains two separate offsets, one for reading and one
-
for writing. The functions that add data all do so at the write
-
offset (the end of the buffer), and reading is done from the read
-
offset (the start of the buffer).</p>
-
<p> The class can also be used to directly read from and write to
-
filedescriptors if so desired. This eliminates at least one memory
-
copy.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>The "avoid copy" part means that a IOBuffer will never shrink
-
unless you call the <code>trim</code> function.</p>
-
</dd></dl>
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>__fd_set_output</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>__fd_set_output</span>(</b><code class='datatype'>object</code> <code class='argument'>f</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>This tells the buffer to trigger the write callback for the
-
specified filedescriptor when data is added to the buffer.</p>
-
<p> This is used internally by Stdio.File to handle nonblocking
-
buffered mode, and is not really intended to be used directly.</p>
-
<p> If f is 0 the state is cleared.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>_encode</b></span><br>
-
<span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>_decode</b></span><br>
-
</dt>
-
<dd><p><code><span class='datatype'>string(8bit)</span> <b><span class='method'>encode_value</span>(</b><span class='class'>Stdio.IOBuffer</span> <span class='argument'>data</span>)</b></code><br>
-
<code><span class='class'>Stdio.IOBuffer</span> <b><span class='method'>decode_value</span>(</b><span class='datatype'>string(8bit)</span> <span class='argument'>data</span>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Encode and decode Stdio.IOBuffer objects.
-
Only the buffer data is kept, no other state is saved.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>_sizeof</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>sizeof</span>(</b> <span class='class'>Stdio.IOBuffer</span> <span class='argument'>arg</span> <b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Returns the buffer size, in bytes.
-
This is how much you can read from the buffer until it runs out of data.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>`[]</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> res = <code class='class'>Stdio.IOBuffer()</code>[ <code class='class'>off</code> ]</code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Return the character at the specified offset.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>`[]=</b></span>
-
</dt>
-
<dd><p><code><code class='class'>Stdio.IOBuffer()</code>[ <code class='class'>off</code> ] = <code class='class'>char</code></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Set the character at the specified offset to <code>char</code>.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add</span>(</b><code class='object unresolved'>AddArgument</code> ... <code class='argument'>data</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><pre><code>private typedef System.Memory|Stdio.IOBuffer|String.Buffer BufferObject;
-
private typedef BufferObject|string(8bit)|int(8bit)|array(AddArgument) AddArgument;</code></pre><p>Add the items in data to the end of the buffer.</p>
-
<p> The supported argument types are:</p>
-
<table class='box'><tr><td><code><code class='datatype'>string(8bit)</code></code></td><td><p>An eight bit string.</p>
-
</td></tr>
-
<tr><td><code><code class='datatype'>int(8bit)</code></code></td><td><p>A single byte</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>System.Memory</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>Stdio.IOBuffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>String.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='datatype'>array</code>(<code class='object unresolved'>AddArgument</code>)</code></td><td><p>Add all elements in the array individually. Each element may be
-
any one of the types listed here.</p>
-
</td></tr>
-
</table>
-
</dd>
-
<dt class='head--doc'>See also</dt>
-
<dd class='body--doc'><p><code>sprintf</code>, <code>add_int8</code>, <code>add_int16</code>, <code>add_int32</code>, <code>add_int</code>
-
and
-
<code>add_hstring</code></p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_hint</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hint</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code>, <code class='datatype'>int(0..)</code> <code class='argument'>size_width</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>First add the size of the integer when encoded to base 256 as a
-
<code>size_width</code> integer, then add the integer to the buffer, both
-
in network byte order.</p>
-
<p> <code>size_width</code> must be less than Int.NATIVE_MAX.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_hstring</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hstring</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>Stdio.IOBuffer</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>System.Memory</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hstring</span>(</b><code class='object unresolved'>String.Buffer</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_hstring</span>(</b><code class='datatype'>array</code> <code class='argument'>data</code>, <code class='datatype'>int</code> <code class='argument'>size_size</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Adds length of data followed by <code>data</code> to the buffer.</p>
-
<p> This is identical to
-
<tt>sprintf("%"+size_size+"H",(string)Stdio.IObuffer(data))</tt> but
-
significantly faster.</p>
-
<p> <code>size_size</code> is the number of bytes used to represent the length of the data.
-
It must be less than Int.NATIVE_MAX.</p>
-
<p> The supported <code>data</code> argument types are</p>
-
<table class='box'><tr><td><code><code class='datatype'>string(8bit)</code></code></td><td><p>An eight bit string.</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>System.Memory</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>Stdio.IOBuffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='object unresolved'>String.Buffer</code></code></td><td><p>A chunk of memory. The whole memory area is added.</p>
-
</td></tr>
-
<tr><td><code><code class='datatype'>array</code></code></td><td><p>Add all elements in the array individually. Each element may be
-
any one of the types listed here.</p>
-
</td></tr>
-
</table></dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_int</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_int</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code>, <code class='datatype'>int(0..)</code> <code class='argument'>width</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Adds a generic integer to the buffer as an (width*8)bit
-
network byteorder number.</p>
-
<p> <code>width</code> must be less than Int.NATIVE_MAX.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_int16</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_int16</span>(</b><code class='datatype'>int(16bit)</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Add a 16-bit network byte order value to the buffer</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_int32</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_int32</span>(</b><code class='datatype'>int</code> <code class='argument'>i</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Adds a 32 bit network byte order value to the buffer</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_int8</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_int8</span>(</b><code class='datatype'>int(8bit)</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Adds a single byte to the buffer.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_ints</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_ints</span>(</b><code class='datatype'>array</code>(<code class='datatype'>int</code>) <code class='argument'>integers</code>, <code class='datatype'>int(8bit)</code> <code class='argument'>len</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Add the integers in the specified array, <code>len</code> bytes per int.
-
Equivalent to calling <code>add_int</code> for each integer, but faster,
-
and if an error occurs the buffer will contain no new
-
data. Either all or none of the integers will be added.</p>
-
<p> Errors can occur if one of the elements in <code>integers</code> is not
-
actually an integer, if sizeof(integers)*len is bigger than can
-
be represented in a size_t, or if the buffer cannot grow due to
-
an out of memory condition.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>add_padding</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>add_padding</span>(</b><code class='datatype'>int</code> <code class='argument'>nbytes</code>, <code class='datatype'>int(8bit)</code>|<code class='datatype'>void</code> <code class='argument'>byte</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Add <code>nbytes</code> bytes of padding, if <code>byte</code> is not specified the
-
area will be filled with 0's, otherwise the specified byte will
-
be repeated.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>cast</b></span>
-
</dt>
-
<dd><p><code><b>(</b><span class='datatype'><code class='datatype'>string</code></span><b>)</b><span class='class'>Stdio.IOBuffer</span>()</code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Convert the buffer to a string.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>This only works for buffers whose length is less than 0x7fffffff.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>clear</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>clear</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Clear the buffer.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>consume</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(0..)</code>|<code class='datatype'>int(-1..-1)</code> <b><span class='method'>consume</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Discard the first <code>n</code> bytes from the buffer</p>
-
<p> Returns -1 on error and the amount of space still left otherwise.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>create</b></span>
-
</dt>
-
<dd><p><code><span class='object'>Stdio.IOBuffer</span> <span class='class'>Stdio.IOBuffer</span><b>(</b><code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>len</code><b>)</b></code><br>
-
<code><span class='object'>Stdio.IOBuffer</span> <span class='class'>Stdio.IOBuffer</span><b>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>contents</code><b>)</b></code><br>
-
<code><span class='object'>Stdio.IOBuffer</span> <span class='class'>Stdio.IOBuffer</span><b>(</b><code class='object unresolved'>System.Memory</code>|<code class='object unresolved'>String.Buffer</code> <code class='argument'>contents</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>If passed an integer or no argument, create a buffer of that
-
size, or if no argument is given, 226 bytes.</p>
-
<p> If <code>contents</code> are specified a new buffer with the contents of
-
the given string/System.Memory or String.Buffer will be created.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>In the <code>String.Buffer</code> case the data has to be copied unless
-
there is only one reference to the String.Buffer object, since
-
modifications of the String.Buffer would cause the IOBuffer to
-
point into invalid memory.</p>
-
<p> In all other cases this will not copy the string data, instead
-
data will be read from the source until it needs to be modified,
-
so the buffer creation is fast regardless of the length of the
-
string.</p>
-
<p> However, as an example, if the buffer is created with a 100Gb
-
<code>System.Memory</code> mmap:ed file as the <code>contents</code> and you later on
-
try to modify the buffer using one of the <code>add</code> functions (or
-
<code>sprintf</code> and similar) the old contents <b>will</b> be copied.</p>
-
<p> You can use <code>read_only()</code> to avoid accidents.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>input_from</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(-1..)</code> <b><span class='method'>input_from</span>(</b><code class='object unresolved'>Stdio.Stream</code> <code class='argument'>f</code>, <code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>nbytes</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read data from <code>f</code> into this buffer. If <code>nbytes</code> is not
-
specified, read until there is no more data to read (currently).</p>
-
<p> Returns the amount of data that was read, or <code class='expr'>-1</code> on
-
read error.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>Please note that this funcition will read all data from the
-
filedescriptor unless it's set to be non-blocking.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>lock</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>object</code> <b><span class='method'>lock</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Makes this buffer read only until the returned object is released.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>This currently simply returns a 0-length subbuffer.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>match</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>mixed</code> <b><span class='method'>match</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>format</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Reads data from the beginning of the buffer to match the
-
specifed format, then return the match.</p>
-
<p> The non-matching data will be left in the buffer.</p>
-
<p> This function is very similar to <code>sscanf</code>, but the
-
result is the sum of the matches. Most useful to match
-
a single value.</p>
-
</dd>
-
<dt class='head--doc'>Example</dt>
-
<dd class='example'><pre><pre><code><span class='comment'>// get the next whitespace separated word from the buffer.</span>
-
buffer->match<span class='delim'>(</span><span class='string'>"%*[ \t\r\n]%[^ \t\r\n]"</span><span class='delim'>)</span><span class='delim'>;</span>
-
</code></pre></pre></dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>output_to</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(-1..)</code> <b><span class='method'>output_to</span>(</b><code class='object unresolved'>Stdio.Stream</code> <code class='argument'>f</code>, <code class='datatype'>int(0..)</code>|<code class='datatype'>void</code> <code class='argument'>nbytes</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Write data from the buffer to the indicated file.</p>
-
</dd>
-
<dt class='head--doc'><span id='p-nbytes'></span>Parameter <code class='parameter'>nbytes</code></dt>
-
<dd></dd><dd class='body--doc'><p>If <code>nbytes</code> is not specified the whole buffer will be written
-
if possible. Otherwise at most <code>nbytes</code> will be written.</p>
-
</dd>
-
<dt class='head--doc'>Returns</dt>
-
<dd class='body--doc'><p>Will return the number of bytes that have been written successfully.</p>
-
<p> If no bytes have been written successfully and <code class='expr'>f->write()</code> failed
-
with an error, <code class='expr'>-1</code> will be returned.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>range_error</b></span>
-
</dt>
-
<dd><p><code><code class='modifier'>protected</code> <code class='object unresolved'>bool</code> <b><span class='method'>range_error</span>(</b><code class='datatype'>int</code> <code class='argument'>howmuch</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>This function is called when an attempt is made to read out of bounds.</p>
-
<p> The default implementation simply returns <code class='expr'>0</code> (zero).</p>
-
<p> Override this function to change the behavior.</p>
-
</dd>
-
<dt class='head--doc'><span id='p-howmuch'></span>Parameter <code class='parameter'>howmuch</code></dt>
-
<dd></dd><dd class='body--doc'><p>The argument <code>howmuch</code> indicates how much data is needed:</p>
-
<table class='box'><tr><td><code><code class='key'>(1..)</code></code></td><td><p>Need <code>howmuch</code> bytes more</p>
-
</td></tr>
-
<tr><td><code><code class='key'>0</code></code></td><td><p>The amount of data needed is not certain.
-
This most often happens when <code>sscanf</code> or <code>read_json</code> is used</p>
-
</td></tr>
-
<tr><td><code><code class='key'>(..-1)</code></code></td><td><p>Tried to <code>unread</code> -<code>howmuch</code> bytes. There is usually no way to satisfy
-
the requested range.</p>
-
<p> The only supported way is to extract the data from the buffer,
-
add the requested amount of "go backbuffer", add the data
-
back, and forward -<code>howmuch</code> bytes.</p>
-
</td></tr>
-
</table>
-
</dd>
-
<dt class='head--doc'>Returns</dt>
-
<dd class='body--doc'><p><code>true</code> if the operation should be retried, <code>false</code> otherwise.</p>
-
<p> Do not return true unless you have added data to the buffer,
-
doing so could result in an infinite loop (since no data is
-
added, the range_error will be called again immediately).</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read all data from the buffer.</p>
-
<p> If there is not enough data available this returns 0.</p>
-
<p> This is basically equivalent to (string)buffer, but it also
-
removes the data from the buffer.</p>
-
</dd>
-
<dt class='head--doc'>See also</dt>
-
<dd class='body--doc'><p><code>try_read()</code></p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read <code>bytes</code> bytes of data from the buffer.</p>
-
<p> If there is not enough data available this returns 0.</p>
-
</dd>
-
<dt class='head--doc'>See also</dt>
-
<dd class='body--doc'><p><code>try_read()</code></p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_buffer</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>read_buffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>read_buffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='object unresolved'>bool</code> <code class='argument'>copy</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Same as <code>read</code>, but returns the result as an IOBuffer.</p>
-
<p> No data is copied unless <code>copy</code> is specified and true, the new buffer
-
points into the old one.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>As long as the subbuffer exists no data can be added to the main buffer.</p>
-
<p> Usually this is OK, since it often represents something that
-
should be parsed before the next whatever is extracted from
-
the buffer, but do take care.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_cstring</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read_cstring</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Reads a \0 terminated C-string and returns the
-
string excluding the terminating \0.</p>
-
<p> If there is not enough data available return UNDEFINED.</p>
-
<p> Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_hbuffer</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>read_hbuffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>read_hbuffer</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='object unresolved'>bool</code> <code class='argument'>copy</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Same as <code>read_hstring</code>, but returns the result as an IOBuffer.</p>
-
<p> No data is copied unless <code>copy</code> is specified and true, the new
-
buffer points into the old one.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>As long as the subbuffer exists no data can be added to the
-
main buffer.</p>
-
<p> Usually this is OK, since it often represents something that
-
should be parsed before the next whatever is extracted from
-
the buffer, but do take care.</p>
-
<p> If you need to unlink the new buffer after it has been
-
created, call <code>trim</code> in it.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_hint</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_hint</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read a network byte order unsigned number of size n*8 bits, then
-
read another network byte order number of the size indicated by
-
the first size.</p>
-
<p> Will return -1 if there is not enough buffer space available
-
unless error mode is set to throw errors.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_hstring</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>read_hstring</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Identical in functionality to <code>read</code>(<code>read_number</code>(<code>n</code>)) but
-
faster.</p>
-
<p> Read a network byte order number of size n*8 bits, then return the
-
indicated number of bytes as a string.</p>
-
<p> If there is not enough data available return 0.</p>
-
<p> Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_int</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_int</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read a network byte order unsigned number of size n*8 bits, then
-
return it.</p>
-
<p> Will return -1 if there is not enough buffer space available
-
unless error mode is set to throw errors.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_int16</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(16bit)</code> <b><span class='method'>read_int16</span>(</b><b>)</b></code></p></dd>
-
</dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_int24</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(24bit)</code> <b><span class='method'>read_int24</span>(</b><b>)</b></code></p></dd>
-
</dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_int32</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(32bit)</code> <b><span class='method'>read_int32</span>(</b><b>)</b></code></p></dd>
-
</dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_int8</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(8bit)</code> <b><span class='method'>read_int8</span>(</b><b>)</b></code></p></dd>
-
</dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_ints</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>array</code>(<code class='datatype'>int</code>) <b><span class='method'>read_ints</span>(</b><code class='datatype'>int</code> <code class='argument'>n</code>, <code class='datatype'>int</code> <code class='argument'>width</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read a list of <code>n</code> network byte order unsigned numbers each of
-
size <code>width</code>*8 bits, then return it.</p>
-
<p> Will return 0 if there is not enough buffer space available
-
unless error mode is set to throw errors.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_json</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>mixed</code> <b><span class='method'>read_json</span>(</b><code class='datatype'>int</code>|<code class='datatype'>void</code> <code class='argument'>require_whitespace_separator</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read a single JSON expression from the buffer and return it.</p>
-
<p> If <code>require_whitespace_separator</code> is true there must be a whitespace
-
after each json value (as an example, newline or space).</p>
-
<p> The JSON is assumed to be utf-8 encoded.</p>
-
</dd>
-
<dt class='head--doc'>Returns</dt>
-
<dd class='body--doc'><p>UNDEFINED if no data is available to read.
-
The read value otherwise.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>Unless whitespaces are required this function only really work correctly
-
with objects, arrays and strings.</p>
-
<p> There is really no way to see where one value starts and the other ends
-
for most other cases</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_only</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>read_only</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Make the buffer permanently read only.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>You can use lock() to do this temporarily.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>read_sint</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int</code> <b><span class='method'>read_sint</span>(</b><code class='datatype'>int</code> <code class='argument'>size</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Read a network byte order two:s complement signed number of size n*8 bits, then
-
return it.</p>
-
<p> Will return UNDEFINED if there is not enough buffer space
-
available unless error mode is set to throw errors.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>rewind_on_error</b></span><br>
-
<span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>rewind_key</b></span><br>
-
</dt>
-
<dd><p><code><code class='object unresolved'>RewindKey</code> <b><span class='method'>rewind_on_error</span>(</b><b>)</b></code><br>
-
<code><code class='object unresolved'>RewindKey</code> <b><span class='method'>rewind_key</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>These functions are very similar. The <code>rewind_on_error</code> edition
-
will create an object that, when it goes out of scope without
-
having been destructed explicitly, will cause the buffer to
-
rewind to the location it had when this function is called.</p>
-
<p> This will happen if you throw an error <i>or</i> otherwise let the
-
object fall out of scope.</p>
-
<p> Use <code>destruct(RewindKey)</code> or <code>RewindKey.release</code> to stop the
-
buffer from being rewound.</p>
-
<p> The second version (<code>rewind_key</code>) requires you to explicitly
-
call <code>RewindKey.rewind</code> to do the rewind.</p>
-
<p> Take some care with these objects, if you create multiple ones
-
at once the results might be somewhat confusing if you do not
-
release them in the reverse order they were created in (then
-
again, you almost certainly really only need one)</p>
-
<p> You can call <code>RewindKey.update</code> in the generated object to
-
change where it will be rewound to.</p>
-
<p> The typical use-case of this functionality is when parsing a
-
packet protocol with variable length packets where the lenght is
-
not immediately known. It saves you from keeping track of how
-
much to rewind if you had not actually gotten the whole packet
-
yet.</p>
-
</dd>
-
<dt class='head--doc'>Example</dt>
-
<dd class='example'><pre><pre><code><span class='type'>void</span> parse_packet<span class='delim'>(</span> <span class='ns'>Stdio</span><span class='delim'>.</span>IOBuffer b <span class='delim'>)</span>
-
<span class='delim'>{</span>
-
<span class='ns'>Stdio</span><span class='delim'>.</span>IOBuffer<span class='delim'>.</span>RewindKey rewind <span class='delim'>=</span> b->rewind_on_error<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
-
b->set_error_mode<span class='delim'>(</span>1<span class='delim'>)</span><span class='delim'>;</span>
-
-
<span class='lang'>switch</span><span class='delim'>(</span> b->read_int8<span class='delim'>(</span><span class='delim'>)</span> <span class='delim'>)</span> <span class='comment'>// packet type</span>
-
<span class='delim'>{</span>
-
<span class='lang'>case</span> DATA<span class='delim'>:</span>
-
<span class='type'>int</span> channel <span class='delim'>=</span> b->read_int8<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
-
<span class='ns'>Stdio</span><span class='delim'>.</span>IOBuffer data <span class='delim'>=</span> b->read_hbuffer<span class='delim'>(</span> 4 <span class='delim'>)</span><span class='delim'>;</span>
-
<span class='comment'>// we have read the whole packet, so no longer rewind on error.</span>
-
rewind->release<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
-
<span class='lang'>return</span> handle_data_packet<span class='delim'>(</span> chennel<span class='delim'>,</span> data <span class='delim'>)</span><span class='delim'>;</span>
-
<span class='delim'>}</span>
-
<span class='delim'>}</span>
-
</code></pre></pre></dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>Just calling <code>rewind_on_error</code> without assigning the return
-
value to something will not do anything. You need to keep the
-
object around while the rewind-to position is still valid.</p>
-
<p> Keeping the object around forbids the buffer from moving data
-
inside itself, this means that it can only grow. So do not keep
-
the rewind key when it is not needed.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>set_error_mode</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>set_error_mode</span>(</b><code class='datatype'>int</code> <code class='argument'>m</code><b>)</b></code><br>
-
<code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>set_error_mode</span>(</b><code class='datatype'>program</code> <code class='argument'>m</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Set the error mode of this buffer to <code>m</code>.</p>
-
<p> If true operations that would normally return 0 (like trying to
-
read too much) will instead throw an error. If <code>m</code> is a program
-
a clone of it will be thrown on error.</p>
-
<p> This is useful when parsing received data, you do not have to
-
verify that each and every read operation suceeds.</p>
-
<p> However, the non-error mode is more useful when checking to see
-
if a packet/segment/whatever has arrived.</p>
-
<p> The thrown error object will have the constant buffer_error set
-
to a non-false value.</p>
-
</dd>
-
<dt class='head--doc'>Example</dt>
-
<dd class='example'><pre><pre><code><span class='type'>void</span> read_callback<span class='delim'>(</span><span class='type'>int</span> i<span class='delim'>,</span> <span class='type'>string</span> new_data<span class='delim'>)</span>
-
<span class='delim'>{</span>
-
inbuffer->add<span class='delim'>(</span> new_data <span class='delim'>)</span><span class='delim'>;</span>
-
-
<span class='lang'>while</span><span class='delim'>(</span> IOBuffer packet <span class='delim'>=</span> inbuffer->read_hbuffer<span class='delim'>(</span>2<span class='delim'>)</span> <span class='delim'>)</span>
-
<span class='delim'>{</span>
-
packet->set_error_mode<span class='delim'>(</span>Buffer<span class='delim'>.</span>THROW_ERROR<span class='delim'>)</span><span class='delim'>;</span>
-
<span class='lang'>if</span><span class='delim'>(</span> <span class='type'>mixed</span> e <span class='delim'>=</span> <span class='lang'>catch</span><span class='delim'>(</span> handle_packet<span class='delim'>(</span> packet <span class='delim'>)</span> <span class='delim'>)</span> <span class='delim'>)</span>
-
<span class='lang'>if</span><span class='delim'>(</span> e->buffer_error <span class='delim'>)</span>
-
protocol_error<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span> <span class='comment'>// illegal data in packet</span>
-
<span class='lang'>else</span>
-
throw<span class='delim'>(</span>e<span class='delim'>)</span><span class='delim'>;</span> <span class='comment'>// the other code did something bad</span>
-
<span class='delim'>}</span>
-
<span class='delim'>}</span>
-
-
<span class='type'>void</span> handle_packet<span class='delim'>(</span> IOBuffer pack <span class='delim'>)</span>
-
<span class='delim'>{</span>
-
<span class='lang'>switch</span><span class='delim'>(</span> pack->read_int8<span class='delim'>(</span><span class='delim'>)</span> <span class='delim'>)</span>
-
<span class='delim'>{</span>
-
...
-
<span class='lang'>case</span> HEADER_FRAME<span class='delim'>:</span>
-
<span class='type'>int</span> num_headers <span class='delim'>=</span> pack->read_int32<span class='delim'>(</span><span class='delim'>)</span><span class='delim'>;</span>
-
<span class='lang'>for</span><span class='delim'>(</span> <span class='type'>int</span> i <span class='delim'>=</span> 0<span class='delim'>;</span> i<span class='delim'><</span>num_headers<span class='delim'>;</span> i++ <span class='delim'>)</span>
-
headers<span class='delim'>[</span>pack->read_hstring<span class='delim'>(</span>2<span class='delim'>)</span><span class='delim'>]</span> <span class='delim'>=</span> pack->read_hstring<span class='delim'>(</span>2<span class='delim'>)</span><span class='delim'>;</span>
-
...
-
<span class='delim'>}</span>
-
<span class='delim'>}</span>
-
</code></pre></pre></dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>sprintf</b></span>
-
</dt>
-
<dd><p><code><code class='object unresolved'>IOBuffer</code> <b><span class='method'>sprintf</span>(</b><code class='object unresolved'>strict_sprintf_format</code> <code class='argument'>format</code>, <code class='object unresolved'>sprintf_args</code> ... <code class='argument'>args</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Appends the output from <code>sprintf</code> at the end of the buffer.</p>
-
<p> This is somewhat faster than add(sprintf(...)) since no
-
intermediate string is created.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>sscanf</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>array</code> <b><span class='method'>sscanf</span>(</b><code class='datatype'>string(8bit)</code> <code class='argument'>format</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Reads data from the beginning of the buffer to match the
-
specifed format, then return an array with the matches.</p>
-
<p> The non-matching data will be left in the buffer.</p>
-
<p> See <code>array_sscanf</code> for more information.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>trim</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>trim</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Frees unused memory.</p>
-
<p> Note that calling this function excessively will slow things
-
down, since the data often has to be copied.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>This function could possibly throw an out-of-memory error
-
if the realloc fails to find a new (smaller) memory area.</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>try_read</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>string(8bit)</code> <b><span class='method'>try_read</span>(</b><code class='datatype'>int</code> <code class='argument'>len</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Attempt to read some data from the buffer.</p>
-
</dd>
-
<dt class='head--doc'><span id='p-len'></span>Parameter <code class='parameter'>len</code></dt>
-
<dd></dd><dd class='body--doc'><p>Read at most <code>len</code> bytes from the buffer.</p>
-
</dd>
-
<dt class='head--doc'>Returns</dt>
-
<dd class='body--doc'><p>If the buffer contains less than <code>len</code> bytes
-
of data, the entire buffer contents are returned.
-
Otherwise the first <code>len</code> bytes are returned.</p>
-
</dd>
-
<dt class='head--doc'>See also</dt>
-
<dd class='body--doc'><p><code>read()</code></p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>unread</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>int(0..)</code>|<code class='datatype'>int(-1..-1)</code> <b><span class='method'>unread</span>(</b><code class='datatype'>int(0..)</code> <code class='argument'>n</code><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Rewind the buffer <code>n</code> bytes.</p>
-
</dd>
-
<dt class='head--doc'>Returns</dt>
-
<dd class='body--doc'><p>This function returns how many more bytes of buffer is
-
available to rewind, or -1 on error.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>Unless you add new data to the buffer using any of the add
-
functions you can always rewind.</p>
-
<p> You can call <code>unread(0)</code> to see how much.</p>
-
</dd></dl>
-
<dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.IOBuffer.RewindKey</b></h2>
-
</dt><dd><dl class='group--doc'>
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>The return value of <code>IOBuffer.rewind_on_error()</code> and
-
<code>IOBuffer.rewind_key()</code></p>
-
<p> This object will cause the buffer to unwind to the position it was
-
at when the object was created either when it is released (when it
-
falls out of scope, explicit destruct does not count) or when
-
<code>rewind</code> is called, depending on which function was used to
-
create it.</p>
-
</dd></dl>
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>release</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>release</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Do not rewind if the object is released.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>This is equivalent to calling destruct() on the object</p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>rewind</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>rewind</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Rewinds the buffer explicitly.</p>
-
</dd>
-
<dt class='head--doc'>Note</dt>
-
<dd class='body--doc'><p>Destructs this <code>RewindKey</code></p>
-
</dd></dl>
-
-
-
<hr />
-
<dl class='group--doc'>
-
<dt class='head--type'><span class='homogen--type'>Method</span>
-
<span class='homogen--name'><b>update</b></span>
-
</dt>
-
<dd><p><code><code class='datatype'>void</code> <b><span class='method'>update</span>(</b><b>)</b></code></p></dd>
-
-
<dt class='head--doc'>Description</dt>
-
<dd class='body--doc'><p>Update the location the buffer will be rewound to to the current
-
position of the buffer.</p>
-
</dd></dl>
-
</dd></dl></dd></dl><dl><dt><h2 class='header'>Class <b class='ms datatype'>Stdio.NonblockingStream</b></h2>
-
</dt><dd><dl class='group--doc'>
-
<dt class='head--doc'>Description</dt>
+
<dd class='body--doc'><p>The Stdio.NonblockingStream API.</p> <p> This class exists purely for typing reasons.</p> <p> Use in types in place of <code>Stdio.File</code> where nonblocking and/or