Skip to content

Commit 5fa3635

Browse files
committed
Add support direct writing to the buffer with buffer.addSize() and buffer.prepBuffer()
1 parent 87a99cf commit 5fa3635

File tree

3 files changed

+71
-22
lines changed

3 files changed

+71
-22
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ you.
8686
| API | Support |
8787
|-----------------------------|---------------------------------------|
8888
| Lua C API (`lua_*`) | 🎉 100% coverage<sup>†</sup> (92/92) |
89-
| Auxilary Library (`luaL_*`) | 80% coverage (40/48) |
89+
| Auxilary Library (`luaL_*`) | 🤩 84% coverage (42/48) |
9090
| LuaJIT Extensions | *No plans to implement.* |
9191

9292
*†: Coroutine yield/resume is not yet part of the public `zig-luajit` Zig API, see [#6][ISSUE-6].*
@@ -225,7 +225,7 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
225225
|----------------------------|-------------------------------------|
226226
| `luaL_addchar` | ☑️ `buffer.addChar()`|
227227
| `luaL_addlstring` ||
228-
| `luaL_addsize` ||
228+
| `luaL_addsize` | ☑️ `buffer.addSize()`|
229229
| `luaL_addstring` ||
230230
| `luaL_addvalue` ||
231231
| `luaL_argcheck` | ☑️📢 `lua.checkArgument()` |
@@ -261,7 +261,7 @@ The `zig-luajit` project has not yet reached the 1.0 release, the API is subject
261261
| `luaL_optlstring` | ☑️📢 `lua.checkLStringOptional()` |
262262
| `luaL_optnumber` | ☑️📢 `lua.checkNumberOptional()` |
263263
| `luaL_optstring` | ☑️📢 `lua.checkStringOptional()` |
264-
| `luaL_prepbuffer` ||
264+
| `luaL_prepbuffer` | ☑️ `buffer.prepBuffer()` |
265265
| `luaL_pushresult` | ☑️ `buffer.pushResult()` |
266266
| `luaL_ref` | ☑️ `lua.ref()` |
267267
| `luaL_unref` | ☑️ `lua.unref()` |

src/lual_api.zig

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
/// Stack Behavior: `[-0, +0, m]`
1111
pub fn addLString(buffer: *Buffer, s: [*]const u8, l: usize) void;
1212

13-
/// Adds to the buffer B a string of length n previously copied to the buffer area.
14-
///
15-
/// From: `void luaL_addsize(luaL_Buffer *B, size_t n);`
16-
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_addsize
17-
/// Stack Behavior: `[-0, +0, m]`
18-
pub fn addSize(buffer: *Buffer, n: usize) void;
19-
2013
/// Adds the zero-terminated string pointed to by s to the buffer B.
2114
/// The string may not contain embedded zeros.
2215
///
@@ -42,15 +35,6 @@ pub fn addValue(buffer: *Buffer) void;
4235
/// Stack Behavior: `[-0, +0, -]`
4336
pub fn newState() ?*Lua;
4437

45-
/// Returns an address to a space of size LUAL_BUFFERSIZE where you can copy a string to be added to buffer B.
46-
/// After copying the string into this space you must call luaL_addsize with the size of the string to actually
47-
/// add it to the buffer.
48-
///
49-
/// From: `char *luaL_prepbuffer(luaL_Buffer *B);`
50-
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_prepbuffer
51-
/// Stack Behavior: `[-0, +0, -]`
52-
pub fn prepBuffer(buffer: *Buffer) [*]u8;
53-
5438
/// Generates an error with a message like "location: bad argument narg to 'func' (tname expected, got rt)",
5539
/// where location is produced by luaL_where, func is the name of the current function,
5640
/// and rt is the type name of the actual argument.

src/root.zig

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,9 +2483,7 @@ pub const Lua = opaque {
24832483
var ptr_copy = ptr;
24842484

24852485
if (@intFromPtr(ptr) >= @intFromPtr(&buffer.buffer) + c.LUAL_BUFFERSIZE) {
2486-
const extra = c.luaL_prepbuffer(@ptrCast(buffer));
2487-
assert(extra != null);
2488-
ptr_copy = extra;
2486+
ptr_copy = buffer.prepBuffer();
24892487
}
24902488

24912489
// We can assert buffer.p is non-null here since prepbuffer guarantees it
@@ -2499,6 +2497,48 @@ pub const Lua = opaque {
24992497
}
25002498
}
25012499

2500+
/// Prepares writable space in the buffer.
2501+
///
2502+
/// Used to provide direct writing of data. The caller **MUST** call `buffer.addSize()` after writing content
2503+
/// to the returned address of memory. If you do not call `buffer.addSize()` then the content will not be added
2504+
/// to the result of the Buffer.
2505+
/// ```
2506+
/// var space = buffer.prepBuffer();
2507+
/// @memcpy(space, "Hello", 5);
2508+
/// buffer.addSize(5); // Required when directly writing
2509+
///
2510+
/// Returns a pointer to space of size `BufferSize` bytes.
2511+
///
2512+
/// From: `char *luaL_prepbuffer(luaL_Buffer *B);`
2513+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_prepbuffer
2514+
/// Stack Behavior: `[-0, +0, -]`
2515+
pub fn prepBuffer(buffer: *Buffer) [*]u8 {
2516+
assert(buffer.p != null and buffer.L != null); // You must use `Lua.initBuffer(&Lua.Buffer)` before calling `Lua.Buffer.prepBuffer()`.
2517+
2518+
const ptr: ?[*]u8 = @ptrCast(c.luaL_prepbuffer(@ptrCast(buffer)));
2519+
assert(ptr != null);
2520+
return ptr.?;
2521+
}
2522+
2523+
/// Adds to the buffer a string of length `n` previously copied to the buffer area. Callers should write to the
2524+
/// buffer area returned from `prepBuffer()`.
2525+
///
2526+
/// From: `void luaL_addsize(luaL_Buffer *B, size_t n);`
2527+
/// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_addsize
2528+
/// Stack Behavior: `[-0, +0, m]`
2529+
pub fn addSize(buffer: *Buffer, n: usize) void {
2530+
assert(buffer.p != null and buffer.L != null); // You must use `Lua.initBuffer(&Lua.Buffer)` before calling `Lua.Buffer.addSize()`.
2531+
2532+
if (buffer.p) |ptr| {
2533+
buffer.p = ptr + n;
2534+
} else {
2535+
std.debug.panic(
2536+
"Failed to buffer.addSize('{d}'): the buffer is not initialized, `buffer.p` is null.\n",
2537+
.{n},
2538+
);
2539+
}
2540+
}
2541+
25022542
/// Finishes the use of the buffer leaving the final string on the top of the stack.
25032543
///
25042544
/// From: `void luaL_pushresult(luaL_Buffer *B);`
@@ -4789,3 +4829,28 @@ test "Buffer should handle very long string" {
47894829
try std.testing.expect(lua.isString(-1));
47904830
try std.testing.expectEqualStrings("0123456789" ** 25_600, try lua.toLString(-1));
47914831
}
4832+
4833+
test "Buffer can be created by direct writes to the buffer" {
4834+
const lua = try Lua.init(std.testing.allocator);
4835+
defer lua.deinit();
4836+
4837+
var b: Lua.Buffer = .{};
4838+
lua.initBuffer(&b);
4839+
var p = b.prepBuffer();
4840+
p[0] = 'H';
4841+
p += 1;
4842+
p[0] = 'e';
4843+
p += 1;
4844+
p[0] = 'l';
4845+
p += 1;
4846+
p[0] = 'l';
4847+
p += 1;
4848+
p[0] = 'o';
4849+
p += 1;
4850+
b.addSize(5);
4851+
b.pushResult();
4852+
4853+
try std.testing.expectEqual(1, lua.getTop());
4854+
try std.testing.expect(lua.isString(-1));
4855+
try std.testing.expectEqualStrings("Hello", try lua.toLString(-1));
4856+
}

0 commit comments

Comments
 (0)