@@ -172,56 +172,64 @@ std::shared_ptr<ArrayIter> Array::iterator()
172172ArrayIter::ArrayIter (PyArrayObject* np_array, std::shared_ptr<ArrayStreamHandler> stream_handler)
173173 : m_stream_handler(std::move(stream_handler))
174174{
175- resetIterator (np_array);
175+ // Create iterator
176+ m_iter = NpyIter_New (np_array,
177+ NPY_ITER_EXTERNAL_LOOP | NPY_ITER_READONLY | NPY_ITER_REFS_OK,
178+ NPY_KEEPORDER, NPY_NO_CASTING, NULL );
179+ if (!m_iter)
180+ throw pdal_error (" Unable to create numpy iterator." );
181+
182+ initIterator ();
176183}
177184
178- void ArrayIter::resetIterator (std::optional<PyArrayObject*> np_array = {} )
185+ void ArrayIter::initIterator ( )
179186{
180- std::optional<int > stream_chunk_size = std::nullopt ;
187+ // For a stream handler, first execute it to get the buffer populated and know the size of the data to iterate
188+ int64_t stream_chunk_size = 0 ;
181189 if (m_stream_handler) {
182190 stream_chunk_size = (*m_stream_handler)();
183- if (* stream_chunk_size == 0 ) {
191+ if (! stream_chunk_size) {
184192 m_done = true ;
185193 return ;
186194 }
187195 }
188196
189- if (np_array) {
190- // Init iterator
191- m_iter = NpyIter_New (np_array.value (),
192- NPY_ITER_EXTERNAL_LOOP | NPY_ITER_READONLY | NPY_ITER_REFS_OK,
193- NPY_KEEPORDER, NPY_NO_CASTING, NULL );
194- if (!m_iter)
195- throw pdal_error (" Unable to create numpy iterator." );
196- } else {
197- // Otherwise, reset the iterator to the initial state
198- if (NpyIter_Reset (m_iter, NULL ) != NPY_SUCCEED) {
199- NpyIter_Deallocate (m_iter);
200- throw pdal_error (" Unable to reset numpy iterator." );
201- }
202- }
203-
197+ // Initialize the iterator function
204198 char *itererr;
205199 m_iterNext = NpyIter_GetIterNext (m_iter, &itererr);
206200 if (!m_iterNext)
207201 {
208202 NpyIter_Deallocate (m_iter);
209- throw pdal_error (std::string (" Unable to create numpy iterator: " ) + itererr);
203+ m_iter = nullptr ;
204+ throw pdal_error (std::string (" Unable to retrieve iteration function from numpy iterator: " ) + itererr);
210205 }
211206 m_data = NpyIter_GetDataPtrArray (m_iter);
212207 m_stride = *NpyIter_GetInnerStrideArray (m_iter);
213208 m_size = *NpyIter_GetInnerLoopSizePtr (m_iter);
214209 if (stream_chunk_size) {
215- if (0 <= *stream_chunk_size && *stream_chunk_size <= m_size) {
216- m_size = *stream_chunk_size;
210+ // Ensure chunk size is valid and then limit iteration accordingly
211+ if (0 < stream_chunk_size && stream_chunk_size <= m_size) {
212+ m_size = stream_chunk_size;
217213 } else {
218214 throw pdal_error (std::string (" Stream chunk size not in the range of array length: " ) +
219- std::to_string (* stream_chunk_size));
215+ std::to_string (stream_chunk_size));
220216 }
221217 }
222218 m_done = false ;
223219}
224220
221+ void ArrayIter::resetIterator ()
222+ {
223+ // Reset the iterator to the initial state
224+ if (NpyIter_Reset (m_iter, NULL ) != NPY_SUCCEED) {
225+ NpyIter_Deallocate (m_iter);
226+ m_iter = nullptr ;
227+ throw pdal_error (" Unable to reset numpy iterator." );
228+ }
229+
230+ initIterator ();
231+ }
232+
225233ArrayIter::~ArrayIter ()
226234{
227235 if (m_iter != nullptr ) {
0 commit comments