Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C bindings #209

Closed
Stranger6667 opened this issue Jun 18, 2023 · 0 comments
Closed

C bindings #209

Stranger6667 opened this issue Jun 18, 2023 · 0 comments

Comments

@Stranger6667
Copy link
Owner

Stranger6667 commented Jun 18, 2023

We need C bindings to extend css-inline accessibility to other languages that can work via C.

TODO:

  • Decide on the public API. Likely it is better to expose inline_to, so the caller is always responsible for managing their memory (otherwise we need to provide a separate function to deallocate the buffer we allocate during inlining with the inline function)
  • Allow the end-user to configure the inlining process - not yet sure what is the best way to achieve this. E.g. it could be a struct that could be constructed from the C side.
  • Generate a header file with proper extern declarations (cbindgen or similar as a starting point?)
  • Document the bindings, specifically focusing on how the caller should manage memory when using this C API.
  • Write tests in C that ensure our C API works and include them in CI

Notes:

  • The bindings crate could live in bindings/c
  • Validate the input from the C side (pointers should be not null)
  • Maybe we can use some negative values to encode erroneous situations? (e.g. -1 for null pointers, -2 for invalid UTF-8, etc)
  • Avoid allocating anything on our side
  • Do not forget the null-terminators (\0) in the output.
  • Consider using a custom Write impl

It can roughly look like this:

use libc::{c_char, c_int, size_t};
use std::ffi::CStr;
use std::ptr;

#[no_mangle]
pub extern "C" fn inline_to(input: *const c_char, output: *mut c_char, output_size: size_t) -> c_int {
    let cstr = unsafe { CStr::from_ptr(input) }.to_str().expect("TODO: handle properly");
    // ... Inline impl via `CSSInliner::inline_to`
}

// `Write` impl for a buffer coming from the C side?
use std::io::{self, Write};

struct CBuffer {
    buffer: *mut c_char,
    buffer_size: size_t,
    pos: usize,
}

impl CBuffer {
    fn new(buffer: *mut c_char, buffer_size: size_t) -> Self {
        Self {
            buffer,
            buffer_size,
            pos: 0,
        }
    }
}


impl Write for CBuffer {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        ...
    }

    fn flush(&mut self) -> io::Result<()> {
        ...
    }
}

cc @lobziik

@Stranger6667 Stranger6667 changed the title Go bindings C bindings Jul 1, 2023
@Stranger6667 Stranger6667 pinned this issue Jul 1, 2023
@Stranger6667 Stranger6667 unpinned this issue Jul 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant