use std::ops::Deref;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use libc::size_t;
-use crate::dav::context::DavContext;
-use crate::dav::ffi;
+use crate::dav::{ffi, utils};
use crate::dav::ffi::{DavReadFunc, DavSeekFunc, DavWriteFunc};
use crate::dav::session::{get_session_error, DavError, Session};
}
}
-fn cstr2str(cstr: *const c_char) -> String {
- if cstr.is_null() {
- String::new()
- } else {
- unsafe {
- CStr::from_ptr(cstr)
- .to_string_lossy()
- .into_owned()
- }
- }
-}
-
impl<'a> ResourceRef<'a> {
pub fn name(&self) -> String {
unsafe {
- cstr2str((*self.ptr).name)
+ utils::cstr2str((*self.ptr).name)
}
}
pub fn path(&self) -> String {
unsafe {
- cstr2str((*self.ptr).path)
+ utils::cstr2str((*self.ptr).path)
}
}
pub fn href(&self) -> String {
unsafe {
- cstr2str((*self.ptr).href)
+ utils::cstr2str((*self.ptr).href)
}
}
pub fn content_type(&self) -> String {
unsafe {
- cstr2str((*self.ptr).contenttype)
+ utils::cstr2str((*self.ptr).contenttype)
}
}
--- /dev/null
+use std::ffi::{c_char, CStr};
+use std::slice;
+
+pub fn cstr2str(cstr: *const c_char) -> String {
+ if cstr.is_null() {
+ String::new()
+ } else {
+ unsafe {
+ CStr::from_ptr(cstr)
+ .to_string_lossy()
+ .into_owned()
+ }
+ }
+}
+
+pub unsafe fn cstr_len2str<'a>(ptr: *const c_char, len: usize) -> String {
+ if ptr.is_null() || len == 0 {
+ return String::new();
+ }
+
+ let bytes = slice::from_raw_parts(ptr as *const u8, len);
+ let result = str::from_utf8(bytes);
+ if let Ok(str) = result {
+ String::from(str)
+ } else {
+ String::new()
+ }
+}
\ No newline at end of file
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+#![allow(dead_code)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
use crate::dav::ffi;
+use crate::dav::ffi::DavXmlNodeType;
+use crate::dav::utils::{cstr2str, cstr_len2str};
+
+pub struct XmlNode<'a> {
+ pub base: XmlNodeRef<'a>
+}
-pub struct XmlNode {
+pub struct XmlNodeRef<'a> {
pub ptr: *mut ffi::DavXmlNode,
-}
\ No newline at end of file
+ _marker: PhantomData<&'a XmlNode<'a>>,
+}
+
+impl<'a> Deref for XmlNode<'a> {
+ type Target = XmlNodeRef<'a>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.base
+ }
+}
+
+
+impl<'a> XmlNodeRef<'a> {
+ fn from_ptr(ptr: *mut ffi::DavXmlNode) -> XmlNodeRef<'a > {
+ XmlNodeRef { ptr, _marker: PhantomData }
+ }
+
+ pub fn parent(&self) -> Option<XmlNodeRef<'_>> {
+ unsafe {
+ if !(*self.ptr).parent.is_null() {
+ return Some(XmlNodeRef::from_ptr((*self.ptr).parent))
+ }
+ }
+ None
+ }
+
+ pub fn prev(&self) -> Option<XmlNodeRef<'_>> {
+ unsafe {
+ if !(*self.ptr).prev.is_null() {
+ return Some(XmlNodeRef::from_ptr((*self.ptr).prev))
+ }
+ }
+ None
+ }
+
+ pub fn next(&self) -> Option<XmlNodeRef<'_>> {
+ unsafe {
+ if !(*self.ptr).next.is_null() {
+ return Some(XmlNodeRef::from_ptr((*self.ptr).next))
+ }
+ }
+ None
+ }
+
+ pub fn first_child(&self) -> Option<XmlNodeRef<'_>> {
+ unsafe {
+ if !(*self.ptr).children.is_null() {
+ return Some(XmlNodeRef::from_ptr((*self.ptr).children))
+ }
+ }
+ None
+ }
+
+ pub fn node_type(&self) -> DavXmlNodeType {
+ unsafe {
+ (*self.ptr).node_type
+ }
+ }
+
+ pub fn namespace(&self) -> String {
+ unsafe {
+ cstr2str((*self.ptr).namespace)
+ }
+ }
+
+ pub fn name(&self) -> String {
+ unsafe {
+ cstr2str((*self.ptr).name)
+ }
+ }
+
+ pub fn has_content(&self) -> bool {
+ unsafe {
+ (*self.ptr).contentlength > 0
+ }
+ }
+
+ pub fn content(&self) -> String {
+ unsafe {
+ cstr_len2str((*self.ptr).content, (*self.ptr).contentlength)
+ }
+ }
+}