<commit_before>use core::libc::size_t;
use core::ptr::{null, to_mut_unsafe_ptr};
use core::cast::transmute;
use ll::*;

fn require_ok(code: lwc_error) {
    match code {
        lwc_error_ok => (),
        e => fail fmt!("lwc error: %?", e)
    }
}

pub struct LwcStringRef {
    priv string: *lwc_string,

    drop {
        rust_lwc_string_unref(self.string);
    }
}

pub fn from_rust_string(s: &str) -> LwcStringRef {
    let mut interned_string = null();
    do str::as_c_str(s) |cs| {
        let code = lwc_intern_string(cs, s.len() as size_t, to_mut_unsafe_ptr(&mut interned_string));
        require_ok(code);
    }

    assert interned_string.is_not_null();

    LwcStringRef {
        string: interned_string
    }
}

pub fn from_lwc_string(s: *lwc_string) -> LwcStringRef {
    rust_lwc_string_ref(s);
    LwcStringRef {
        string: s
    }
}

impl LwcStringRef {
    fn len() -> uint {
        unsafe {
            (*self.string).len as uint
        }
    }

    fn clone() -> LwcStringRef {
        from_lwc_string(self.string)
    }
}

impl LwcStringRef: ToStr {
    pure fn to_str() -> ~str {
        unsafe {
            // The string is located immediately after the handle
            let p: *c_char = transmute(self.string.offset(1));
            str::raw::from_c_str_len(p, self.len())
        }
    }
}

#[test]
fn smoke_test() {
    let s1 = from_rust_string("test");<commit_msg>Add a way to get a raw lwc_string from an LwcStringRef<commit_after>use core::libc::size_t;
use core::ptr::{null, to_mut_unsafe_ptr};
use core::cast::transmute;
use ll::*;

fn require_ok(code: lwc_error) {
    match code {
        lwc_error_ok => (),
        e => fail fmt!("lwc error: %?", e)
    }
}

pub struct LwcStringRef {
    priv string: *lwc_string,

    drop {
        rust_lwc_string_unref(self.string);
    }
}

pub fn from_rust_string(s: &str) -> LwcStringRef {
    let mut interned_string = null();
    do str::as_c_str(s) |cs| {
        let code = lwc_intern_string(cs, s.len() as size_t, to_mut_unsafe_ptr(&mut interned_string));
        require_ok(code);
    }

    assert interned_string.is_not_null();

    LwcStringRef {
        string: interned_string
    }
}

pub fn from_lwc_string(s: *lwc_string) -> LwcStringRef {
    rust_lwc_string_ref(s);
    LwcStringRef {
        string: s
    }
}

impl LwcStringRef {
    fn len() -> uint {
        unsafe {
            (*self.string).len as uint
        }
    }

    fn clone() -> LwcStringRef {
        from_lwc_string(self.string)
    }

    fn raw_reffed() -> *lwc_string {
        self.string
    }
}

impl LwcStringRef: ToStr {
    pure fn to_str() -> ~str {
        unsafe {
            // The string is located immediately after the handle
            let p: *c_char = transmute(self.string.offset(1));
            str::raw::from_c_str_len(p, self.len())
        }
    }
}

#[test]
fn smoke_test() {
    let s1 = from_rust_string("test");
{'fraction_non_alphanumeric': 0.12958519026396983, 'fraction_numerical': 0.0013712718546451835, 'mean_word_length': 2.4451003541912635, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2022693', 'n_tokens_mistral': 1074, 'n_tokens_neox': 1062, 'n_words': 221}