|
|
1.1 root 1: /***
2: *cenumpt.cpp
3: *
4: * Copyright (C) 1992-93, Microsoft Corporation. All Rights Reserved.
5: *
6: *Purpose:
7: * This module implements the CEnumPoint class.
8: *
9: *
10: *Implementation Notes:
11: *
12: *****************************************************************************/
13:
14: #include "hostenv.h"
15: #include "cenumpt.h"
16:
17:
18: CEnumPoint::CEnumPoint()
19: {
20: m_refs = 0;
21:
22: m_psa = NULL;
23: m_celts = 0;
24: m_iCurrent = 0;
25: }
26:
27:
28: /***
29: *HRESULT CEnumPoint::Create(SAFEARRAY*, CEnumPoint**)
30: *Purpose:
31: * This routine creates a CPoint enumerator from the given
32: * (1 X N) SafeArray of CPoint IDispatch pointers.
33: *
34: *Entry:
35: * psa = pointer to a SafeArray of VARIANTs
36: *
37: *Exit:
38: * return value = HRESULT
39: *
40: * *ppenum = pointer to a CPoint enumerator
41: *
42: ***********************************************************************/
43: HRESULT
44: CEnumPoint::Create(SAFEARRAY FAR* psa, CEnumPoint FAR* FAR* ppenum)
45: {
46: long lBound;
47: HRESULT hresult;
48: CEnumPoint FAR* penum;
49:
50:
51: // Verify that the SafeArray is the proper shape.
52: //
53: if(SafeArrayGetDim(psa) != 1)
54: return ResultFromScode(E_INVALIDARG);
55:
56: hresult = SafeArrayGetLBound(psa, 1, &lBound);
57: if(FAILED(hresult))
58: return hresult;
59:
60: if(lBound != 0)
61: return ResultFromScode(E_INVALIDARG);
62:
63: penum = new FAR CEnumPoint();
64: if(penum == NULL)
65: return ResultFromScode(E_OUTOFMEMORY);
66: penum->AddRef();
67:
68: hresult = SafeArrayGetUBound(psa, 1, &lBound);
69: if(FAILED(hresult))
70: goto LError0;
71:
72: penum->m_psa = psa;
73: penum->m_celts = lBound + 1;
74:
75: *ppenum = penum;
76:
77: return NOERROR;
78:
79: LError0:;
80: penum->Release();
81:
82: return hresult;
83: }
84:
85:
86: //---------------------------------------------------------------------
87: // IUnknown methods
88: //---------------------------------------------------------------------
89:
90:
91: STDMETHODIMP
92: CEnumPoint::QueryInterface(REFIID riid, void FAR* FAR* ppv)
93: {
94: if(riid != IID_IUnknown)
95: if(riid != IID_IEnumVARIANT)
96: return ResultFromScode(E_NOINTERFACE);
97:
98: *ppv = this;
99: AddRef();
100: return NOERROR;
101: }
102:
103:
104: STDMETHODIMP_(unsigned long)
105: CEnumPoint::AddRef()
106: {
107: return ++m_refs;
108: }
109:
110:
111: STDMETHODIMP_(unsigned long)
112: CEnumPoint::Release()
113: {
114: if(--m_refs == 0){
115: if(m_psa != NULL)
116: SafeArrayDestroy(m_psa);
117: delete this;
118: return 0;
119: }
120: return m_refs;
121: }
122:
123:
124: //---------------------------------------------------------------------
125: // IEnumVARIANT methods
126: //---------------------------------------------------------------------
127:
128:
129: /***
130: *HRESULT CEnumPoint::Next(unsigned long, VARIANT*, unsigned long*)
131: *Purpose:
132: * Attempt to get the next 'celt' items in the enumeration sequence.
133: *
134: *Entry:
135: * celt = the number of elements to get
136: *
137: *Exit:
138: * return value = HRESULT
139: * S_OK
140: * S_FALSE - the end of the sequence was reached
141: *
142: * rgvar = array of the next 'celt' items
143: * *pceltFetched = count of the elements actually fetched.
144: *
145: ***********************************************************************/
146: STDMETHODIMP
147: CEnumPoint::Next(
148: unsigned long celt,
149: VARIANT FAR* rgvar,
150: unsigned long FAR* pceltFetched)
151: {
152: long ix;
153: unsigned int i;
154: HRESULT hresult;
155:
156:
157: for(i = 0; i < celt; ++i)
158: VariantInit(&rgvar[i]);
159:
160: for(i = 0; i < celt; ++i){
161: if(m_iCurrent == m_celts){
162: hresult = ResultFromScode(S_FALSE);
163: goto LDone;
164: }
165:
166: ix = m_iCurrent++;
167: hresult = SafeArrayGetElement(m_psa, &ix, &rgvar[i]);
168: if(FAILED(hresult))
169: goto LError0;
170: }
171:
172: hresult = NOERROR;
173:
174: LDone:;
175: *pceltFetched = i;
176:
177: return hresult;
178:
179: LError0:;
180:
181: for(i = 0; i < celt; ++i)
182: VariantClear(&rgvar[i]);
183:
184: return hresult;
185: }
186:
187:
188: /***
189: *HRESULT CEnumPoint::Skip(unsigned long)
190: *Purpose:
191: * Attempt to skip over the next 'celt' elements in the enumeration
192: * sequence.
193: *
194: *Entry:
195: * celt = the count of elements to skip
196: *
197: *Exit:
198: * return value = HRESULT
199: * S_OK
200: * S_FALSE - the end of the sequence was reached
201: *
202: ***********************************************************************/
203: STDMETHODIMP
204: CEnumPoint::Skip(unsigned long celt)
205: {
206: m_iCurrent += celt;
207:
208: if(m_iCurrent > m_celts)
209: m_iCurrent = m_celts;
210:
211: return (m_iCurrent == m_celts)
212: ? ResultFromScode(S_FALSE) : NOERROR;
213: }
214:
215:
216: /***
217: *HRESULT CEnumPoint::Reset(void)
218: *Purpose:
219: * Reset the enumeration sequence back to the beginning.
220: *
221: *Entry:
222: * None
223: *
224: *Exit:
225: * return value = SHRESULT CODE
226: * S_OK
227: *
228: ***********************************************************************/
229: STDMETHODIMP
230: CEnumPoint::Reset()
231: {
232: m_iCurrent = 0;
233:
234: return NOERROR;
235: }
236:
237:
238: /***
239: *HRESULT CEnumPoint::Clone(IEnumVARIANT**)
240: *Purpose:
241: * Retrun a CPoint enumerator with exactly the same state as the
242: * current one.
243: *
244: *Entry:
245: * None
246: *
247: *Exit:
248: * return value = HRESULT
249: * S_OK
250: * E_OUTOFMEMORY
251: *
252: ***********************************************************************/
253: STDMETHODIMP
254: CEnumPoint::Clone(IEnumVARIANT FAR* FAR* ppenum)
255: {
256: HRESULT hresult;
257: SAFEARRAY FAR* psa;
258: CEnumPoint FAR* penum;
259:
260: hresult = SafeArrayCopy(m_psa, &psa);
261: if(FAILED(hresult))
262: return hresult;
263:
264: hresult = CEnumPoint::Create(psa, &penum);
265: if(FAILED(hresult))
266: goto LError0;
267:
268: // Assert(penum->m_celts == m_celts);
269:
270: penum->m_iCurrent = m_iCurrent;
271:
272: *ppenum = penum;
273:
274: return NOERROR;
275:
276: LError0:
277: SafeArrayDestroy(psa);
278:
279: return hresult;
280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.