Skip to content

Instantly share code, notes, and snippets.

@Boddlnagg
Created May 15, 2016 20:26
Show Gist options
  • Select an option

  • Save Boddlnagg/ada2a3c3227e3c922f326b2c6580d58d to your computer and use it in GitHub Desktop.

Select an option

Save Boddlnagg/ada2a3c3227e3c922f326b2c6580d58d to your computer and use it in GitHub Desktop.

Revisions

  1. Boddlnagg created this gist May 15, 2016.
    63 changes: 63 additions & 0 deletions hstring.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    use ::std::ptr;
    use ::winapi::*;
    use ::runtimeobject::*;

    pub struct HString(HSTRING);

    impl<'a> From<&'a str> for HString {
    fn from(s: &'a str) -> Self {
    let mut s16: Vec<_> = s.encode_utf16().collect();
    let len = s16.len();
    s16.push(0x0u16); // add null-terminator
    let mut hstr = HString(ptr::null_mut());
    let slice: &[u16] = &s16;
    let res = unsafe { WindowsCreateString(slice as *const _ as LPCWSTR, len as UINT32, &mut hstr.0) };
    assert!(res == S_OK);
    hstr
    }
    }

    impl HString {
    pub unsafe fn get(&self) -> HSTRING {
    self.0
    }

    pub unsafe fn wrap(hstr: HSTRING) -> HString {
    HString(hstr)
    }

    pub unsafe fn null() -> HString {
    HString(ptr::null_mut())
    }

    pub fn get_address(&mut self) -> &mut HSTRING {
    &mut self.0
    }
    }

    impl ToString for HString {
    fn to_string(&self) -> String {
    unsafe {
    let mut len = 0;
    let buf = WindowsGetStringRawBuffer(self.0, &mut len);
    let slice: &[u16] = ::std::slice::from_raw_parts(buf, len as usize);
    String::from_utf16_lossy(slice)
    }
    }
    }

    impl Drop for HString {
    fn drop(&mut self) {
    if !self.0.is_null() {
    unsafe { WindowsDeleteString(self.0) };
    }
    }
    }

    #[test]
    fn hstring_roundtrip() {
    let s = "12345";
    let hstr: HString = s.into();
    assert!(unsafe { WindowsGetStringLen(hstr.get()) } == 5);
    assert!(s == hstr.to_string());
    }