summaryrefslogtreecommitdiff
path: root/gstreamer-sharp/Iterator.cs
blob: 29dc742c556ab4c1f69fca3d7b4c19bfa3dcb6f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections;
using System.Runtime.InteropServices;
using GLib;

namespace Gst {

  internal class Enumerable : IEnumerable {
    private class Enumerator : IEnumerator {
      Hashtable seen = new Hashtable ();
      IntPtr iterator;

      private object current = null;
      public object Current {
        get {
          return current;
        }
      }

      public bool MoveNext () {
        IntPtr raw_ret;
        bool retry = false;

        if (iterator == IntPtr.Zero)
          return false;

        do {
          int ret = gst_iterator_next (iterator, out raw_ret);
          switch (ret) {
            case 0:
              return false;
            case 1:
              if (seen.Contains (raw_ret)) {
                retry = true;
                break;
              }

              seen.Add (raw_ret, null);
              current = GLib.Object.GetObject (raw_ret, true);
              return true;
            case 2:
              gst_iterator_resync (iterator);
              retry = true;
              break;
            default:
            case 3:
              throw new Exception ("Error while iterating pads");
          }
        } while (retry);

        return false;
      }

      public void Reset () {
        seen.Clear ();
        if (iterator != IntPtr.Zero)
          gst_iterator_resync (iterator);
      }

      public Enumerator (IntPtr iterator) {
        this.iterator = iterator;
      }
    }

    private IntPtr iterator;
    private Enumerator enumerator;

    public Enumerable (IntPtr iterator) {
      this.iterator = iterator;
      this.enumerator = new Enumerator (iterator);
    }

    public IEnumerator GetEnumerator () {
      return enumerator;
    }

    ~Enumerable () {
      if (iterator != IntPtr.Zero)
        gst_iterator_free (iterator);
    }

    [DllImport ("gstreamer-0.10.dll") ]
    static extern int gst_iterator_next (IntPtr iterator, out IntPtr elem);
    [DllImport ("gstreamer-0.10.dll") ]
    static extern void gst_iterator_resync (IntPtr iterator);
    [DllImport ("gstreamer-0.10.dll") ]
    static extern void gst_iterator_free (IntPtr iterator);

  }
}