- Sync with trunk up to r46941.
[reactos.git] / dll / directx / msdvbnp / enumpins.cpp
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 (janderwald@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 }