From 10a1310dbb89ec3c87848efb4cf34b46290f0030 Mon Sep 17 00:00:00 2001 From: "Simeon H.K. Fitch" Date: Tue, 23 May 2023 12:47:32 -0400 Subject: [PATCH] Convert `Feature` to use `foreign_types`. --- src/raster/gcp.rs | 7 +- src/spatial_ref/srs.rs | 4 +- src/vector/feature.rs | 151 +++++++++++++++++------------------------ src/vector/layer.rs | 29 +++----- 4 files changed, 80 insertions(+), 111 deletions(-) diff --git a/src/raster/gcp.rs b/src/raster/gcp.rs index a6c8a6bfc..483ead158 100644 --- a/src/raster/gcp.rs +++ b/src/raster/gcp.rs @@ -1,6 +1,7 @@ //! Raster ground control point support -use crate::spatial_ref::SpatialRef; +use foreign_types::ForeignTypeRef; +use crate::spatial_ref::SpatialRefRef; use crate::Dataset; impl Dataset { @@ -11,14 +12,14 @@ impl Dataset { /// the representation of ground control points, when embedded. /// /// See: [`GDALGetGCPSpatialRef`](https://gdal.org/api/raster_c_api.html#_CPPv420GDALGetGCPSpatialRef12GDALDatasetH) - pub fn gcp_spatial_ref(&self) -> Option { + pub fn gcp_spatial_ref(&self) -> Option<&SpatialRefRef> { let c_ptr = unsafe { gdal_sys::GDALGetGCPSpatialRef(self.c_dataset()) }; if c_ptr.is_null() { return None; } - unsafe { SpatialRef::from_c_obj(c_ptr) }.ok() + Some(unsafe { SpatialRefRef::from_ptr(c_ptr) }) } } diff --git a/src/spatial_ref/srs.rs b/src/spatial_ref/srs.rs index dc942b793..94570bfae 100644 --- a/src/spatial_ref/srs.rs +++ b/src/spatial_ref/srs.rs @@ -3,7 +3,7 @@ use gdal_sys::{self, OGRErr}; use std::ffi::{CStr, CString}; use std::ptr::{self}; use std::str::FromStr; -use foreign_types::{foreign_type, ForeignType}; +use foreign_types::{foreign_type, ForeignType, ForeignTypeRef}; use crate::errors::*; @@ -115,7 +115,9 @@ impl SpatialRef { Ok(unsafe { Self::from_ptr(c_obj) }) } } +} +impl SpatialRefRef { pub fn to_wkt(&self) -> Result { let mut c_wkt = ptr::null_mut(); let rv = unsafe { gdal_sys::OSRExportToWkt(self.as_ptr(), &mut c_wkt) }; diff --git a/src/vector/feature.rs b/src/vector/feature.rs index ab96655c7..b0fca3696 100644 --- a/src/vector/feature.rs +++ b/src/vector/feature.rs @@ -1,7 +1,7 @@ use crate::utils::{_last_null_pointer_err, _string, _string_array}; use crate::vector::geometry::Geometry; use crate::vector::{Defn, GeometryRef, LayerAccess}; -use gdal_sys::{self, OGRErr, OGRFeatureH, OGRFieldType}; +use gdal_sys::{self, OGRErr, OGRFieldType}; use libc::{c_char, c_double, c_int, c_longlong}; use std::convert::TryInto; use std::ffi::{CString, NulError}; @@ -12,12 +12,16 @@ use chrono::{DateTime, Datelike, FixedOffset, LocalResult, NaiveDate, TimeZone, use crate::errors::*; use std::slice; -use foreign_types::{ForeignType, ForeignTypeRef}; +use foreign_types::{foreign_type, ForeignType, ForeignTypeRef}; -/// OGR Feature -pub struct Feature<'a> { - _defn: &'a Defn, - c_feature: OGRFeatureH + +foreign_type! { + /// OGR Feature + pub unsafe type Feature<'a> { + type CType = libc::c_void; + type PhantomData = &'a (); + fn drop = gdal_sys::OGR_F_Destroy; + } } impl<'a> Feature<'a> { @@ -26,29 +30,7 @@ impl<'a> Feature<'a> { if c_feature.is_null() { return Err(_last_null_pointer_err("OGR_F_Create")); }; - Ok(Feature { - _defn: defn, - c_feature - }) - } - - /// Creates a new Feature by wrapping a C pointer and a Defn - /// - /// # Safety - /// This method operates on a raw C pointer - pub unsafe fn from_c_feature(defn: &'a Defn, c_feature: OGRFeatureH) -> Feature { - Feature { - _defn: defn, - c_feature, - } - } - - /// Returns the C wrapped pointer - /// - /// # Safety - /// This method returns a raw C pointer - pub unsafe fn c_feature(&self) -> OGRFeatureH { - self.c_feature + Ok(unsafe { Feature::from_ptr(c_feature) }) } // pub fn _lazy_feature_geometries(defn: &'a Defn) -> Vec { @@ -61,7 +43,7 @@ impl<'a> Feature<'a> { /// Returns the feature identifier, or `None` if none has been assigned. pub fn fid(&self) -> Option { - let fid = unsafe { gdal_sys::OGR_F_GetFID(self.c_feature) }; + let fid = unsafe { gdal_sys::OGR_F_GetFID(self.as_ptr()) }; if fid < 0 { None } else { @@ -89,59 +71,59 @@ impl<'a> Feature<'a> { /// /// If the field is null, returns `None`. fn field_from_id(&self, field_id: i32) -> Result> { - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_id) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_id) } != 0 { return Ok(None); } - let field_defn = unsafe { gdal_sys::OGR_F_GetFieldDefnRef(self.c_feature, field_id) }; + let field_defn = unsafe { gdal_sys::OGR_F_GetFieldDefnRef(self.as_ptr(), field_id) }; let field_type = unsafe { gdal_sys::OGR_Fld_GetType(field_defn) }; match field_type { OGRFieldType::OFTString => { - let rv = unsafe { gdal_sys::OGR_F_GetFieldAsString(self.c_feature, field_id) }; + let rv = unsafe { gdal_sys::OGR_F_GetFieldAsString(self.as_ptr(), field_id) }; Ok(Some(FieldValue::StringValue(_string(rv)))) } OGRFieldType::OFTStringList => { let rv = unsafe { - let ptr = gdal_sys::OGR_F_GetFieldAsStringList(self.c_feature, field_id); + let ptr = gdal_sys::OGR_F_GetFieldAsStringList(self.as_ptr(), field_id); _string_array(ptr) }; Ok(Some(FieldValue::StringListValue(rv))) } OGRFieldType::OFTReal => { - let rv = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.c_feature, field_id) }; + let rv = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.as_ptr(), field_id) }; Ok(Some(FieldValue::RealValue(rv))) } OGRFieldType::OFTRealList => { let rv = unsafe { let mut len: i32 = 0; let ptr = - gdal_sys::OGR_F_GetFieldAsDoubleList(self.c_feature, field_id, &mut len); + gdal_sys::OGR_F_GetFieldAsDoubleList(self.as_ptr(), field_id, &mut len); slice::from_raw_parts(ptr, len as usize).to_vec() }; Ok(Some(FieldValue::RealListValue(rv))) } OGRFieldType::OFTInteger => { - let rv = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.c_feature, field_id) }; + let rv = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.as_ptr(), field_id) }; Ok(Some(FieldValue::IntegerValue(rv))) } OGRFieldType::OFTIntegerList => { let rv = unsafe { let mut len: i32 = 0; let ptr = - gdal_sys::OGR_F_GetFieldAsIntegerList(self.c_feature, field_id, &mut len); + gdal_sys::OGR_F_GetFieldAsIntegerList(self.as_ptr(), field_id, &mut len); slice::from_raw_parts(ptr, len as usize).to_vec() }; Ok(Some(FieldValue::IntegerListValue(rv))) } OGRFieldType::OFTInteger64 => { - let rv = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.c_feature, field_id) }; + let rv = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.as_ptr(), field_id) }; Ok(Some(FieldValue::Integer64Value(rv))) } OGRFieldType::OFTInteger64List => { let rv = unsafe { let mut len: i32 = 0; let ptr = - gdal_sys::OGR_F_GetFieldAsInteger64List(self.c_feature, field_id, &mut len); + gdal_sys::OGR_F_GetFieldAsInteger64List(self.as_ptr(), field_id, &mut len); slice::from_raw_parts(ptr, len as usize).to_vec() }; Ok(Some(FieldValue::Integer64ListValue(rv))) @@ -166,7 +148,7 @@ impl<'a> Feature<'a> { fn field_idx_from_name>(&self, field_name: S) -> Result { let c_str_field_name = CString::new(field_name.as_ref())?; let field_id = - unsafe { gdal_sys::OGR_F_GetFieldIndex(self.c_feature, c_str_field_name.as_ptr()) }; + unsafe { gdal_sys::OGR_F_GetFieldIndex(self.as_ptr(), c_str_field_name.as_ptr()) }; if field_id == -1 { return Err(GdalError::InvalidFieldName { field_name: field_name.as_ref().to_string(), @@ -192,11 +174,11 @@ impl<'a> Feature<'a> { }); } - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -211,11 +193,11 @@ impl<'a> Feature<'a> { pub fn field_as_integer_by_name(&self, field_name: &str) -> Result> { let field_idx = self.field_idx_from_name(field_name)?; - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -230,11 +212,11 @@ impl<'a> Feature<'a> { pub fn field_as_integer64_by_name(&self, field_name: &str) -> Result> { let field_idx = self.field_idx_from_name(field_name)?; - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -254,11 +236,11 @@ impl<'a> Feature<'a> { }); } - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsInteger64(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -273,11 +255,11 @@ impl<'a> Feature<'a> { pub fn field_as_double_by_name(&self, field_name: &str) -> Result> { let field_idx = self.field_idx_from_name(field_name)?; - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -297,11 +279,11 @@ impl<'a> Feature<'a> { }); } - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.c_feature, field_idx) }; + let value = unsafe { gdal_sys::OGR_F_GetFieldAsDouble(self.as_ptr(), field_idx) }; Ok(Some(value)) } @@ -315,11 +297,11 @@ impl<'a> Feature<'a> { pub fn field_as_string_by_name(&self, field_name: &str) -> Result> { let field_idx = self.field_idx_from_name(field_name)?; - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.c_feature, field_idx) }); + let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.as_ptr(), field_idx) }); Ok(Some(value)) } @@ -338,11 +320,11 @@ impl<'a> Feature<'a> { }); } - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } - let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.c_feature, field_idx) }); + let value = _string(unsafe { gdal_sys::OGR_F_GetFieldAsString(self.as_ptr(), field_idx) }); Ok(Some(value)) } @@ -359,7 +341,7 @@ impl<'a> Feature<'a> { ) -> Result>> { let field_idx = self.field_idx_from_name(field_name)?; - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } @@ -382,7 +364,7 @@ impl<'a> Feature<'a> { }); } - if unsafe { gdal_sys::OGR_F_IsFieldNull(self.c_feature, field_idx) } != 0 { + if unsafe { gdal_sys::OGR_F_IsFieldNull(self.as_ptr(), field_idx) } != 0 { return Ok(None); } @@ -402,7 +384,7 @@ impl<'a> Feature<'a> { let success = unsafe { gdal_sys::OGR_F_GetFieldAsDateTime( - self.c_feature, + self.as_ptr(), field_id, &mut year, &mut month, @@ -449,17 +431,17 @@ impl<'a> Feature<'a> { /// Get the feature's geometry. pub fn geometry(&self) -> Option<&GeometryRef> { - if self._defn.geom_field_count() <= 0 { + if self.geom_field_count() <= 0 { return None; } - let c_geom = unsafe { gdal_sys::OGR_F_GetGeometryRef(self.c_feature) }; + let c_geom = unsafe { gdal_sys::OGR_F_GetGeometryRef(self.as_ptr()) }; Some(unsafe { GeometryRef::from_ptr(c_geom) }) } pub fn geometry_by_name(&self, field_name: &str) -> Result<&GeometryRef> { let c_str_field_name = CString::new(field_name)?; let idx = - unsafe { gdal_sys::OGR_F_GetGeomFieldIndex(self.c_feature, c_str_field_name.as_ptr()) }; + unsafe { gdal_sys::OGR_F_GetGeomFieldIndex(self.as_ptr(), c_str_field_name.as_ptr()) }; if idx == -1 { Err(GdalError::InvalidFieldName { field_name: field_name.to_string(), @@ -471,13 +453,13 @@ impl<'a> Feature<'a> { } pub fn geometry_by_index(&self, idx: usize) -> Result<&GeometryRef> { - if idx as isize >= self._defn.geom_field_count() { + if idx as i32 >= self.geom_field_count() { return Err(GdalError::InvalidFieldIndex { index: idx, method_name: "geometry_by_index", }); } - let c_geom = unsafe { gdal_sys::OGR_F_GetGeomFieldRef(self.c_feature, idx as i32) }; + let c_geom = unsafe { gdal_sys::OGR_F_GetGeomFieldRef(self.as_ptr(), idx as i32) }; if c_geom.is_null() { return Err(_last_null_pointer_err("OGR_F_GetGeomFieldRef")); } @@ -485,7 +467,7 @@ impl<'a> Feature<'a> { } pub fn create(&self, lyr: &L) -> Result<()> { - let rv = unsafe { gdal_sys::OGR_L_CreateFeature(lyr.c_layer(), self.c_feature) }; + let rv = unsafe { gdal_sys::OGR_L_CreateFeature(lyr.c_layer(), self.as_ptr()) }; if rv != OGRErr::OGRERR_NONE { return Err(GdalError::OgrError { err: rv, @@ -498,7 +480,7 @@ impl<'a> Feature<'a> { pub fn set_field_string(&self, field_name: &str, value: &str) -> Result<()> { let c_str_value = CString::new(value)?; let idx = self.field_idx_from_name(field_name)?; - unsafe { gdal_sys::OGR_F_SetFieldString(self.c_feature, idx, c_str_value.as_ptr()) }; + unsafe { gdal_sys::OGR_F_SetFieldString(self.as_ptr(), idx, c_str_value.as_ptr()) }; Ok(()) } @@ -516,13 +498,13 @@ impl<'a> Feature<'a> { // gdal-sys despite being constant. let c_value = c_str_ptrs.as_ptr() as *mut *mut c_char; let idx = self.field_idx_from_name(field_name)?; - unsafe { gdal_sys::OGR_F_SetFieldStringList(self.c_feature, idx, c_value) }; + unsafe { gdal_sys::OGR_F_SetFieldStringList(self.as_ptr(), idx, c_value) }; Ok(()) } pub fn set_field_double(&self, field_name: &str, value: f64) -> Result<()> { let idx = self.field_idx_from_name(field_name)?; - unsafe { gdal_sys::OGR_F_SetFieldDouble(self.c_feature, idx, value as c_double) }; + unsafe { gdal_sys::OGR_F_SetFieldDouble(self.as_ptr(), idx, value as c_double) }; Ok(()) } @@ -530,7 +512,7 @@ impl<'a> Feature<'a> { let idx = self.field_idx_from_name(field_name)?; unsafe { gdal_sys::OGR_F_SetFieldDoubleList( - self.c_feature, + self.as_ptr(), idx, value.len() as c_int, value.as_ptr(), @@ -541,7 +523,7 @@ impl<'a> Feature<'a> { pub fn set_field_integer(&self, field_name: &str, value: i32) -> Result<()> { let idx = self.field_idx_from_name(field_name)?; - unsafe { gdal_sys::OGR_F_SetFieldInteger(self.c_feature, idx, value as c_int) }; + unsafe { gdal_sys::OGR_F_SetFieldInteger(self.as_ptr(), idx, value as c_int) }; Ok(()) } @@ -549,7 +531,7 @@ impl<'a> Feature<'a> { let idx = self.field_idx_from_name(field_name)?; unsafe { gdal_sys::OGR_F_SetFieldIntegerList( - self.c_feature, + self.as_ptr(), idx, value.len() as c_int, value.as_ptr(), @@ -560,7 +542,7 @@ impl<'a> Feature<'a> { pub fn set_field_integer64(&self, field_name: &str, value: i64) -> Result<()> { let idx = self.field_idx_from_name(field_name)?; - unsafe { gdal_sys::OGR_F_SetFieldInteger64(self.c_feature, idx, value as c_longlong) }; + unsafe { gdal_sys::OGR_F_SetFieldInteger64(self.as_ptr(), idx, value as c_longlong) }; Ok(()) } @@ -568,7 +550,7 @@ impl<'a> Feature<'a> { let idx = self.field_idx_from_name(field_name)?; unsafe { gdal_sys::OGR_F_SetFieldInteger64List( - self.c_feature, + self.as_ptr(), idx, value.len() as c_int, value.as_ptr(), @@ -594,7 +576,7 @@ impl<'a> Feature<'a> { unsafe { gdal_sys::OGR_F_SetFieldDateTime( - self.c_feature, + self.as_ptr(), idx, year, month, @@ -639,7 +621,7 @@ impl<'a> Feature<'a> { } pub fn set_geometry(&mut self, geom: Geometry) -> Result<()> { - let rv = unsafe { gdal_sys::OGR_F_SetGeometry(self.c_feature, geom.as_ptr()) }; + let rv = unsafe { gdal_sys::OGR_F_SetGeometry(self.as_ptr(), geom.as_ptr()) }; if rv != OGRErr::OGRERR_NONE { return Err(GdalError::OgrError { err: rv, @@ -649,7 +631,11 @@ impl<'a> Feature<'a> { Ok(()) } pub fn field_count(&self) -> i32 { - unsafe { gdal_sys::OGR_F_GetFieldCount(self.c_feature) } + unsafe { gdal_sys::OGR_F_GetFieldCount(self.as_ptr()) } + } + + pub fn geom_field_count(&self) -> i32 { + unsafe { gdal_sys::OGR_F_GetGeomFieldCount(self.as_ptr()) } } pub fn fields(&self) -> FieldValueIterator { @@ -662,7 +648,6 @@ impl Debug for Feature<'_> { let fields = self.fields().collect::>(); f.debug_struct("Feature") .field("fid", &self.fid()) - .field("defn", &self._defn) .field("geometry", &self.geometry()) .field("fields", &fields) .finish() @@ -694,7 +679,7 @@ impl<'a> Iterator for FieldValueIterator<'a> { if idx < self.count { self.idx += 1; let field_defn = - unsafe { gdal_sys::OGR_F_GetFieldDefnRef(self.feature.c_feature, idx) }; + unsafe { gdal_sys::OGR_F_GetFieldDefnRef(self.feature.as_ptr(), idx) }; let field_name = unsafe { gdal_sys::OGR_Fld_GetNameRef(field_defn) }; let name = _string(field_name); let fv: Option<(String, Option)> = self @@ -720,14 +705,6 @@ impl<'a> Iterator for FieldValueIterator<'a> { } } -impl<'a> Drop for Feature<'a> { - fn drop(&mut self) { - unsafe { - gdal_sys::OGR_F_Destroy(self.c_feature); - } - } -} - #[derive(Clone, Debug, PartialEq)] pub enum FieldValue { IntegerValue(i32), diff --git a/src/vector/layer.rs b/src/vector/layer.rs index 36f3b462d..80c1fb373 100644 --- a/src/vector/layer.rs +++ b/src/vector/layer.rs @@ -6,7 +6,7 @@ use crate::vector::{Envelope, Feature, FieldValue, Geometry}; use crate::{dataset::Dataset, gdal_major_object::MajorObject}; use gdal_sys::{self, GDALMajorObjectH, OGRErr, OGRFieldDefnH, OGRFieldType, OGRLayerH}; use libc::c_int; -use std::mem::{ManuallyDrop, MaybeUninit}; +use std::mem::MaybeUninit; use std::ptr::null_mut; use std::{convert::TryInto, ffi::CString, marker::PhantomData}; use foreign_types::{ForeignType, ForeignTypeRef}; @@ -239,7 +239,7 @@ pub trait LayerAccess: Sized { if c_feature.is_null() { None } else { - Some(unsafe { Feature::from_c_feature(self.defn(), c_feature) }) + Some(unsafe { Feature::from_ptr(c_feature) }) } } @@ -257,7 +257,7 @@ pub trait LayerAccess: Sized { /// /// See: [SetFeature](https://gdal.org/doxygen/classOGRLayer.html#a681139bfd585b74d7218e51a32144283) fn set_feature(&self, feature: Feature) -> Result<()> { - unsafe { gdal_sys::OGR_L_SetFeature(self.c_layer(), feature.c_feature()) }; + unsafe { gdal_sys::OGR_L_SetFeature(self.c_layer(), feature.into_ptr()) }; Ok(()) } @@ -298,21 +298,16 @@ pub trait LayerAccess: Sized { Ok(()) } fn create_feature(&mut self, geometry: Geometry) -> Result<()> { - // `OGR_F_SetGeometryDirectly` takes ownership of the Geometry. - // According to https://doc.rust-lang.org/std/mem/fn.forget.html#relationship-with-manuallydrop - // `ManuallyDrop` is the suggested means of transferring memory management while - // robustly preventing a double-free. - let geometry = ManuallyDrop::new(geometry); let feature = Feature::new(self.defn())?; - let rv = unsafe { gdal_sys::OGR_F_SetGeometryDirectly(feature.c_feature(), geometry.as_ptr()) }; + let rv = unsafe { gdal_sys::OGR_F_SetGeometryDirectly(feature.as_ptr(), geometry.into_ptr()) }; if rv != OGRErr::OGRERR_NONE { return Err(GdalError::OgrError { err: rv, method_name: "OGR_F_SetGeometryDirectly", }); } - let rv = unsafe { gdal_sys::OGR_L_CreateFeature(self.c_layer(), feature.c_feature()) }; + let rv = unsafe { gdal_sys::OGR_L_CreateFeature(self.c_layer(), feature.as_ptr()) }; if rv != OGRErr::OGRERR_NONE { return Err(GdalError::OgrError { err: rv, @@ -509,9 +504,9 @@ pub trait LayerAccess: Sized { } pub struct FeatureIterator<'a> { - defn: &'a Defn, c_layer: OGRLayerH, size_hint: Option, + _lifetime: PhantomData<&'a ()> } impl<'a> Iterator for FeatureIterator<'a> { @@ -523,7 +518,7 @@ impl<'a> Iterator for FeatureIterator<'a> { if c_feature.is_null() { None } else { - Some(unsafe { Feature::from_c_feature(self.defn, c_feature) }) + Some(unsafe { Feature::from_ptr(c_feature) }) } } @@ -537,12 +532,11 @@ impl<'a> Iterator for FeatureIterator<'a> { impl<'a> FeatureIterator<'a> { pub(crate) fn _with_layer(layer: &'a L) -> Self { - let defn = layer.defn(); let size_hint = layer.try_feature_count().and_then(|s| s.try_into().ok()); Self { c_layer: unsafe { layer.c_layer() }, size_hint, - defn, + _lifetime: PhantomData } } } @@ -566,12 +560,7 @@ where return None; } - Some(unsafe { - // We have to convince the compiler that our `Defn` adheres to our iterator lifetime `<'a>` - let defn: &'a Defn = std::mem::transmute::<&'_ _, &'a _>(self.layer.defn()); - - Feature::from_c_feature(defn, c_feature) - }) + Some(unsafe { Feature::from_ptr( c_feature) }) } fn size_hint(&self) -> (usize, Option) {