1 //---------------------------------------------------------------
2 //
3 // For conditions of distribution and use, see copyright notice
4 // in Flashpix.h
5 //
6 // Copyright (c) 1999 Digital Imaging Group, Inc.
7 //
8 // Contents: CExposedIterator implementation
9 //
10 //---------------------------------------------------------------
11
12 #include "exphead.cxx"
13
14 #include "expiter.hxx"
15 #include "h/sstream.hxx"
16
17 //+--------------------------------------------------------------
18 //
19 // Member: CExposedIterator::CExposedIterator, public
20 //
21 // Synopsis: Constructor
22 //
23 // Arguments: [ppdf] - Public Docfile
24 // [pKey] - Initial cursor (doc file name)
25 //
26 //---------------------------------------------------------------
27
CExposedIterator(CExposedDocFile * ppdf,CDfName * pKey)28 CExposedIterator::CExposedIterator(CExposedDocFile *ppdf, CDfName *pKey)
29 {
30 olDebugOut((DEB_ITRACE, "In CExposedIterator::CExposedIterator("
31 "%p, %p)\n", ppdf, pKey));
32 _dfnKey.Set(pKey);
33 _ppdf = ppdf;
34 // keep a ref, so that the pointer is valid throughout life time
35 // of iterator
36 _ppdf->AddRef();
37 _cReferences = 1;
38 _sig = CEXPOSEDITER_SIG;
39 olDebugOut((DEB_ITRACE,
40 "Out CExposedIterator::CExposedIterator\n"));
41 }
42
43 //+--------------------------------------------------------------
44 //
45 // Member: CExposedIterator::~CExposedIterator, public
46 //
47 // Synopsis: Destructor
48 //
49 //---------------------------------------------------------------
50
~CExposedIterator(void)51 CExposedIterator::~CExposedIterator(void)
52 {
53 olDebugOut((DEB_ITRACE, "In CExposedIterator::~CExposedIterator\n"));
54 _sig = CEXPOSEDITER_SIGDEL;
55 olAssert(_cReferences == 0);
56 if (_ppdf) _ppdf->Release();
57 olDebugOut((DEB_ITRACE, "Out CExposedIterator::~CExposedIterator\n"));
58 }
59
60 //+--------------------------------------------------------------
61 //
62 // Member: CExposedIterator::Next, public
63 //
64 // Synopsis: Gets N entries from an iterator
65 //
66 // Arguments: [celt] - Count of elements
67 // [rgelt] - Array for element return
68 // [pceltFetched] - If non-NULL, contains the number of
69 // elements fetched
70 //
71 // Returns: Appropriate status code
72 //
73 // Modifies: [rgelt]
74 // [pceltFetched]
75 //
76 //---------------------------------------------------------------
77
Next(ULONG celt,STATSTGW FAR * rgelt,ULONG * pceltFetched)78 SCODE CExposedIterator::Next(ULONG celt,
79 STATSTGW FAR *rgelt,
80 ULONG *pceltFetched)
81 {
82 SCODE sc;
83 STATSTGW stat, *pelt = rgelt;
84 ULONG celtDone;
85 CDfName dfnInitial;
86
87 olDebugOut((DEB_ITRACE, "In CExposedIterator::Next(%lu, %p, %p)\n",
88 celt, rgelt, pceltFetched));
89
90 if (pceltFetched)
91 {
92 olChk(ValidateBuffer(pceltFetched, sizeof(ULONG)));
93 *pceltFetched = 0;
94 }
95 else if (celt > 1)
96 olErr(EH_Err, STG_E_INVALIDPARAMETER);
97 olAssert(0xffffUL/sizeof(STATSTGW) >= celt);
98 olChkTo(EH_RetSc,
99 ValidateOutBuffer(rgelt, sizeof(STATSTGW)*celt));
100 memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
101 olChk(Validate());
102 olChk(_ppdf->CheckReverted());
103
104 dfnInitial.Set(&_dfnKey); // preserve initial key to reset on failure
105 for (; pelt<rgelt+celt; pelt++)
106 {
107 sc = _ppdf->FindGreaterEntry(&_dfnKey, NULL, &stat);
108 if (FAILED(sc))
109 {
110 if (sc == STG_E_NOMOREFILES) sc = S_FALSE;
111 break;
112 }
113 _dfnKey.Set(stat.pwcsName); // advance key
114
115 stat.grfMode = 0;
116 stat.grfLocksSupported = 0;
117 stat.reserved = 0;
118 *pelt = stat;
119 }
120
121 // Can't move this down because dfnInitial isn't set for all EH_Err cases
122 if (FAILED(sc)) _dfnKey.Set(&dfnInitial);
123
124 olDebugOut((DEB_ITRACE, "Out CExposedIterator::Next => %lX\n", sc));
125 EH_Err:
126 celtDone = pelt-rgelt;
127 if (FAILED(sc))
128 {
129 ULONG i;
130
131 for (i = 0; i<celtDone; i++)
132 delete[] rgelt[i].pwcsName;
133 memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
134 }
135 else if (pceltFetched)
136 *pceltFetched = celtDone;
137 EH_RetSc:
138 return sc;
139 }
140
141 //+--------------------------------------------------------------
142 //
143 // Member: CExposedIterator::Skip, public
144 //
145 // Synopsis: Skips N entries from an iterator
146 //
147 // Arguments: [celt] - Count of elements
148 //
149 // Returns: Appropriate status code
150 //
151 //---------------------------------------------------------------
152
Skip(ULONG celt)153 STDMETHODIMP CExposedIterator::Skip(ULONG celt)
154 {
155 SCODE sc;
156 CDfName dfnNext;
157
158 olDebugOut((DEB_ITRACE, "In CExposedIterator::Skip(%lu)\n", celt));
159
160 olChk(Validate());
161 olChk(_ppdf->CheckReverted());
162 for (; celt>0; celt--)
163 {
164 sc = _ppdf->FindGreaterEntry(&_dfnKey, &dfnNext, NULL);
165 if (FAILED(sc))
166 {
167 if (sc == STG_E_NOMOREFILES)
168 sc = S_FALSE;
169 break;
170 }
171 _dfnKey.Set(&dfnNext); // advance the cursor
172 }
173
174 olDebugOut((DEB_ITRACE, "Out CExposedIterator::Skip\n"));
175 EH_Err:
176 return ResultFromScode(sc);
177 }
178
179 //+--------------------------------------------------------------
180 //
181 // Member: CExposedIterator::Reset, public
182 //
183 // Synopsis: Rewinds the iterator
184 //
185 // Returns: Appropriate status code
186 //
187 //---------------------------------------------------------------
188
Reset(void)189 STDMETHODIMP CExposedIterator::Reset(void)
190 {
191 SCODE sc;
192
193 olDebugOut((DEB_ITRACE, "In CExposedIterator::Reset()\n"));
194
195 olChk(Validate());
196 _dfnKey.Set((WORD)0, (BYTE*)NULL); // set to smallest key
197 sc = _ppdf->CheckReverted();
198
199 olDebugOut((DEB_ITRACE, "Out CExposedIterator::Reset\n"));
200 EH_Err:
201 return ResultFromScode(sc);
202 }
203
204 //+--------------------------------------------------------------
205 //
206 // Member: CExposedIterator::Clone, public
207 //
208 // Synopsis: Clones this iterator
209 //
210 // Arguments: [ppenm] - Clone return
211 //
212 // Returns: Appropriate status code
213 //
214 // Modifies: [ppenm]
215 //
216 //---------------------------------------------------------------
217
Clone(IEnumSTATSTG ** ppenm)218 STDMETHODIMP CExposedIterator::Clone(IEnumSTATSTG **ppenm)
219 {
220 SCODE sc;
221 CExposedIterator *piExp;
222
223 olDebugOut((DEB_ITRACE, "In CExposedIterator::Clone(%p)\n", ppenm));
224
225 olChk(ValidateOutPtrBuffer(ppenm));
226 *ppenm = NULL;
227 olChk(Validate());
228 olChk(_ppdf->CheckReverted());
229 olMem(piExp = new CExposedIterator(_ppdf, &_dfnKey));
230 *ppenm = piExp;
231
232 olDebugOut((DEB_ITRACE, "Out CExposedIterator::Clone => %p\n",
233 SAFE_DREF(ppenm)));
234 // Fall through
235 EH_Err:
236 return ResultFromScode(sc);
237 }
238
239 //+--------------------------------------------------------------
240 //
241 // Member: CExposedIterator::Release, public
242 //
243 // Synopsis: Releases resources for the iterator
244 //
245 // Returns: Appropriate status code
246 //
247 //---------------------------------------------------------------
248
STDMETHODIMP_(ULONG)249 STDMETHODIMP_(ULONG) CExposedIterator::Release(void)
250 {
251 ULONG lRet;
252
253 olDebugOut((DEB_ITRACE, "In CExposedIterator::Release()\n"));
254 if (FAILED(Validate()))
255 return 0;
256 olAssert(_cReferences > 0);
257 lRet = --(_cReferences);
258 if (_cReferences <= 0)
259 delete this;
260
261 olDebugOut((DEB_ITRACE, "Out CExposedIterator::Release\n"));
262 return lRet;
263 }
264
265 //+--------------------------------------------------------------
266 //
267 // Member: CExposedIterator::AddRef, public
268 //
269 // Synopsis: Increments the ref count
270 //
271 // Returns: Appropriate status code
272 //
273 //---------------------------------------------------------------
274
STDMETHODIMP_(ULONG)275 STDMETHODIMP_(ULONG) CExposedIterator::AddRef(void)
276 {
277 ULONG ulRet;
278
279 olDebugOut((DEB_ITRACE, "In CExposedIterator::AddRef()\n"));
280
281 if (FAILED(Validate())) return 0;
282 ulRet = ++(_cReferences);
283
284 olDebugOut((DEB_ITRACE, "Out CExposedIterator::AddRef\n"));
285 return ulRet;
286 }
287
288 //+--------------------------------------------------------------
289 //
290 // Member: CExposedIterator::QueryInterface, public
291 //
292 // Synopsis: Returns an object for the requested interface
293 //
294 // Arguments: [iid] - Interface ID
295 // [ppvObj] - Object return
296 //
297 // Returns: Appropriate status code
298 //
299 // Modifies: [ppvObj]
300 //
301 //---------------------------------------------------------------
302
QueryInterface(REFIID iid,void ** ppvObj)303 STDMETHODIMP CExposedIterator::QueryInterface(REFIID iid, void **ppvObj)
304 {
305 SCODE sc;
306
307 olDebugOut((DEB_ITRACE, "In CExposedIterator::QueryInterface(?, %p)\n",
308 ppvObj));
309
310 olChk(Validate());
311 olChk(ValidateOutPtrBuffer(ppvObj));
312 *ppvObj = NULL;
313 olChk(_ppdf->CheckReverted());
314 olChk(ValidateIid(iid));
315 if (IsEqualIID(iid, IID_IEnumSTATSTG) || IsEqualIID(iid, IID_IUnknown))
316 {
317 *ppvObj = this;
318 AddRef();
319 sc = S_OK;
320 }
321 else
322 {
323 sc = E_NOINTERFACE;
324 }
325
326 olDebugOut((DEB_ITRACE, "Out CExposedIterator::QueryInterface => %p\n",
327 SAFE_DREF(ppvObj)));
328 EH_Err:
329 return ResultFromScode(sc);
330 }
331