aboutsummaryrefslogtreecommitdiff
path: root/doc/ext_buffer.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/ext_buffer.html457
1 files changed, 404 insertions, 53 deletions
diff --git a/doc/ext_buffer.html b/doc/ext_buffer.html
index 455c298d..94af757d 100644
--- a/doc/ext_buffer.html
+++ b/doc/ext_buffer.html
@@ -1,19 +1,30 @@
1<!DOCTYPE html> 1<!DOCTYPE html>
2<html> 2<html>
3<head> 3<head>
4<title>String Buffers</title> 4<title>String Buffer Library</title>
5<meta charset="utf-8"> 5<meta charset="utf-8">
6<meta name="Copyright" content="Copyright (C) 2005-2021"> 6<meta name="Copyright" content="Copyright (C) 2005-2021">
7<meta name="Language" content="en"> 7<meta name="Language" content="en">
8<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> 8<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
9<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> 9<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
10<style type="text/css">
11.lib {
12 vertical-align: middle;
13 margin-left: 5px;
14 padding: 0 5px;
15 font-size: 60%;
16 border-radius: 5px;
17 background: #c5d5ff;
18 color: #000;
19}
20</style>
10</head> 21</head>
11<body> 22<body>
12<div id="site"> 23<div id="site">
13<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a> 24<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
14</div> 25</div>
15<div id="head"> 26<div id="head">
16<h1>String Buffers</h1> 27<h1>String Buffer Library</h1>
17</div> 28</div>
18<div id="nav"> 29<div id="nav">
19<ul><li> 30<ul><li>
@@ -57,31 +68,35 @@
57</div> 68</div>
58<div id="main"> 69<div id="main">
59<p> 70<p>
60
61The string buffer library allows <b>high-performance manipulation of 71The string buffer library allows <b>high-performance manipulation of
62string-like data</b>. 72string-like data</b>.
63
64</p> 73</p>
65<p> 74<p>
66
67Unlike Lua strings, which are constants, string buffers are 75Unlike Lua strings, which are constants, string buffers are
68<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data 76<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data
69can be stored, formatted and encoded into a string buffer and later 77can be stored, formatted and encoded into a string buffer and later
70converted, decoded or extracted. 78converted, extracted or decoded.
71
72</p> 79</p>
73<p> 80<p>
74
75The convenient string buffer API simplifies common string manipulation 81The convenient string buffer API simplifies common string manipulation
76tasks, that would otherwise require creating many intermediate strings. 82tasks, that would otherwise require creating many intermediate strings.
77String buffers improve performance by eliminating redundant memory 83String buffers improve performance by eliminating redundant memory
78copies, object creation, string interning and garbage collection 84copies, object creation, string interning and garbage collection
79overhead. In conjunction with the FFI library, they allow zero-copy 85overhead. In conjunction with the FFI library, they allow zero-copy
80operations. 86operations.
87</p>
88<p>
89The string buffer libary also includes a high-performance
90<a href="serialize">serializer</a> for Lua objects.
91</p>
81 92
93<h2 id="wip" style="color:#ff0000">Work in Progress</h2>
94<p>
95<b style="color:#ff0000">This library is a work in progress. More
96functionality will be added soon.</b>
82</p> 97</p>
83 98
84<h2 id="load">Using the String Buffer Library</h2> 99<h2 id="use">Using the String Buffer Library</h2>
85<p> 100<p>
86The string buffer library is built into LuaJIT by default, but it's not 101The string buffer library is built into LuaJIT by default, but it's not
87loaded by default. Add this to the start of every Lua file that needs 102loaded by default. Add this to the start of every Lua file that needs
@@ -90,137 +105,406 @@ one of its functions:
90<pre class="code"> 105<pre class="code">
91local buffer = require("string.buffer") 106local buffer = require("string.buffer")
92</pre> 107</pre>
108<p>
109The convention for the syntax shown on this page is that <tt>buffer</tt>
110refers to the buffer library and <tt>buf</tt> refers to an individual
111buffer object.
112</p>
113<p>
114Please note the difference between a Lua function call, e.g.
115<tt>buffer.new()</tt> (with a dot) and a Lua method call, e.g.
116<tt>buf:reset()</tt> (with a colon).
117</p>
93 118
94<h2 id="wip" style="color:#ff0000">Work in Progress</h2> 119<h3 id="buffer_object">Buffer Objects</h3>
120<p>
121A buffer object is a garbage-collected Lua object. After creation with
122<tt>buffer.new()</tt>, it can (and should) be reused for many operations.
123When the last reference to a buffer object is gone, it will eventually
124be freed by the garbage collector, along with the allocated buffer
125space.
126</p>
127<p>
128Buffers operate like a FIFO (first-in first-out) data structure. Data
129can be appended (written) to the end of the buffer and consumed (read)
130from the front of the buffer. These operations can be freely mixed.
131</p>
132<p>
133The buffer space that holds the characters is managed automatically
134&mdash; it grows as needed and already consumed space is recycled. Use
135<tt>buffer.new(size)</tt> and <tt>buf:free()</tt>, if you need more
136control.
137</p>
138<p>
139The maximum size of a single buffer is the same as the maximum size of a
140Lua string, which is slightly below two gigabytes. For huge data sizes,
141neither strings nor buffers are the right data structure &mdash; use the
142FFI library to directly map memory or files up to the virtual memory
143limit of your OS.
144</p>
95 145
146<h3 id="buffer_overview">Buffer Method Overview</h3>
147<ul>
148<li>
149The <tt>buf:put*()</tt>-like methods append (write) characters to the
150end of the buffer.
151</li>
152<li>
153The <tt>buf:get*()</tt>-like methods consume (read) characters from the
154front of the buffer.
155</li>
156<li>
157Other methods, like <tt>buf:tostring()</tt> only read the buffer
158contents, but don't change the buffer.
159</li>
160<li>
161The <tt>buf:set()</tt> method allows zero-copy consumption of a string
162or an FFI cdata object as a buffer.
163</li>
164<li>
165The FFI-specific methods allow zero-copy read/write-style operations or
166modifying the buffer contents in-place. Please check the
167<a href="#ffi_caveats">FFI caveats</a> below, too.
168</li>
169<li>
170Methods that don't need to return anything specific, return the buffer
171object itself as a convenience. This allows method chaining, e.g.:
172<tt>buf:reset():encode(obj)</tt> or <tt>buf:skip(len):get()</tt>
173</li>
174</ul>
175
176<h2 id="create">Buffer Creation and Management</h2>
177
178<h3 id="buffer_new"><tt>local buf = buffer.new([size])</tt></h3>
179<p>
180Creates a new buffer object.
181</p>
96<p> 182<p>
183The optional <tt>size</tt> argument ensures a minimum initial buffer
184size. This is strictly an optimization for cases where the required
185buffer size is known beforehand.
186</p>
97 187
98<b style="color:#ff0000">This library is a work in progress. More 188<h3 id="buffer_reset"><tt>buf = buf:reset()</tt></h3>
99functions will be added soon.</b> 189<p>
190Reset (empty) the buffer. The allocated buffer space is not freed and
191may be reused.
192</p>
100 193
194<h3 id="buffer_free"><tt>buf = buf:free()</tt></h3>
195<p>
196The buffer space of the buffer object is freed. The object itself
197remains intact, empty and it may be reused.
198</p>
199<p>
200Note: you normally don't need to use this method. The garbage collector
201automatically frees the buffer space, when the buffer object is
202collected. Use this method, if you need to free the associated memory
203immediately.
101</p> 204</p>
102 205
103<h2 id="serialize">Serialization of Lua Objects</h2> 206<h2 id="write">Buffer Writers</h2>
207
208<h3 id="buffer_put"><tt>buf = buf:put([str|num|obj] [, ...])</tt></h3>
209<p>
210Appends a string <tt>str</tt>, a number <tt>num</tt> or any object
211<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.
212Multiple arguments are appended in the given order.
213</p>
214<p>
215Appending a buffer to a buffer is possible and short-circuited
216internally. But it still involves a copy. Better combine the buffer
217writes to use a single buffer.
218</p>
219
220<h3 id="buffer_putf"><tt>buf = buf:putf(format, ...)</tt></h3>
221<p>
222Appends the formatted arguments to the buffer. The <tt>format</tt>
223string supports the same options as <tt>string.format()</tt>.
224</p>
225
226<h3 id="buffer_putcdata"><tt>buf = buf:putcdata(cdata, len)</tt><span class="lib">FFI</span></h3>
104<p> 227<p>
228Appends the given <tt>len</tt> number of bytes from the memory pointed
229to by the FFI <tt>cdata</tt> object to the buffer. The object needs to
230be convertible to a (constant) pointer.
231</p>
232
233<h3 id="buffer_set"><tt>buf = buf:set(str)<br>
234buf = buf:set(cdata, len)</tt><span class="lib">FFI</span></h3>
235<p>
236This method allows zero-copy consumption of a string or an FFI cdata
237object as a buffer. It stores a reference to the passed string
238<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer
239space originally allocated is freed. This is <i>not</i> an append
240operation, unlike the <tt>buf:put*()</tt> methods.
241</p>
242<p>
243After calling this method, the buffer behaves as if
244<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>
245had been called. However, the data is only referenced and not copied, as
246long as the buffer is only consumed.
247</p>
248<p>
249In case the buffer is written to later on, the referenced data is copied
250and the object reference is removed (copy-on-write semantics).
251</p>
252<p>
253The stored reference is an anchor for the garbage collector and keeps the
254originally passed string or FFI cdata object alive.
255</p>
256
257<h3 id="buffer_reserve"><tt>ptr, len = buf:reserve(size)</tt><span class="lib">FFI</span><br>
258<tt>buf = buf:commit(used)</tt><span class="lib">FFI</span></h3>
259<p>
260The <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of
261write space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI
262cdata pointer <tt>ptr</tt> that points to this space.
263</p>
264<p>
265The available length in bytes is returned in <tt>len</tt>. This is at
266least <tt>size</tt> bytes, but may be more to facilitate efficient
267buffer growth. You can either make use of the additional space or ignore
268<tt>len</tt> and only use <tt>size</tt> bytes.
269</p>
270<p>
271The <tt>commit</tt> method appends the <tt>used</tt> bytes of the
272previously returned write space to the buffer data.
273</p>
274<p>
275This pair of methods allows zero-copy use of C read-style APIs:
276</p>
277<pre class="code">
278local MIN_SIZE = 65536
279repeat
280 local ptr, len = buf:reserve(MIN_SIZE)
281 local n = C.read(fd, ptr, len)
282 if n == 0 then break end -- EOF.
283 if n &lt; 0 then error("read error") end
284 buf:commit(n)
285until false
286</pre>
287<p>
288The reserved write space is <i>not</i> initialized. At least the
289<tt>used</tt> bytes <b>must</b> be written to before calling the
290<tt>commit</tt> method. There's no need to call the <tt>commit</tt>
291method, if nothing is added to the buffer (e.g. on error).
292</p>
293
294<h2 id="read">Buffer Readers</h2>
295
296<h3 id="buffer_length"><tt>len = #buf</tt></h3>
297<p>
298Returns the current length of the buffer data in bytes.
299</p>
300
301<h3 id="buffer_concat"><tt>res = str|num|buf .. str|num|buf [...]</tt></h3>
302<p>
303The Lua concatenation operator <tt>..</tt> also accepts buffers, just
304like strings or numbers. It always returns a string and not a buffer.
305</p>
306<p>
307Note that although this is supported for convenience, this thwarts one
308of the main reasons to use buffers, which is to avoid string
309allocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.
310</p>
311<p>
312Mixing this with unrelated objects that have a <tt>__concat</tt>
313metamethod may not work, since these probably only expect strings.
314</p>
315
316<h3 id="buffer_skip"><tt>buf = buf:skip(len)</tt></h3>
317<p>
318Skips (consumes) <tt>len</tt> bytes from the buffer up to the current
319length of the buffer data.
320</p>
321
322<h3 id="buffer_get"><tt>str, ... = buf:get([len|nil] [,...])</tt></h3>
323<p>
324Consumes the buffer data and returns one or more strings. If called
325without arguments, the whole buffer data is consumed. If called with a
326number, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument
327consumes the remaining buffer space (this only makes sense as the last
328argument). Multiple arguments consume the buffer data in the given
329order.
330</p>
331<p>
332Note: a zero length or no remaining buffer data returns an empty string
333and not <tt>nil</tt>.
334</p>
105 335
336<h3 id="buffer_tostring"><tt>str = buf:tostring()<br>
337str = tostring(buf)</tt></h3>
338<p>
339Creates a string from the buffer data, but doesn't consume it. The
340buffer remains unchanged.
341</p>
342<p>
343Buffer objects also define a <tt>__tostring</tt> metamethod. This means
344buffers can be passed to the global <tt>tostring()</tt> function and
345many other functions that accept this in place of strings. The important
346internal uses in functions like <tt>io.write()</tt> are short-circuited
347to avoid the creation of an intermediate string object.
348</p>
349
350<h3 id="buffer_ref"><tt>ptr, len = buf:ref()</tt><span class="lib">FFI</span></h3>
351<p>
352Returns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that
353points to the buffer data. The length of the buffer data in bytes is
354returned in <tt>len</tt>.
355</p>
356<p>
357The returned pointer can be directly passed to C functions that expect a
358buffer and a length. You can also do bytewise reads
359(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes
360(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.
361</p>
362<p>
363In conjunction with the <tt>skip</tt> method, this allows zero-copy use
364of C write-style APIs:
365</p>
366<pre class="code">
367repeat
368 local ptr, len = buf:ref()
369 if len == 0 then break end
370 local n = C.write(fd, ptr, len)
371 if n &lt; 0 then error("write error") end
372 buf:skip(n)
373until n >= len
374</pre>
375<p>
376Unlike Lua strings, buffer data is <i>not</i> implicitly
377zero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that
378expect zero-terminated strings. If you're not using <tt>len</tt>, then
379you're doing something wrong.
380</p>
381
382<h2 id="serialize">Serialization of Lua Objects</h2>
383<p>
106The following functions and methods allow <b>high-speed serialization</b> 384The following functions and methods allow <b>high-speed serialization</b>
107(encoding) of a Lua object into a string and decoding it back to a Lua 385(encoding) of a Lua object into a string and decoding it back to a Lua
108object. This allows convenient storage and transport of <b>structured 386object. This allows convenient storage and transport of <b>structured
109data</b>. 387data</b>.
110
111</p> 388</p>
112<p> 389<p>
113
114The encoded data is in an <a href="#serialize_format">internal binary 390The encoded data is in an <a href="#serialize_format">internal binary
115format</a>. The data can be stored in files, binary-transparent 391format</a>. The data can be stored in files, binary-transparent
116databases or transmitted to other LuaJIT instances across threads, 392databases or transmitted to other LuaJIT instances across threads,
117processes or networks. 393processes or networks.
118
119</p> 394</p>
120<p> 395<p>
121
122Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or 396Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or
123server-class system, even when serializing many small objects. Decoding 397server-class system, even when serializing many small objects. Decoding
124speed is mostly constrained by object creation cost. 398speed is mostly constrained by object creation cost.
125
126</p> 399</p>
127<p> 400<p>
128
129The serializer handles most Lua types, common FFI number types and 401The serializer handles most Lua types, common FFI number types and
130nested structures. Functions, thread objects, other FFI cdata, full 402nested structures. Functions, thread objects, other FFI cdata, full
131userdata and associated metatables cannot be serialized (yet). 403userdata and associated metatables cannot be serialized (yet).
132
133</p> 404</p>
134<p> 405<p>
135
136The encoder serializes nested structures as trees. Multiple references 406The encoder serializes nested structures as trees. Multiple references
137to a single object will be stored separately and create distinct objects 407to a single object will be stored separately and create distinct objects
138after decoding. Circular references cause an error. 408after decoding. Circular references cause an error.
139
140
141</p> 409</p>
142 410
143<h3 id="buffer_encode"><tt>str = buffer.encode(obj)</tt></h3> 411<h3 id="serialize_methods">Serialization Functions and Methods</h3>
144<p>
145
146Serializes (encodes) the Lua object <tt>obj</tt> into the string
147<tt>str</tt>.
148 412
413<h3 id="buffer_encode"><tt>str = buffer.encode(obj)<br>
414buf = buf:encode(obj)</tt></h3>
415<p>
416Serializes (encodes) the Lua object <tt>obj</tt>. The stand-alone
417function returns a string <tt>str</tt>. The buffer method appends the
418encoding to the buffer.
149</p> 419</p>
150<p> 420<p>
151
152<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't 421<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't
153need to be a Lua table. 422need to be a Lua table.
154
155</p> 423</p>
156<p> 424<p>
157
158This function may throw an error when attempting to serialize 425This function may throw an error when attempting to serialize
159unsupported object types, circular references or deeply nested tables. 426unsupported object types, circular references or deeply nested tables.
160
161</p> 427</p>
162 428
163<h3 id="buffer_decode"><tt>obj = buffer.decode(str)</tt></h3> 429<h3 id="buffer_decode"><tt>obj = buffer.decode(str)<br>
430obj = buf:decode()</tt></h3>
164<p> 431<p>
165 432The stand-alone function de-serializes (decodes) the string
166De-serializes (decodes) the string <tt>str</tt> into the Lua object 433<tt>str</tt>, the buffer method de-serializes one object from the
167<tt>obj</tt>. 434buffer. Both return a Lua object <tt>obj</tt>.
168
169</p> 435</p>
170<p> 436<p>
171
172The returned object may be any of the supported Lua types &mdash; 437The returned object may be any of the supported Lua types &mdash;
173even <tt>nil</tt>. 438even <tt>nil</tt>.
174
175</p> 439</p>
176<p> 440<p>
177
178This function may throw an error when fed with malformed or incomplete 441This function may throw an error when fed with malformed or incomplete
179encoded data. The standalone function throws when there's left-over data 442encoded data. The stand-alone function throws when there's left-over
180after decoding a single top-level object. 443data after decoding a single top-level object. The buffer method leaves
181 444any left-over data in the buffer.
182</p> 445</p>
183 446
184<h2 id="serialize_format">Serialization Format Specification</h2> 447<h3 id="serialize_stream">Streaming Serialization</h3>
448<p>
449In some contexts, it's desirable to do piecewise serialization of large
450datasets, also known as <i>streaming</i>.
451</p>
452<p>
453This serialization format can be safely concatenated and supports streaming.
454Multiple encodings can simply be appended to a buffer and later decoded
455individually:
456</p>
457<pre class="code">
458local buf = buffer.new()
459buf:encode(obj1)
460buf:encode(obj2)
461local copy1 = buf:decode()
462local copy2 = buf:decode()
463</pre>
185<p> 464<p>
465Here's how to iterate over a stream:
466</p>
467<pre class="code">
468while #buf ~= 0 do
469 local obj = buf:decode()
470 -- Do something with obj.
471end
472</pre>
473<p>
474Since the serialization format doesn't prepend a length to its encoding,
475network applications may need to transmit the length, too.
476</p>
186 477
478<h3 id="serialize_format">Serialization Format Specification</h3>
479<p>
187This serialization format is designed for <b>internal use</b> by LuaJIT 480This serialization format is designed for <b>internal use</b> by LuaJIT
188applications. Serialized data is upwards-compatible and portable across 481applications. Serialized data is upwards-compatible and portable across
189all supported LuaJIT platforms. 482all supported LuaJIT platforms.
190
191</p> 483</p>
192<p> 484<p>
193
194It's an <b>8-bit binary format</b> and not human-readable. It uses e.g. 485It's an <b>8-bit binary format</b> and not human-readable. It uses e.g.
195embedded zeroes and stores embedded Lua string objects unmodified, which 486embedded zeroes and stores embedded Lua string objects unmodified, which
196are 8-bit-clean, too. Encoded data can be safely concatenated for 487are 8-bit-clean, too. Encoded data can be safely concatenated for
197streaming and later decoded one top-level object at a time. 488streaming and later decoded one top-level object at a time.
198
199</p> 489</p>
200<p> 490<p>
201
202The encoding is reasonably compact, but tuned for maximum performance, 491The encoding is reasonably compact, but tuned for maximum performance,
203not for minimum space usage. It compresses well with any of the common 492not for minimum space usage. It compresses well with any of the common
204byte-oriented data compression algorithms. 493byte-oriented data compression algorithms.
205
206</p> 494</p>
207<p> 495<p>
208
209Although documented here for reference, this format is explicitly 496Although documented here for reference, this format is explicitly
210<b>not</b> intended to be a 'public standard' for structured data 497<b>not</b> intended to be a 'public standard' for structured data
211interchange across computer languages (like JSON or MessagePack). Please 498interchange across computer languages (like JSON or MessagePack). Please
212do not use it as such. 499do not use it as such.
213
214</p> 500</p>
215<p> 501<p>
216
217The specification is given below as a context-free grammar with a 502The specification is given below as a context-free grammar with a
218top-level <tt>object</tt> as the starting point. Alternatives are 503top-level <tt>object</tt> as the starting point. Alternatives are
219separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats. 504separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.
220Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are 505Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are
221either plain hex numbers, encoded as bytes, or have a <tt>.format</tt> 506either plain hex numbers, encoded as bytes, or have a <tt>.format</tt>
222suffix. 507suffix.
223
224</p> 508</p>
225<pre> 509<pre>
226object → nil | false | true 510object → nil | false | true
@@ -261,6 +545,73 @@ string → (0x20+len).U len*char.B
261 0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B 545 0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
262 0x1fe0.. → 0xff n.I 546 0x1fe0.. → 0xff n.I
263</pre> 547</pre>
548
549<h2 id="error">Error handling</h2>
550<p>
551Many of the buffer methods can throw an error. Out-of-memory or usage
552errors are best caught with an outer wrapper for larger parts of code.
553There's not much one can do after that, anyway.
554</p>
555<p>
556OTOH you may want to catch some errors individually. Buffer methods need
557to receive the buffer object as the first argument. The Lua colon-syntax
558<tt>obj:method()</tt> does that implicitly. But to wrap a method with
559<tt>pcall()</tt>, the arguments need to be passed like this:
560</p>
561<pre class="code">
562local ok, err = pcall(buf.encode, buf, obj)
563if not ok then
564 -- Handle error in err.
565end
566</pre>
567
568<h2 id="ffi_caveats">FFI caveats</h2>
569<p>
570The string buffer library has been designed to work well together with
571the FFI library. But due to the low-level nature of the FFI library,
572some care needs to be taken:
573</p>
574<p>
575First, please remember that FFI pointers are zero-indexed. The space
576returned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the
577returned pointer and ends before <tt>len</tt> bytes after that.
578</p>
579<p>
580I.e. the first valid index is <tt>ptr[0]</tt> and the last valid index
581is <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid
582index at all. The returned pointer may even be <tt>NULL</tt>.
583</p>
584<p>
585The space pointed to by the returned pointer is only valid as long as
586the buffer is not modified in any way (neither append, nor consume, nor
587reset, etc.). The pointer is also not a GC anchor for the buffer object
588itself.
589</p>
590<p>
591Buffer data is only guaranteed to be byte-aligned. Casting the returned
592pointer to a data type with higher alignment may cause unaligned
593accesses. It depends on the CPU architecture whether this is allowed or
594not (it's always OK on x86/x64 and mostly OK on other modern
595architectures).
596</p>
597<p>
598FFI pointers or references do not count as GC anchors for an underlying
599object. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is
600anchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by
601<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset
602creates a new pointer, even when the offset is zero. In this case, you
603need to make sure there's still a reference to the original array as
604long as its contents are in use by the buffer.
605</p>
606<p>
607Even though each LuaJIT VM instance is single-threaded (but you can
608create multiple VMs), FFI data structures can be accessed concurrently.
609Be careful when reading/writing FFI cdata from/to buffers to avoid
610concurrent accesses or modifications. In particular, the memory
611referenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified
612while buffer readers are working on it. Shared, but read-only memory
613mappings of files are OK, but only if the file does not change.
614</p>
264<br class="flush"> 615<br class="flush">
265</div> 616</div>
266<div id="foot"> 617<div id="foot">