From 4bc05eae68782690056bc9ad8ae23bdf76689d00 Mon Sep 17 00:00:00 2001
From: Stefan Knoblich <stkn@openisdn.net>
Date: Sat, 1 Jun 2013 15:20:51 +0200
Subject: [PATCH] FreeTDM: Add span iterator

Part of my ongoing effort to split ftdm_io.c into more manageable pieces.

This change (along with others in the future) allows decoupling of the
span registry and its users, in preparation of moving all span related
functions and data structures into ftdm_span.c.

Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
---
 libs/freetdm/src/ftdm_io.c                    | 14 ++++++++++++++
 libs/freetdm/src/include/freetdm.h            |  6 ++++++
 libs/freetdm/src/include/private/ftdm_types.h |  1 +
 3 files changed, 21 insertions(+)

diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index cbafb09593..0ff1628a2d 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -4438,6 +4438,16 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_get_iterator(ftdm_iterator_type_t type, ftdm_
 	return iter;
 }
 
+FT_DECLARE(ftdm_iterator_t *) ftdm_get_span_iterator(ftdm_iterator_t *iter)
+{
+	if (!(iter = ftdm_get_iterator(FTDM_ITERATOR_SPANS, iter))) {
+		return NULL;
+	}
+
+	iter->pvt.hashiter = hashtable_first(globals.span_hash);
+	return iter;
+}
+
 FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter)
 {
 	if (!span->chan_count) {
@@ -4457,6 +4467,7 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter)
 
 	switch (iter->type) {
 	case FTDM_ITERATOR_VARS:
+	case FTDM_ITERATOR_SPANS:
 		if (!iter->pvt.hashiter) {
 			return NULL;
 		}
@@ -4492,6 +4503,9 @@ FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter)
 		hashtable_this(iter->pvt.hashiter, &key, NULL, &val);
 		/* I decided to return the key instead of the value since the value can be retrieved using the key */
 		return (void *)key;
+	case FTDM_ITERATOR_SPANS:
+		hashtable_this(iter->pvt.hashiter, &key, NULL, &val);
+		return (void *)val;
 	case FTDM_ITERATOR_CHANS:
 		ftdm_assert_return(iter->pvt.chaniter.index, NULL, "channel iterator index cannot be zero!\n");
 		ftdm_assert_return(iter->pvt.chaniter.index <= iter->pvt.chaniter.span->chan_count, NULL, "channel iterator index bigger than span chan count!\n");
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index f430ae263e..1a035655d2 100755
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -1589,6 +1589,7 @@ FT_DECLARE(ftdm_status_t) ftdm_usrmsg_set_raw_data(ftdm_usrmsg_t *usrmsg, void *
 
 /*! \brief Get iterator current value (depends on the iterator type)
  *  \note Channel iterators return a pointer to ftdm_channel_t
+ *        Span iterators return a pointer to ftdm_span_t
  *        Variable iterators return a pointer to the variable name (not the variable value)
  */
 FT_DECLARE(void *) ftdm_iterator_current(ftdm_iterator_t *iter);
@@ -1725,6 +1726,11 @@ FT_DECLARE(const char *) ftdm_span_get_name(const ftdm_span_t *span);
  */
 FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *span, ftdm_iterator_t *iter);
 
+/*! \brief Get iterator for spans
+ *  \param iter Optional iterator. You can reuse an old iterator (not previously freed) to avoid the extra allocation of a new iterator.
+ */
+FT_DECLARE(ftdm_iterator_t *) ftdm_get_span_iterator(ftdm_iterator_t *iter);
+
 /*! 
  * \brief Execute a text command. The text command output will be returned and must be free'd 
  *
diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h
index c92164dd8c..b6786d1a55 100755
--- a/libs/freetdm/src/include/private/ftdm_types.h
+++ b/libs/freetdm/src/include/private/ftdm_types.h
@@ -360,6 +360,7 @@ typedef ftdm_status_t (*ftdm_channel_sig_dtmf_t)(ftdm_channel_t *ftdmchan, const
 typedef enum {
 	FTDM_ITERATOR_VARS = 1,
 	FTDM_ITERATOR_CHANS,
+	FTDM_ITERATOR_SPANS,
 } ftdm_iterator_type_t;
 
 struct ftdm_iterator {