Skip to content

Commit 28f1a89

Browse files
authored
Add an as_bytes function for the C-ABI (#750)
1 parent 0944a68 commit 28f1a89

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ All notable changes to MiniJinja are documented here.
1313
merge feature, and fixed enumeration behavior when non-map objects
1414
are attempted to be merged. #745
1515
- Added `mj_value_new_bytes` to the C-ABI. #749
16+
- Added `mj_value_as_bytes` to the C-ABI to borrow from strings or
17+
byte values. #750
1618

1719
## 2.8.0
1820

minijinja-cabi/example/hello.c

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <minijinja.h>
22
#include <stdio.h>
33
#include <assert.h>
4+
#include <string.h>
45

56
int main()
67
{
@@ -60,6 +61,14 @@ seq: {{ seq }}");
6061
mj_str_free(ervs);
6162
mj_value_decref(&erv);
6263

64+
// you can borrow utf-8 from strings, if they are strings.
65+
mj_value bv = mj_value_new_string("Hello");
66+
uintptr_t bvlen;
67+
const char *bvstr = mj_value_as_bytes(bv, &bvlen);
68+
assert(bvlen == 5);
69+
assert(memcmp(bvstr, "Hello", 5) == 0);
70+
mj_value_decref(&bv);
71+
6372
mj_env_free(env);
6473

6574
return 0;

minijinja-cabi/include/minijinja.h

+5
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ MINIJINJA_API void mj_syntax_config_default(struct mj_syntax_config *syntax);
252252
*/
253253
MINIJINJA_API bool mj_value_append(struct mj_value *slf, struct mj_value value);
254254

255+
/*
256+
If the value is a string or bytes, returns it the pointer
257+
*/
258+
MINIJINJA_API const char *mj_value_as_bytes(struct mj_value value, uintptr_t *len_out);
259+
255260
/*
256261
Extracts a float from the value
257262
*/

minijinja-cabi/src/utils.rs

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ impl<T> AbiResult for *mut T {
2121
}
2222
}
2323

24+
impl<T> AbiResult for *const T {
25+
fn err_value() -> Self {
26+
ptr::null()
27+
}
28+
}
29+
2430
impl AbiResult for u64 {
2531
fn err_value() -> Self {
2632
0

minijinja-cabi/src/value.rs

+17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::BTreeMap;
22
use std::ffi::{c_char, CStr, CString};
33
use std::mem::{transmute, ManuallyDrop};
44
use std::ops::Deref;
5+
use std::ptr;
56
use std::sync::Arc;
67

78
use minijinja::value::{Object, ValueIter, ValueKind};
@@ -284,6 +285,22 @@ ffi_fn! {
284285
}
285286
}
286287

288+
ffi_fn! {
289+
/// If the value is a string or bytes, returns it the pointer
290+
/// to it, and the length.
291+
///
292+
/// Note that strings are not null terminated. If you need that, use
293+
/// `mj_value_to_str` which will also stringify non string values.
294+
unsafe fn mj_value_as_bytes(_scope, value: mj_value, len_out: &mut usize) -> *const c_char {
295+
if let Some(bytes) = value.as_bytes() {
296+
*len_out = bytes.len();
297+
bytes.as_ptr() as *const c_char
298+
} else {
299+
ptr::null()
300+
}
301+
}
302+
}
303+
287304
ffi_fn! {
288305
/// Extracts an integer from the value
289306
unsafe fn mj_value_as_i64(_scope, value: mj_value) -> i64 {

0 commit comments

Comments
 (0)