xref: /reactos/dll/directx/msdvbnp/enumpins.cpp (revision d6eebaa4)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Network Provider for MPEG2 based networks
4  * FILE:            dll/directx/msdvbnp/enumpins.cpp
5  * PURPOSE:         IEnumPins interface
6  *
7  * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 #include "precomp.h"
10 
11 class CEnumPins : public IEnumPins
12 {
13 public:
14     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
15 
16     STDMETHODIMP_(ULONG) AddRef()
17     {
18         InterlockedIncrement(&m_Ref);
19         return m_Ref;
20     }
21     STDMETHODIMP_(ULONG) Release()
22     {
23         InterlockedDecrement(&m_Ref);
24         if (!m_Ref)
25         {
26             delete this;
27             return 0;
28         }
29         return m_Ref;
30     }
31 
32 
33     HRESULT STDMETHODCALLTYPE Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched);
34     HRESULT STDMETHODCALLTYPE Skip(ULONG cPins);
35     HRESULT STDMETHODCALLTYPE Reset();
36     HRESULT STDMETHODCALLTYPE Clone(IEnumPins **ppEnum);
37 
38     CEnumPins(ULONG NumPins, IPin ** pins) : m_Ref(0), m_NumPins(NumPins), m_Pins(pins), m_Index(0){};
39     virtual ~CEnumPins(){};
40 
41 protected:
42     LONG m_Ref;
43     ULONG m_NumPins;
44     IPin ** m_Pins;
45     ULONG m_Index;
46 };
47 
48 HRESULT
49 STDMETHODCALLTYPE
50 CEnumPins::QueryInterface(
51     IN  REFIID refiid,
52     OUT PVOID* Output)
53 {
54     if (IsEqualGUID(refiid, IID_IUnknown))
55     {
56         *Output = PVOID(this);
57         reinterpret_cast<IUnknown*>(*Output)->AddRef();
58         return NOERROR;
59     }
60     if (IsEqualGUID(refiid, IID_IEnumPins))
61     {
62         *Output = (IEnumPins*)(this);
63         reinterpret_cast<IEnumPins*>(*Output)->AddRef();
64         return NOERROR;
65     }
66 
67     WCHAR Buffer[MAX_PATH];
68     LPOLESTR lpstr;
69     StringFromCLSID(refiid, &lpstr);
70     swprintf(Buffer, L"CEnumPins::QueryInterface: NoInterface for %s\n", lpstr);
71     OutputDebugStringW(Buffer);
72     CoTaskMemFree(lpstr);
73 
74     return E_NOINTERFACE;
75 }
76 
77 HRESULT
78 STDMETHODCALLTYPE
79 CEnumPins::Next(
80     ULONG cPins,
81     IPin **ppPins,
82     ULONG *pcFetched)
83 {
84     ULONG i = 0;
85 
86     if (!ppPins)
87         return E_POINTER;
88 
89     if (cPins > 1 && !pcFetched)
90         return E_INVALIDARG;
91 
92     while(i < cPins)
93     {
94         if (m_Index + i >= m_NumPins)
95             break;
96 
97         ppPins[i] = m_Pins[m_Index + i];
98         m_Pins[m_Index + i]->AddRef();
99 
100         i++;
101     }
102 
103     if (pcFetched)
104     {
105         *pcFetched = i;
106     }
107 
108     m_Index += i;
109 
110     if (i < cPins)
111         return S_FALSE;
112     else
113         return S_OK;
114 }
115 
116 HRESULT
117 STDMETHODCALLTYPE
118 CEnumPins::Skip(
119     ULONG cPins)
120 {
121     if (cPins + m_Index >= m_NumPins)
122     {
123         return S_FALSE;
124     }
125 
126     m_Index += cPins;
127     return S_OK;
128 }
129 
130 HRESULT
131 STDMETHODCALLTYPE
132 CEnumPins::Reset()
133 {
134     m_Index = 0;
135     return S_OK;
136 }
137 
138 HRESULT
139 STDMETHODCALLTYPE
140 CEnumPins::Clone(
141     IEnumPins **ppEnum)
142 {
143     OutputDebugStringW(L"CEnumPins::Clone : NotImplemented\n");
144     return E_NOTIMPL;
145 }
146 
147 HRESULT
148 WINAPI
149 CEnumPins_fnConstructor(
150     IUnknown *pUnknown,
151     ULONG NumPins,
152     IPin ** pins,
153     REFIID riid,
154     LPVOID * ppv)
155 {
156     CEnumPins * handler = new CEnumPins(NumPins, pins);
157 
158     if (!handler)
159         return E_OUTOFMEMORY;
160 
161     if (FAILED(handler->QueryInterface(riid, ppv)))
162     {
163         /* not supported */
164         delete handler;
165         return E_NOINTERFACE;
166     }
167 
168     return NOERROR;
169 }
170