aboutsummaryrefslogtreecommitdiff
path: root/doc/ext_buffer.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ext_buffer.html')
-rw-r--r--doc/ext_buffer.html697
1 files changed, 697 insertions, 0 deletions
diff --git a/doc/ext_buffer.html b/doc/ext_buffer.html
new file mode 100644
index 00000000..7b874f57
--- /dev/null
+++ b/doc/ext_buffer.html
@@ -0,0 +1,697 @@
1<!DOCTYPE html>
2<html>
3<head>
4<title>String Buffer Library</title>
5<meta charset="utf-8">
6<meta name="Copyright" content="Copyright (C) 2005-2022">
7<meta name="Language" content="en">
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">
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>
21</head>
22<body>
23<div id="site">
24<a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
25</div>
26<div id="head">
27<h1>String Buffer Library</h1>
28</div>
29<div id="nav">
30<ul><li>
31<a href="luajit.html">LuaJIT</a>
32<ul><li>
33<a href="https://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
34</li><li>
35<a href="install.html">Installation</a>
36</li><li>
37<a href="running.html">Running</a>
38</li></ul>
39</li><li>
40<a href="extensions.html">Extensions</a>
41<ul><li>
42<a href="ext_ffi.html">FFI Library</a>
43<ul><li>
44<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
45</li><li>
46<a href="ext_ffi_api.html">ffi.* API</a>
47</li><li>
48<a href="ext_ffi_semantics.html">FFI Semantics</a>
49</li></ul>
50</li><li>
51<a class="current" href="ext_buffer.html">String Buffers</a>
52</li><li>
53<a href="ext_jit.html">jit.* Library</a>
54</li><li>
55<a href="ext_c_api.html">Lua/C API</a>
56</li><li>
57<a href="ext_profiler.html">Profiler</a>
58</li></ul>
59</li><li>
60<a href="status.html">Status</a>
61</li><li>
62<a href="faq.html">FAQ</a>
63</li><li>
64<a href="http://wiki.luajit.org/">Wiki <span class="ext">&raquo;</span></a>
65</li><li>
66<a href="https://luajit.org/list.html">Mailing List <span class="ext">&raquo;</span></a>
67</li></ul>
68</div>
69<div id="main">
70<p>
71The string buffer library allows <b>high-performance manipulation of
72string-like data</b>.
73</p>
74<p>
75Unlike Lua strings, which are constants, string buffers are
76<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data
77can be stored, formatted and encoded into a string buffer and later
78converted, extracted or decoded.
79</p>
80<p>
81The convenient string buffer API simplifies common string manipulation
82tasks, that would otherwise require creating many intermediate strings.
83String buffers improve performance by eliminating redundant memory
84copies, object creation, string interning and garbage collection
85overhead. In conjunction with the FFI library, they allow zero-copy
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>
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>
97</p>
98
99<h2 id="use">Using the String Buffer Library</h2>
100<p>
101The string buffer library is built into LuaJIT by default, but it's not
102loaded by default. Add this to the start of every Lua file that needs
103one of its functions:
104</p>
105<pre class="code">
106local buffer = require("string.buffer")
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>
118
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 may 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>
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 [,options]])<br>
179local buf = buffer.new([options])</tt></h3>
180<p>
181Creates a new buffer object.
182</p>
183<p>
184The optional <tt>size</tt> argument ensures a minimum initial buffer
185size. This is strictly an optimization when the required buffer size is
186known beforehand. The buffer space will grow as needed, in any case.
187</p>
188<p>
189The optional table <tt>options</tt> sets various
190<a href="#serialize_options">serialization options</a>.
191</p>
192
193<h3 id="buffer_reset"><tt>buf = buf:reset()</tt></h3>
194<p>
195Reset (empty) the buffer. The allocated buffer space is not freed and
196may be reused.
197</p>
198
199<h3 id="buffer_free"><tt>buf = buf:free()</tt></h3>
200<p>
201The buffer space of the buffer object is freed. The object itself
202remains intact, empty and may be reused.
203</p>
204<p>
205Note: you normally don't need to use this method. The garbage collector
206automatically frees the buffer space, when the buffer object is
207collected. Use this method, if you need to free the associated memory
208immediately.
209</p>
210
211<h2 id="write">Buffer Writers</h2>
212
213<h3 id="buffer_put"><tt>buf = buf:put([str|num|obj] [,…])</tt></h3>
214<p>
215Appends a string <tt>str</tt>, a number <tt>num</tt> or any object
216<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.
217Multiple arguments are appended in the given order.
218</p>
219<p>
220Appending a buffer to a buffer is possible and short-circuited
221internally. But it still involves a copy. Better combine the buffer
222writes to use a single buffer.
223</p>
224
225<h3 id="buffer_putf"><tt>buf = buf:putf(format, …)</tt></h3>
226<p>
227Appends the formatted arguments to the buffer. The <tt>format</tt>
228string supports the same options as <tt>string.format()</tt>.
229</p>
230
231<h3 id="buffer_putcdata"><tt>buf = buf:putcdata(cdata, len)</tt><span class="lib">FFI</span></h3>
232<p>
233Appends the given <tt>len</tt> number of bytes from the memory pointed
234to by the FFI <tt>cdata</tt> object to the buffer. The object needs to
235be convertible to a (constant) pointer.
236</p>
237
238<h3 id="buffer_set"><tt>buf = buf:set(str)<br>
239buf = buf:set(cdata, len)</tt><span class="lib">FFI</span></h3>
240<p>
241This method allows zero-copy consumption of a string or an FFI cdata
242object as a buffer. It stores a reference to the passed string
243<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer
244space originally allocated is freed. This is <i>not</i> an append
245operation, unlike the <tt>buf:put*()</tt> methods.
246</p>
247<p>
248After calling this method, the buffer behaves as if
249<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>
250had been called. However, the data is only referenced and not copied, as
251long as the buffer is only consumed.
252</p>
253<p>
254In case the buffer is written to later on, the referenced data is copied
255and the object reference is removed (copy-on-write semantics).
256</p>
257<p>
258The stored reference is an anchor for the garbage collector and keeps the
259originally passed string or FFI cdata object alive.
260</p>
261
262<h3 id="buffer_reserve"><tt>ptr, len = buf:reserve(size)</tt><span class="lib">FFI</span><br>
263<tt>buf = buf:commit(used)</tt><span class="lib">FFI</span></h3>
264<p>
265The <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of
266write space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI
267cdata pointer <tt>ptr</tt> that points to this space.
268</p>
269<p>
270The available length in bytes is returned in <tt>len</tt>. This is at
271least <tt>size</tt> bytes, but may be more to facilitate efficient
272buffer growth. You can either make use of the additional space or ignore
273<tt>len</tt> and only use <tt>size</tt> bytes.
274</p>
275<p>
276The <tt>commit</tt> method appends the <tt>used</tt> bytes of the
277previously returned write space to the buffer data.
278</p>
279<p>
280This pair of methods allows zero-copy use of C read-style APIs:
281</p>
282<pre class="code">
283local MIN_SIZE = 65536
284repeat
285 local ptr, len = buf:reserve(MIN_SIZE)
286 local n = C.read(fd, ptr, len)
287 if n == 0 then break end -- EOF.
288 if n &lt; 0 then error("read error") end
289 buf:commit(n)
290until false
291</pre>
292<p>
293The reserved write space is <i>not</i> initialized. At least the
294<tt>used</tt> bytes <b>must</b> be written to before calling the
295<tt>commit</tt> method. There's no need to call the <tt>commit</tt>
296method, if nothing is added to the buffer (e.g. on error).
297</p>
298
299<h2 id="read">Buffer Readers</h2>
300
301<h3 id="buffer_length"><tt>len = #buf</tt></h3>
302<p>
303Returns the current length of the buffer data in bytes.
304</p>
305
306<h3 id="buffer_concat"><tt>res = str|num|buf .. str|num|buf […]</tt></h3>
307<p>
308The Lua concatenation operator <tt>..</tt> also accepts buffers, just
309like strings or numbers. It always returns a string and not a buffer.
310</p>
311<p>
312Note that although this is supported for convenience, this thwarts one
313of the main reasons to use buffers, which is to avoid string
314allocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.
315</p>
316<p>
317Mixing this with unrelated objects that have a <tt>__concat</tt>
318metamethod may not work, since these probably only expect strings.
319</p>
320
321<h3 id="buffer_skip"><tt>buf = buf:skip(len)</tt></h3>
322<p>
323Skips (consumes) <tt>len</tt> bytes from the buffer up to the current
324length of the buffer data.
325</p>
326
327<h3 id="buffer_get"><tt>str, … = buf:get([len|nil] [,…])</tt></h3>
328<p>
329Consumes the buffer data and returns one or more strings. If called
330without arguments, the whole buffer data is consumed. If called with a
331number, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument
332consumes the remaining buffer space (this only makes sense as the last
333argument). Multiple arguments consume the buffer data in the given
334order.
335</p>
336<p>
337Note: a zero length or no remaining buffer data returns an empty string
338and not <tt>nil</tt>.
339</p>
340
341<h3 id="buffer_tostring"><tt>str = buf:tostring()<br>
342str = tostring(buf)</tt></h3>
343<p>
344Creates a string from the buffer data, but doesn't consume it. The
345buffer remains unchanged.
346</p>
347<p>
348Buffer objects also define a <tt>__tostring</tt> metamethod. This means
349buffers can be passed to the global <tt>tostring()</tt> function and
350many other functions that accept this in place of strings. The important
351internal uses in functions like <tt>io.write()</tt> are short-circuited
352to avoid the creation of an intermediate string object.
353</p>
354
355<h3 id="buffer_ref"><tt>ptr, len = buf:ref()</tt><span class="lib">FFI</span></h3>
356<p>
357Returns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that
358points to the buffer data. The length of the buffer data in bytes is
359returned in <tt>len</tt>.
360</p>
361<p>
362The returned pointer can be directly passed to C functions that expect a
363buffer and a length. You can also do bytewise reads
364(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes
365(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.
366</p>
367<p>
368In conjunction with the <tt>skip</tt> method, this allows zero-copy use
369of C write-style APIs:
370</p>
371<pre class="code">
372repeat
373 local ptr, len = buf:ref()
374 if len == 0 then break end
375 local n = C.write(fd, ptr, len)
376 if n &lt; 0 then error("write error") end
377 buf:skip(n)
378until n >= len
379</pre>
380<p>
381Unlike Lua strings, buffer data is <i>not</i> implicitly
382zero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that
383expect zero-terminated strings. If you're not using <tt>len</tt>, then
384you're doing something wrong.
385</p>
386
387<h2 id="serialize">Serialization of Lua Objects</h2>
388<p>
389The following functions and methods allow <b>high-speed serialization</b>
390(encoding) of a Lua object into a string and decoding it back to a Lua
391object. This allows convenient storage and transport of <b>structured
392data</b>.
393</p>
394<p>
395The encoded data is in an <a href="#serialize_format">internal binary
396format</a>. The data can be stored in files, binary-transparent
397databases or transmitted to other LuaJIT instances across threads,
398processes or networks.
399</p>
400<p>
401Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or
402server-class system, even when serializing many small objects. Decoding
403speed is mostly constrained by object creation cost.
404</p>
405<p>
406The serializer handles most Lua types, common FFI number types and
407nested structures. Functions, thread objects, other FFI cdata and full
408userdata cannot be serialized (yet).
409</p>
410<p>
411The encoder serializes nested structures as trees. Multiple references
412to a single object will be stored separately and create distinct objects
413after decoding. Circular references cause an error.
414</p>
415
416<h3 id="serialize_methods">Serialization Functions and Methods</h3>
417
418<h3 id="buffer_encode"><tt>str = buffer.encode(obj)<br>
419buf = buf:encode(obj)</tt></h3>
420<p>
421Serializes (encodes) the Lua object <tt>obj</tt>. The stand-alone
422function returns a string <tt>str</tt>. The buffer method appends the
423encoding to the buffer.
424</p>
425<p>
426<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't
427need to be a Lua table.
428</p>
429<p>
430This function may throw an error when attempting to serialize
431unsupported object types, circular references or deeply nested tables.
432</p>
433
434<h3 id="buffer_decode"><tt>obj = buffer.decode(str)<br>
435obj = buf:decode()</tt></h3>
436<p>
437The stand-alone function de-serializes (decodes) the string
438<tt>str</tt>, the buffer method de-serializes one object from the
439buffer. Both return a Lua object <tt>obj</tt>.
440</p>
441<p>
442The returned object may be any of the supported Lua types &mdash;
443even <tt>nil</tt>.
444</p>
445<p>
446This function may throw an error when fed with malformed or incomplete
447encoded data. The stand-alone function throws when there's left-over
448data after decoding a single top-level object. The buffer method leaves
449any left-over data in the buffer.
450</p>
451<p>
452Attempting to de-serialize an FFI type will throw an error, if the FFI
453library is not built-in or has not been loaded, yet.
454</p>
455
456<h3 id="serialize_options">Serialization Options</h3>
457<p>
458The <tt>options</tt> table passed to <tt>buffer.new()</tt> may contain
459the following members (all optional):
460</p>
461<ul>
462<li>
463<tt>dict</tt> is a Lua table holding a <b>dictionary of strings</b> that
464commonly occur as table keys of objects you are serializing. These keys
465are compactly encoded as indexes during serialization. A well chosen
466dictionary saves space and improves serialization performance.
467</li>
468<li>
469<tt>metatable</tt> is a Lua table holding a <b>dictionary of metatables</b>
470for the table objects you are serializing.
471</li>
472</ul>
473<p>
474<tt>dict</tt> needs to be an array of strings and <tt>metatable</tt> needs
475to be an array of tables. Both starting at index 1 and without holes (no
476<tt>nil</tt> inbetween). The tables are anchored in the buffer object and
477internally modified into a two-way index (don't do this yourself, just pass
478a plain array). The tables must not be modified after they have been passed
479to <tt>buffer.new()</tt>.
480</p>
481<p>
482The <tt>dict</tt> and <tt>metatable</tt> tables used by the encoder and
483decoder must be the same. Put the most common entries at the front. Extend
484at the end to ensure backwards-compatibility &mdash; older encodings can
485then still be read. You may also set some indexes to <tt>false</tt> to
486explicitly drop backwards-compatibility. Old encodings that use these
487indexes will throw an error when decoded.
488</p>
489<p>
490Metatables that are not found in the <tt>metatable</tt> dictionary are
491ignored when encoding. Decoding returns a table with a <tt>nil</tt>
492metatable.
493</p>
494<p>
495Note: parsing and preparation of the options table is somewhat
496expensive. Create a buffer object only once and recycle it for multiple
497uses. Avoid mixing encoder and decoder buffers, since the
498<tt>buf:set()</tt> method frees the already allocated buffer space:
499</p>
500<pre class="code">
501local options = {
502 dict = { "commonly", "used", "string", "keys" },
503}
504local buf_enc = buffer.new(options)
505local buf_dec = buffer.new(options)
506
507local function encode(obj)
508 return buf_enc:reset():encode(obj):get()
509end
510
511local function decode(str)
512 return buf_dec:set(str):decode()
513end
514</pre>
515
516<h3 id="serialize_stream">Streaming Serialization</h3>
517<p>
518In some contexts, it's desirable to do piecewise serialization of large
519datasets, also known as <i>streaming</i>.
520</p>
521<p>
522This serialization format can be safely concatenated and supports streaming.
523Multiple encodings can simply be appended to a buffer and later decoded
524individually:
525</p>
526<pre class="code">
527local buf = buffer.new()
528buf:encode(obj1)
529buf:encode(obj2)
530local copy1 = buf:decode()
531local copy2 = buf:decode()
532</pre>
533<p>
534Here's how to iterate over a stream:
535</p>
536<pre class="code">
537while #buf ~= 0 do
538 local obj = buf:decode()
539 -- Do something with obj.
540end
541</pre>
542<p>
543Since the serialization format doesn't prepend a length to its encoding,
544network applications may need to transmit the length, too.
545</p>
546
547<h3 id="serialize_format">Serialization Format Specification</h3>
548<p>
549This serialization format is designed for <b>internal use</b> by LuaJIT
550applications. Serialized data is upwards-compatible and portable across
551all supported LuaJIT platforms.
552</p>
553<p>
554It's an <b>8-bit binary format</b> and not human-readable. It uses e.g.
555embedded zeroes and stores embedded Lua string objects unmodified, which
556are 8-bit-clean, too. Encoded data can be safely concatenated for
557streaming and later decoded one top-level object at a time.
558</p>
559<p>
560The encoding is reasonably compact, but tuned for maximum performance,
561not for minimum space usage. It compresses well with any of the common
562byte-oriented data compression algorithms.
563</p>
564<p>
565Although documented here for reference, this format is explicitly
566<b>not</b> intended to be a 'public standard' for structured data
567interchange across computer languages (like JSON or MessagePack). Please
568do not use it as such.
569</p>
570<p>
571The specification is given below as a context-free grammar with a
572top-level <tt>object</tt> as the starting point. Alternatives are
573separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.
574Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are
575either plain hex numbers, encoded as bytes, or have a <tt>.format</tt>
576suffix.
577</p>
578<pre>
579object → nil | false | true
580 | null | lightud32 | lightud64
581 | int | num | tab | tab_mt
582 | int64 | uint64 | complex
583 | string
584
585nil → 0x00
586false → 0x01
587true → 0x02
588
589null → 0x03 // NULL lightuserdata
590lightud32 → 0x04 data.I // 32 bit lightuserdata
591lightud64 → 0x05 data.L // 64 bit lightuserdata
592
593int → 0x06 int.I // int32_t
594num → 0x07 double.L
595
596tab → 0x08 // Empty table
597 | 0x09 h.U h*{object object} // Key/value hash
598 | 0x0a a.U a*object // 0-based array
599 | 0x0b a.U a*object h.U h*{object object} // Mixed
600 | 0x0c a.U (a-1)*object // 1-based array
601 | 0x0d a.U (a-1)*object h.U h*{object object} // Mixed
602tab_mt → 0x0e (index-1).U tab // Metatable dict entry
603
604int64 → 0x10 int.L // FFI int64_t
605uint64 → 0x11 uint.L // FFI uint64_t
606complex → 0x12 re.L im.L // FFI complex
607
608string → (0x20+len).U len*char.B
609 | 0x0f (index-1).U // String dict entry
610
611.B = 8 bit
612.I = 32 bit little-endian
613.L = 64 bit little-endian
614.U = prefix-encoded 32 bit unsigned number n:
615 0x00..0xdf → n.B
616 0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B
617 0x1fe0.. → 0xff n.I
618</pre>
619
620<h2 id="error">Error handling</h2>
621<p>
622Many of the buffer methods can throw an error. Out-of-memory or usage
623errors are best caught with an outer wrapper for larger parts of code.
624There's not much one can do after that, anyway.
625</p>
626<p>
627OTOH you may want to catch some errors individually. Buffer methods need
628to receive the buffer object as the first argument. The Lua colon-syntax
629<tt>obj:method()</tt> does that implicitly. But to wrap a method with
630<tt>pcall()</tt>, the arguments need to be passed like this:
631</p>
632<pre class="code">
633local ok, err = pcall(buf.encode, buf, obj)
634if not ok then
635 -- Handle error in err.
636end
637</pre>
638
639<h2 id="ffi_caveats">FFI caveats</h2>
640<p>
641The string buffer library has been designed to work well together with
642the FFI library. But due to the low-level nature of the FFI library,
643some care needs to be taken:
644</p>
645<p>
646First, please remember that FFI pointers are zero-indexed. The space
647returned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the
648returned pointer and ends before <tt>len</tt> bytes after that.
649</p>
650<p>
651I.e. the first valid index is <tt>ptr[0]</tt> and the last valid index
652is <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid
653index at all. The returned pointer may even be <tt>NULL</tt>.
654</p>
655<p>
656The space pointed to by the returned pointer is only valid as long as
657the buffer is not modified in any way (neither append, nor consume, nor
658reset, etc.). The pointer is also not a GC anchor for the buffer object
659itself.
660</p>
661<p>
662Buffer data is only guaranteed to be byte-aligned. Casting the returned
663pointer to a data type with higher alignment may cause unaligned
664accesses. It depends on the CPU architecture whether this is allowed or
665not (it's always OK on x86/x64 and mostly OK on other modern
666architectures).
667</p>
668<p>
669FFI pointers or references do not count as GC anchors for an underlying
670object. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is
671anchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by
672<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset
673creates a new pointer, even when the offset is zero. In this case, you
674need to make sure there's still a reference to the original array as
675long as its contents are in use by the buffer.
676</p>
677<p>
678Even though each LuaJIT VM instance is single-threaded (but you can
679create multiple VMs), FFI data structures can be accessed concurrently.
680Be careful when reading/writing FFI cdata from/to buffers to avoid
681concurrent accesses or modifications. In particular, the memory
682referenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified
683while buffer readers are working on it. Shared, but read-only memory
684mappings of files are OK, but only if the file does not change.
685</p>
686<br class="flush">
687</div>
688<div id="foot">
689<hr class="hide">
690Copyright &copy; 2005-2022
691<span class="noprint">
692&middot;
693<a href="contact.html">Contact</a>
694</span>
695</div>
696</body>
697</html>