File: | store/source/stordata.cxx |
Location: | line 308, column 5 |
Description: | Dereference of null pointer |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | ||||
21 | #include "stordata.hxx" | |||
22 | ||||
23 | #include "sal/types.h" | |||
24 | #include "osl/diagnose.h" | |||
25 | ||||
26 | #include "store/types.h" | |||
27 | #include "storbase.hxx" | |||
28 | #include "storbios.hxx" | |||
29 | ||||
30 | using namespace store; | |||
31 | ||||
32 | /*======================================================================== | |||
33 | * | |||
34 | * OStoreDataPageObject implementation. | |||
35 | * | |||
36 | *======================================================================*/ | |||
37 | /* | |||
38 | * guard. | |||
39 | */ | |||
40 | storeError OStoreDataPageObject::guard (sal_uInt32 nAddr) | |||
41 | { | |||
42 | return PageHolderObject< page >::guard (m_xPage, nAddr); | |||
43 | } | |||
44 | ||||
45 | /* | |||
46 | * verify. | |||
47 | */ | |||
48 | storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const | |||
49 | { | |||
50 | return PageHolderObject< page >::verify (m_xPage, nAddr); | |||
51 | } | |||
52 | ||||
53 | /*======================================================================== | |||
54 | * | |||
55 | * OStoreIndirectionPageObject implementation. | |||
56 | * | |||
57 | *======================================================================*/ | |||
58 | /* | |||
59 | * store_truncate_Impl (single indirect page). | |||
60 | */ | |||
61 | static storeError store_truncate_Impl ( | |||
62 | sal_uInt32 nAddr, | |||
63 | sal_uInt16 nSingle, | |||
64 | OStorePageBIOS &rBIOS) | |||
65 | { | |||
66 | if (nAddr != STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
67 | { | |||
68 | // Load single indirect page. | |||
69 | OStoreIndirectionPageObject aSingle; | |||
70 | storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); | |||
71 | if (eErrCode == store_E_None) | |||
72 | { | |||
73 | // Truncate to 'nSingle' direct pages. | |||
74 | eErrCode = aSingle.truncate (nSingle, rBIOS); | |||
75 | if (eErrCode != store_E_None) | |||
76 | return eErrCode; | |||
77 | } | |||
78 | else | |||
79 | { | |||
80 | if (eErrCode != store_E_InvalidChecksum) | |||
81 | return eErrCode; | |||
82 | } | |||
83 | ||||
84 | // Check for complete truncation. | |||
85 | if (nSingle == 0) | |||
86 | { | |||
87 | // Free single indirect page. | |||
88 | eErrCode = rBIOS.free (nAddr); | |||
89 | if (eErrCode != store_E_None) | |||
90 | return eErrCode; | |||
91 | } | |||
92 | } | |||
93 | return store_E_None; | |||
94 | } | |||
95 | ||||
96 | /* | |||
97 | * store_truncate_Impl (double indirect page). | |||
98 | */ | |||
99 | static storeError store_truncate_Impl ( | |||
100 | sal_uInt32 nAddr, | |||
101 | sal_uInt16 nDouble, | |||
102 | sal_uInt16 nSingle, | |||
103 | OStorePageBIOS &rBIOS) | |||
104 | { | |||
105 | if (nAddr != STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
106 | { | |||
107 | // Load double indirect page. | |||
108 | OStoreIndirectionPageObject aDouble; | |||
109 | storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); | |||
110 | if (eErrCode == store_E_None) | |||
111 | { | |||
112 | // Truncate to 'nDouble', 'nSingle' pages. | |||
113 | eErrCode = aDouble.truncate (nDouble, nSingle, rBIOS); | |||
114 | if (eErrCode != store_E_None) | |||
115 | return eErrCode; | |||
116 | } | |||
117 | else | |||
118 | { | |||
119 | if (eErrCode != store_E_InvalidChecksum) | |||
120 | return eErrCode; | |||
121 | } | |||
122 | ||||
123 | // Check for complete truncation. | |||
124 | if ((nDouble + nSingle) == 0) | |||
125 | { | |||
126 | // Free double indirect page. | |||
127 | eErrCode = rBIOS.free (nAddr); | |||
128 | if (eErrCode != store_E_None) | |||
129 | return eErrCode; | |||
130 | } | |||
131 | } | |||
132 | return store_E_None; | |||
133 | } | |||
134 | ||||
135 | /* | |||
136 | * store_truncate_Impl (triple indirect page). | |||
137 | */ | |||
138 | static storeError store_truncate_Impl ( | |||
139 | sal_uInt32 nAddr, | |||
140 | sal_uInt16 nTriple, | |||
141 | sal_uInt16 nDouble, | |||
142 | sal_uInt16 nSingle, | |||
143 | OStorePageBIOS &rBIOS) | |||
144 | { | |||
145 | if (nAddr != STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
146 | { | |||
147 | // Load triple indirect page. | |||
148 | OStoreIndirectionPageObject aTriple; | |||
149 | storeError eErrCode = rBIOS.loadObjectAt (aTriple, nAddr); | |||
150 | if (eErrCode != store_E_None) | |||
151 | return eErrCode; | |||
152 | ||||
153 | // Truncate to 'nTriple', 'nDouble', 'nSingle' pages. | |||
154 | eErrCode = aTriple.truncate (nTriple, nDouble, nSingle, rBIOS); | |||
155 | if (eErrCode != store_E_None) | |||
156 | return eErrCode; | |||
157 | ||||
158 | // Check for complete truncation. | |||
159 | if ((nTriple + nDouble + nSingle) == 0) | |||
160 | { | |||
161 | // Free triple indirect page. | |||
162 | eErrCode = rBIOS.free (nAddr); | |||
163 | if (eErrCode != store_E_None) | |||
164 | return eErrCode; | |||
165 | } | |||
166 | } | |||
167 | return store_E_None; | |||
168 | } | |||
169 | ||||
170 | /* | |||
171 | * loadOrCreate. | |||
172 | */ | |||
173 | storeError OStoreIndirectionPageObject::loadOrCreate ( | |||
174 | sal_uInt32 nAddr, | |||
175 | OStorePageBIOS & rBIOS) | |||
176 | { | |||
177 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
178 | { | |||
179 | storeError eErrCode = construct<page>(rBIOS.allocator()); | |||
180 | if (eErrCode != store_E_None) | |||
181 | return eErrCode; | |||
182 | ||||
183 | eErrCode = rBIOS.allocate (*this); | |||
184 | if (eErrCode != store_E_None) | |||
185 | return eErrCode; | |||
186 | ||||
187 | // Save location pending at caller. | |||
188 | return store_E_Pending; | |||
189 | } | |||
190 | return rBIOS.loadObjectAt (*this, nAddr); | |||
191 | } | |||
192 | ||||
193 | /* | |||
194 | * guard. | |||
195 | */ | |||
196 | storeError OStoreIndirectionPageObject::guard (sal_uInt32 nAddr) | |||
197 | { | |||
198 | return PageHolderObject< page >::guard (m_xPage, nAddr); | |||
199 | } | |||
200 | ||||
201 | /* | |||
202 | * verify. | |||
203 | */ | |||
204 | storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr) const | |||
205 | { | |||
206 | return PageHolderObject< page >::verify (m_xPage, nAddr); | |||
207 | } | |||
208 | ||||
209 | /* | |||
210 | * read (single indirect). | |||
211 | */ | |||
212 | storeError OStoreIndirectionPageObject::read ( | |||
213 | sal_uInt16 nSingle, | |||
214 | OStoreDataPageObject &rData, | |||
215 | OStorePageBIOS &rBIOS) | |||
216 | { | |||
217 | PageHolderObject< page > xImpl (m_xPage); | |||
218 | page const & rPage = (*xImpl); | |||
219 | ||||
220 | // Check arguments. | |||
221 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
222 | if (!(nSingle < nLimit)) | |||
223 | return store_E_InvalidAccess; | |||
224 | ||||
225 | // Obtain data page location. | |||
226 | sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]); | |||
227 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
228 | return store_E_NotExists; | |||
229 | ||||
230 | // Load data page and leave. | |||
231 | return rBIOS.loadObjectAt (rData, nAddr); | |||
232 | } | |||
233 | ||||
234 | /* | |||
235 | * read (double indirect). | |||
236 | */ | |||
237 | storeError OStoreIndirectionPageObject::read ( | |||
238 | sal_uInt16 nDouble, | |||
239 | sal_uInt16 nSingle, | |||
240 | OStoreDataPageObject &rData, | |||
241 | OStorePageBIOS &rBIOS) | |||
242 | { | |||
243 | PageHolderObject< page > xImpl (m_xPage); | |||
244 | page const & rPage = (*xImpl); | |||
245 | ||||
246 | // Check arguments. | |||
247 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
248 | if (!((nDouble < nLimit) && (nSingle < nLimit))) | |||
249 | return store_E_InvalidAccess; | |||
250 | ||||
251 | // Check single indirect page location. | |||
252 | sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nDouble]); | |||
253 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
254 | return store_E_NotExists; | |||
255 | ||||
256 | // Load single indirect page. | |||
257 | OStoreIndirectionPageObject aSingle; | |||
258 | storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); | |||
259 | if (eErrCode != store_E_None) | |||
260 | return eErrCode; | |||
261 | ||||
262 | // Read single indirect and leave. | |||
263 | return aSingle.read (nSingle, rData, rBIOS); | |||
264 | } | |||
265 | ||||
266 | /* | |||
267 | * read (triple indirect). | |||
268 | */ | |||
269 | storeError OStoreIndirectionPageObject::read ( | |||
270 | sal_uInt16 nTriple, | |||
271 | sal_uInt16 nDouble, | |||
272 | sal_uInt16 nSingle, | |||
273 | OStoreDataPageObject &rData, | |||
274 | OStorePageBIOS &rBIOS) | |||
275 | { | |||
276 | PageHolderObject< page > xImpl (m_xPage); | |||
277 | page const & rPage = (*xImpl); | |||
278 | ||||
279 | // Check arguments. | |||
280 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
281 | if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) | |||
282 | return store_E_InvalidAccess; | |||
283 | ||||
284 | // Check double indirect page location. | |||
285 | sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nTriple]); | |||
286 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
287 | return store_E_NotExists; | |||
288 | ||||
289 | // Load double indirect page. | |||
290 | OStoreIndirectionPageObject aDouble; | |||
291 | storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); | |||
292 | if (eErrCode != store_E_None) | |||
293 | return eErrCode; | |||
294 | ||||
295 | // Read double indirect and leave. | |||
296 | return aDouble.read (nDouble, nSingle, rData, rBIOS); | |||
297 | } | |||
298 | ||||
299 | /* | |||
300 | * write (single indirect). | |||
301 | */ | |||
302 | storeError OStoreIndirectionPageObject::write ( | |||
303 | sal_uInt16 nSingle, | |||
304 | OStoreDataPageObject &rData, | |||
305 | OStorePageBIOS &rBIOS) | |||
306 | { | |||
307 | PageHolderObject< page > xImpl (m_xPage); | |||
308 | page & rPage = (*xImpl); | |||
| ||||
309 | ||||
310 | // Check arguments. | |||
311 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
312 | if (!(nSingle < nLimit)) | |||
313 | return store_E_InvalidAccess; | |||
314 | ||||
315 | // Obtain data page location. | |||
316 | sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]); | |||
317 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
318 | { | |||
319 | // Allocate data page. | |||
320 | storeError eErrCode = rBIOS.allocate (rData); | |||
321 | if (eErrCode != store_E_None) | |||
322 | return eErrCode; | |||
323 | ||||
324 | // Store data page location. | |||
325 | rPage.m_pData[nSingle] = store::htonl(rData.location()); | |||
326 | ||||
327 | // Save this page. | |||
328 | return rBIOS.saveObjectAt (*this, location()); | |||
329 | } | |||
330 | else | |||
331 | { | |||
332 | // Save data page. | |||
333 | return rBIOS.saveObjectAt (rData, nAddr); | |||
334 | } | |||
335 | } | |||
336 | ||||
337 | /* | |||
338 | * write (double indirect). | |||
339 | */ | |||
340 | storeError OStoreIndirectionPageObject::write ( | |||
341 | sal_uInt16 nDouble, | |||
342 | sal_uInt16 nSingle, | |||
343 | OStoreDataPageObject &rData, | |||
344 | OStorePageBIOS &rBIOS) | |||
345 | { | |||
346 | PageHolderObject< page > xImpl (m_xPage); | |||
347 | page & rPage = (*xImpl); | |||
348 | ||||
349 | // Check arguments. | |||
350 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
351 | if (!((nDouble < nLimit) && (nSingle < nLimit))) | |||
352 | return store_E_InvalidAccess; | |||
353 | ||||
354 | // Load or create single indirect page. | |||
355 | OStoreIndirectionPageObject aSingle; | |||
356 | storeError eErrCode = aSingle.loadOrCreate (store::ntohl(rPage.m_pData[nDouble]), rBIOS); | |||
357 | if (eErrCode != store_E_None) | |||
358 | { | |||
359 | if (eErrCode != store_E_Pending) | |||
360 | return eErrCode; | |||
361 | rPage.m_pData[nDouble] = store::htonl(aSingle.location()); | |||
362 | ||||
363 | eErrCode = rBIOS.saveObjectAt (*this, location()); | |||
364 | if (eErrCode != store_E_None) | |||
365 | return eErrCode; | |||
366 | } | |||
367 | ||||
368 | // Write single indirect and leave. | |||
369 | return aSingle.write (nSingle, rData, rBIOS); | |||
370 | } | |||
371 | ||||
372 | /* | |||
373 | * write (triple indirect). | |||
374 | */ | |||
375 | storeError OStoreIndirectionPageObject::write ( | |||
376 | sal_uInt16 nTriple, | |||
377 | sal_uInt16 nDouble, | |||
378 | sal_uInt16 nSingle, | |||
379 | OStoreDataPageObject &rData, | |||
380 | OStorePageBIOS &rBIOS) | |||
381 | { | |||
382 | PageHolderObject< page > xImpl (m_xPage); | |||
383 | page & rPage = (*xImpl); | |||
384 | ||||
385 | // Check arguments. | |||
386 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
387 | if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) | |||
388 | return store_E_InvalidAccess; | |||
389 | ||||
390 | // Load or create double indirect page. | |||
391 | OStoreIndirectionPageObject aDouble; | |||
392 | storeError eErrCode = aDouble.loadOrCreate (store::ntohl(rPage.m_pData[nTriple]), rBIOS); | |||
393 | if (eErrCode != store_E_None) | |||
394 | { | |||
395 | if (eErrCode != store_E_Pending) | |||
396 | return eErrCode; | |||
397 | rPage.m_pData[nTriple] = store::htonl(aDouble.location()); | |||
398 | ||||
399 | eErrCode = rBIOS.saveObjectAt (*this, location()); | |||
400 | if (eErrCode != store_E_None) | |||
401 | return eErrCode; | |||
402 | } | |||
403 | ||||
404 | // Write double indirect and leave. | |||
405 | return aDouble.write (nDouble, nSingle, rData, rBIOS); | |||
406 | } | |||
407 | ||||
408 | /* | |||
409 | * truncate (single indirect). | |||
410 | */ | |||
411 | storeError OStoreIndirectionPageObject::truncate ( | |||
412 | sal_uInt16 nSingle, | |||
413 | OStorePageBIOS & rBIOS) | |||
414 | { | |||
415 | PageHolderObject< page > xImpl (m_xPage); | |||
416 | page & rPage = (*xImpl); | |||
417 | ||||
418 | // Check arguments. | |||
419 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
420 | if (!(nSingle < nLimit)) | |||
421 | return store_E_InvalidAccess; | |||
422 | ||||
423 | // Truncate. | |||
424 | storeError eErrCode = store_E_None; | |||
425 | for (sal_uInt16 i = nLimit; i > nSingle; i--) | |||
426 | { | |||
427 | // Obtain data page location. | |||
428 | sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[i - 1]); | |||
429 | if (nAddr != STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
430 | { | |||
431 | // Free data page. | |||
432 | eErrCode = rBIOS.free (nAddr); | |||
433 | if (eErrCode != store_E_None) | |||
434 | return eErrCode; | |||
435 | ||||
436 | // Clear pointer to data page. | |||
437 | rPage.m_pData[i - 1] = STORE_PAGE_NULL((sal_uInt32)(~0)); | |||
438 | touch(); | |||
439 | } | |||
440 | } | |||
441 | ||||
442 | // Check for modified page. | |||
443 | if (dirty()) | |||
444 | { | |||
445 | // Save this page. | |||
446 | eErrCode = rBIOS.saveObjectAt (*this, location()); | |||
447 | } | |||
448 | ||||
449 | // Done. | |||
450 | return eErrCode; | |||
451 | } | |||
452 | ||||
453 | /* | |||
454 | * truncate (double indirect). | |||
455 | */ | |||
456 | storeError OStoreIndirectionPageObject::truncate ( | |||
457 | sal_uInt16 nDouble, | |||
458 | sal_uInt16 nSingle, | |||
459 | OStorePageBIOS &rBIOS) | |||
460 | { | |||
461 | PageHolderObject< page > xImpl (m_xPage); | |||
462 | page & rPage = (*xImpl); | |||
463 | ||||
464 | // Check arguments. | |||
465 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
466 | if (!((nDouble < nLimit) && (nSingle < nLimit))) | |||
467 | return store_E_InvalidAccess; | |||
468 | ||||
469 | // Truncate. | |||
470 | storeError eErrCode = store_E_None; | |||
471 | for (sal_uInt16 i = nLimit; i > nDouble + 1; i--) | |||
472 | { | |||
473 | // Truncate single indirect page to zero direct pages. | |||
474 | eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, rBIOS); | |||
475 | if (eErrCode != store_E_None) | |||
476 | return eErrCode; | |||
477 | ||||
478 | // Clear pointer to single indirect page. | |||
479 | rPage.m_pData[i - 1] = STORE_PAGE_NULL((sal_uInt32)(~0)); | |||
480 | touch(); | |||
481 | } | |||
482 | ||||
483 | // Truncate last single indirect page to 'nSingle' direct pages. | |||
484 | eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nDouble]), nSingle, rBIOS); | |||
485 | if (eErrCode != store_E_None) | |||
486 | return eErrCode; | |||
487 | ||||
488 | // Check for complete truncation. | |||
489 | if (nSingle == 0) | |||
490 | { | |||
491 | // Clear pointer to last single indirect page. | |||
492 | rPage.m_pData[nDouble] = STORE_PAGE_NULL((sal_uInt32)(~0)); | |||
493 | touch(); | |||
494 | } | |||
495 | ||||
496 | // Check for modified page. | |||
497 | if (dirty()) | |||
498 | { | |||
499 | // Save this page. | |||
500 | eErrCode = rBIOS.saveObjectAt (*this, location()); | |||
501 | } | |||
502 | ||||
503 | // Done. | |||
504 | return eErrCode; | |||
505 | } | |||
506 | ||||
507 | /* | |||
508 | * truncate (triple indirect). | |||
509 | */ | |||
510 | storeError OStoreIndirectionPageObject::truncate ( | |||
511 | sal_uInt16 nTriple, | |||
512 | sal_uInt16 nDouble, | |||
513 | sal_uInt16 nSingle, | |||
514 | OStorePageBIOS &rBIOS) | |||
515 | { | |||
516 | PageHolderObject< page > xImpl (m_xPage); | |||
517 | page & rPage = (*xImpl); | |||
518 | ||||
519 | // Check arguments. | |||
520 | sal_uInt16 const nLimit = rPage.capacityCount(); | |||
521 | if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) | |||
522 | return store_E_InvalidAccess; | |||
523 | ||||
524 | // Truncate. | |||
525 | storeError eErrCode = store_E_None; | |||
526 | for (sal_uInt16 i = nLimit; i > nTriple + 1; i--) | |||
527 | { | |||
528 | // Truncate double indirect page to zero single indirect pages. | |||
529 | eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, 0, rBIOS); | |||
530 | if (eErrCode != store_E_None) | |||
531 | return eErrCode; | |||
532 | ||||
533 | // Clear pointer to double indirect page. | |||
534 | rPage.m_pData[i - 1] = STORE_PAGE_NULL((sal_uInt32)(~0)); | |||
535 | touch(); | |||
536 | } | |||
537 | ||||
538 | // Truncate last double indirect page to 'nDouble', 'nSingle' pages. | |||
539 | eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nTriple]), nDouble, nSingle, rBIOS); | |||
540 | if (eErrCode != store_E_None) | |||
541 | return eErrCode; | |||
542 | ||||
543 | // Check for complete truncation. | |||
544 | if ((nDouble + nSingle) == 0) | |||
545 | { | |||
546 | // Clear pointer to last double indirect page. | |||
547 | rPage.m_pData[nTriple] = STORE_PAGE_NULL((sal_uInt32)(~0)); | |||
548 | touch(); | |||
549 | } | |||
550 | ||||
551 | // Check for modified page. | |||
552 | if (dirty()) | |||
553 | { | |||
554 | // Save this page. | |||
555 | eErrCode = rBIOS.saveObjectAt (*this, location()); | |||
556 | } | |||
557 | ||||
558 | // Done. | |||
559 | return eErrCode; | |||
560 | } | |||
561 | ||||
562 | /*======================================================================== | |||
563 | * | |||
564 | * OStoreDirectoryPageObject implementation. | |||
565 | * | |||
566 | *======================================================================*/ | |||
567 | /* | |||
568 | * guard. | |||
569 | */ | |||
570 | storeError OStoreDirectoryPageObject::guard (sal_uInt32 nAddr) | |||
571 | { | |||
572 | return PageHolderObject< page >::guard (m_xPage, nAddr); | |||
573 | } | |||
574 | ||||
575 | /* | |||
576 | * verify. | |||
577 | */ | |||
578 | storeError OStoreDirectoryPageObject::verify (sal_uInt32 nAddr) const | |||
579 | { | |||
580 | return PageHolderObject< page >::verify (m_xPage, nAddr); | |||
581 | // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE); | |||
582 | } | |||
583 | ||||
584 | /* | |||
585 | * scope (external data page; private). | |||
586 | */ | |||
587 | OStoreDirectoryPageData::ChunkScope | |||
588 | OStoreDirectoryPageObject::scope ( | |||
589 | sal_uInt32 nPage, | |||
590 | page::DataBlock::LinkDescriptor &rDescr) const | |||
591 | { | |||
592 | page const & rPage = PAGE(); | |||
593 | OStoreDirectoryDataBlock const & rDataBlock = rPage.m_aDataBlock; | |||
594 | ||||
595 | sal_uInt32 index0, index1, index2, index3; | |||
596 | ||||
597 | // direct. | |||
598 | sal_uInt32 nCount = rDataBlock.directCount(); | |||
599 | sal_uInt32 nLimit = nCount; | |||
600 | if (nPage < nLimit) | |||
601 | { | |||
602 | // Page to index reduction. | |||
603 | index0 = nPage; | |||
604 | ||||
605 | // Setup LinkDescriptor indices. | |||
606 | rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff); | |||
607 | ||||
608 | // Done. | |||
609 | return page::SCOPE_DIRECT; | |||
610 | } | |||
611 | nPage -= nLimit; | |||
612 | ||||
613 | // single indirect. | |||
614 | sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr); | |||
615 | nCount = rDataBlock.singleCount(); | |||
616 | nLimit = nCount * nCapacity; | |||
617 | if (nPage < nLimit) | |||
618 | { | |||
619 | // Page to index reduction. | |||
620 | sal_uInt32 n = nPage; | |||
621 | ||||
622 | // Reduce to single indirect i(1), direct n = i(0). | |||
623 | index1 = n / nCapacity; | |||
624 | index0 = n % nCapacity; | |||
625 | ||||
626 | // Verify reduction. | |||
627 | n = index1 * nCapacity + index0; | |||
628 | OSL_POSTCOND(n == nPage, "wrong math on indirect indices")do { if (true && (!(n == nPage))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "628" ": "), "%s", "wrong math on indirect indices"); } } while (false); | |||
629 | if (n != nPage) | |||
630 | return page::SCOPE_UNKNOWN; | |||
631 | ||||
632 | // Setup LinkDescriptor indices. | |||
633 | rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff); | |||
634 | rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff); | |||
635 | ||||
636 | // Done. | |||
637 | return page::SCOPE_SINGLE; | |||
638 | } | |||
639 | nPage -= nLimit; | |||
640 | ||||
641 | // double indirect. | |||
642 | nCount = rDataBlock.doubleCount(); | |||
643 | nLimit = nCount * nCapacity * nCapacity; | |||
644 | if (nPage < nLimit) | |||
645 | { | |||
646 | // Page to index reduction. | |||
647 | sal_uInt32 n = nPage; | |||
648 | ||||
649 | // Reduce to double indirect i(2), single indirect n = i(0). | |||
650 | index2 = n / (nCapacity * nCapacity); | |||
651 | n = n % (nCapacity * nCapacity); | |||
652 | ||||
653 | // Reduce to single indirect i(1), direct n = i(0). | |||
654 | index1 = n / nCapacity; | |||
655 | index0 = n % nCapacity; | |||
656 | ||||
657 | // Verify reduction. | |||
658 | n = index2 * nCapacity * nCapacity + | |||
659 | index1 * nCapacity + index0; | |||
660 | OSL_POSTCOND(n == nPage, "wrong math on double indirect indices")do { if (true && (!(n == nPage))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "660" ": "), "%s", "wrong math on double indirect indices" ); } } while (false); | |||
661 | if (n != nPage) | |||
662 | return page::SCOPE_UNKNOWN; | |||
663 | ||||
664 | // Setup LinkDescriptor indices. | |||
665 | rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff); | |||
666 | rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff); | |||
667 | rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff); | |||
668 | ||||
669 | // Done. | |||
670 | return page::SCOPE_DOUBLE; | |||
671 | } | |||
672 | nPage -= nLimit; | |||
673 | ||||
674 | // triple indirect. | |||
675 | nCount = rDataBlock.tripleCount(); | |||
676 | nLimit = nCount * nCapacity * nCapacity * nCapacity; | |||
677 | if (nPage < nLimit) | |||
678 | { | |||
679 | // Page to index reduction. | |||
680 | sal_uInt32 n = nPage; | |||
681 | ||||
682 | // Reduce to triple indirect i(3), double indirect n. | |||
683 | index3 = n / (nCapacity * nCapacity * nCapacity); | |||
684 | n = n % (nCapacity * nCapacity * nCapacity); | |||
685 | ||||
686 | // Reduce to double indirect i(2), single indirect n. | |||
687 | index2 = n / (nCapacity * nCapacity); | |||
688 | n = n % (nCapacity * nCapacity); | |||
689 | ||||
690 | // Reduce to single indirect i(1), direct n = i(0). | |||
691 | index1 = n / nCapacity; | |||
692 | index0 = n % nCapacity; | |||
693 | ||||
694 | // Verify reduction. | |||
695 | n = index3 * nCapacity * nCapacity * nCapacity + | |||
696 | index2 * nCapacity * nCapacity + | |||
697 | index1 * nCapacity + index0; | |||
698 | OSL_POSTCOND(n == nPage, "wrong math on triple indirect indices")do { if (true && (!(n == nPage))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "698" ": "), "%s", "wrong math on triple indirect indices" ); } } while (false); | |||
699 | if (n != nPage) | |||
700 | return page::SCOPE_UNKNOWN; | |||
701 | ||||
702 | // Setup LinkDescriptor indices. | |||
703 | rDescr.m_nIndex0 = (sal_uInt16)(index0 & 0xffff); | |||
704 | rDescr.m_nIndex1 = (sal_uInt16)(index1 & 0xffff); | |||
705 | rDescr.m_nIndex2 = (sal_uInt16)(index2 & 0xffff); | |||
706 | rDescr.m_nIndex3 = (sal_uInt16)(index3 & 0xffff); | |||
707 | ||||
708 | // Done. | |||
709 | return page::SCOPE_TRIPLE; | |||
710 | } | |||
711 | ||||
712 | // Unreachable (more than triple indirect). | |||
713 | return page::SCOPE_UNREACHABLE; | |||
714 | } | |||
715 | ||||
716 | /* | |||
717 | * read (external data page). | |||
718 | */ | |||
719 | storeError OStoreDirectoryPageObject::read ( | |||
720 | sal_uInt32 nPage, | |||
721 | OStoreDataPageObject &rData, | |||
722 | OStorePageBIOS &rBIOS) | |||
723 | { | |||
724 | // Determine scope and link indices. | |||
725 | page::DataBlock::LinkDescriptor aLink; | |||
726 | page::ChunkScope eScope = scope (nPage, aLink); | |||
727 | ||||
728 | storeError eErrCode = store_E_None; | |||
729 | if (eScope == page::SCOPE_DIRECT) | |||
730 | { | |||
731 | sal_uInt32 const nAddr = directLink (aLink.m_nIndex0); | |||
732 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
733 | return store_E_NotExists; | |||
734 | ||||
735 | eErrCode = rBIOS.loadObjectAt (rData, nAddr); | |||
736 | } | |||
737 | else if (eScope == page::SCOPE_SINGLE) | |||
738 | { | |||
739 | sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1); | |||
740 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
741 | return store_E_NotExists; | |||
742 | ||||
743 | OStoreIndirectionPageObject aSingle; | |||
744 | eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); | |||
745 | if (eErrCode != store_E_None) | |||
746 | return eErrCode; | |||
747 | ||||
748 | eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS); | |||
749 | } | |||
750 | else if (eScope == page::SCOPE_DOUBLE) | |||
751 | { | |||
752 | sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2); | |||
753 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
754 | return store_E_NotExists; | |||
755 | ||||
756 | OStoreIndirectionPageObject aDouble; | |||
757 | eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); | |||
758 | if (eErrCode != store_E_None) | |||
759 | return eErrCode; | |||
760 | ||||
761 | eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); | |||
762 | } | |||
763 | else if (eScope == page::SCOPE_TRIPLE) | |||
764 | { | |||
765 | sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3); | |||
766 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
767 | return store_E_NotExists; | |||
768 | ||||
769 | OStoreIndirectionPageObject aTriple; | |||
770 | eErrCode = rBIOS.loadObjectAt (aTriple, nAddr); | |||
771 | if (eErrCode != store_E_None) | |||
772 | return eErrCode; | |||
773 | ||||
774 | eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); | |||
775 | } | |||
776 | else if (eScope == page::SCOPE_UNREACHABLE) | |||
777 | { | |||
778 | // Out of scope. | |||
779 | eErrCode = store_E_CantSeek; | |||
780 | } | |||
781 | else | |||
782 | { | |||
783 | // Unknown scope. | |||
784 | OSL_TRACE("OStoreDirectoryPageObject::get(): scope failed")do { if (true && (1 > 0)) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "784" ": "), "OStoreDirectoryPageObject::get(): scope failed" ); } } while (false); | |||
785 | eErrCode = store_E_Unknown; | |||
786 | } | |||
787 | ||||
788 | // Leave. | |||
789 | return eErrCode; | |||
790 | } | |||
791 | ||||
792 | /* | |||
793 | * write (external data page). | |||
794 | */ | |||
795 | storeError OStoreDirectoryPageObject::write ( | |||
796 | sal_uInt32 nPage, | |||
797 | OStoreDataPageObject &rData, | |||
798 | OStorePageBIOS &rBIOS) | |||
799 | { | |||
800 | // Determine scope and link indices. | |||
801 | page::DataBlock::LinkDescriptor aLink; | |||
802 | page::ChunkScope eScope = scope (nPage, aLink); | |||
803 | ||||
804 | storeError eErrCode = store_E_None; | |||
805 | if (eScope == page::SCOPE_DIRECT) | |||
| ||||
806 | { | |||
807 | sal_uInt32 const nAddr = directLink (aLink.m_nIndex0); | |||
808 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) | |||
809 | { | |||
810 | // Allocate data page. | |||
811 | eErrCode = rBIOS.allocate (rData); | |||
812 | if (eErrCode != store_E_None) | |||
813 | return eErrCode; | |||
814 | ||||
815 | // Store data page location. | |||
816 | directLink (aLink.m_nIndex0, rData.location()); | |||
817 | } | |||
818 | else | |||
819 | { | |||
820 | // Save data page. | |||
821 | eErrCode = rBIOS.saveObjectAt (rData, nAddr); | |||
822 | } | |||
823 | } | |||
824 | else if (eScope == page::SCOPE_SINGLE) | |||
825 | { | |||
826 | OStoreIndirectionPageObject aSingle; | |||
827 | eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS); | |||
828 | if (eErrCode != store_E_None) | |||
829 | { | |||
830 | if (eErrCode != store_E_Pending) | |||
831 | return eErrCode; | |||
832 | singleLink (aLink.m_nIndex1, aSingle.location()); | |||
833 | } | |||
834 | ||||
835 | eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS); | |||
836 | } | |||
837 | else if (eScope == page::SCOPE_DOUBLE) | |||
838 | { | |||
839 | OStoreIndirectionPageObject aDouble; | |||
840 | eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS); | |||
841 | if (eErrCode != store_E_None) | |||
842 | { | |||
843 | if (eErrCode != store_E_Pending) | |||
844 | return eErrCode; | |||
845 | doubleLink (aLink.m_nIndex2, aDouble.location()); | |||
846 | } | |||
847 | ||||
848 | eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); | |||
849 | } | |||
850 | else if (eScope == page::SCOPE_TRIPLE) | |||
851 | { | |||
852 | OStoreIndirectionPageObject aTriple; | |||
853 | eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS); | |||
854 | if (eErrCode != store_E_None) | |||
855 | { | |||
856 | if (eErrCode != store_E_Pending) | |||
857 | return eErrCode; | |||
858 | tripleLink (aLink.m_nIndex3, aTriple.location()); | |||
859 | } | |||
860 | ||||
861 | eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); | |||
862 | } | |||
863 | else if (eScope == page::SCOPE_UNREACHABLE) | |||
864 | { | |||
865 | // Out of scope. | |||
866 | eErrCode = store_E_CantSeek; | |||
867 | } | |||
868 | else | |||
869 | { | |||
870 | // Unknown scope. | |||
871 | OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed")do { if (true && (1 > 0)) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "871" ": "), "OStoreDirectoryPageObject::put(): scope failed" ); } } while (false); | |||
872 | eErrCode = store_E_Unknown; | |||
873 | } | |||
874 | ||||
875 | // Leave. | |||
876 | return eErrCode; | |||
877 | } | |||
878 | ||||
879 | /* | |||
880 | * truncate (external data page). | |||
881 | */ | |||
882 | storeError OStoreDirectoryPageObject::truncate ( | |||
883 | sal_uInt32 nPage, | |||
884 | OStorePageBIOS &rBIOS) | |||
885 | { | |||
886 | // Determine scope and link indices. | |||
887 | page::DataBlock::LinkDescriptor aLink; | |||
888 | page::ChunkScope eScope = scope (nPage, aLink); | |||
889 | ||||
890 | storeError eErrCode = store_E_None; | |||
891 | if (eScope == page::SCOPE_DIRECT) | |||
892 | { | |||
893 | // Truncate all triple indirect pages. | |||
894 | eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); | |||
895 | if (eErrCode != store_E_None) | |||
896 | return eErrCode; | |||
897 | ||||
898 | // Truncate all double indirect pages. | |||
899 | eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS); | |||
900 | if (eErrCode != store_E_None) | |||
901 | return eErrCode; | |||
902 | ||||
903 | // Truncate all single indirect pages. | |||
904 | eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS); | |||
905 | if (eErrCode != store_E_None) | |||
906 | return eErrCode; | |||
907 | ||||
908 | // Truncate direct pages, including 'aLink.m_nIndex0'. | |||
909 | eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS); | |||
910 | } | |||
911 | else if (eScope == page::SCOPE_SINGLE) | |||
912 | { | |||
913 | // Truncate all triple indirect pages. | |||
914 | eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); | |||
915 | if (eErrCode != store_E_None) | |||
916 | return eErrCode; | |||
917 | ||||
918 | // Truncate all double indirect pages. | |||
919 | eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS); | |||
920 | if (eErrCode != store_E_None) | |||
921 | return eErrCode; | |||
922 | ||||
923 | // Truncate single indirect pages, downto 'aLink.m_nIndex1'. | |||
924 | eErrCode = truncate (eScope, aLink.m_nIndex1 + 1, rBIOS); | |||
925 | if (eErrCode != store_E_None) | |||
926 | return eErrCode; | |||
927 | ||||
928 | // Truncate last single indirect page to ... pages. | |||
929 | eErrCode = store_truncate_Impl (singleLink (aLink.m_nIndex1), aLink.m_nIndex0, rBIOS); | |||
930 | if (eErrCode != store_E_None) | |||
931 | return eErrCode; | |||
932 | ||||
933 | // Check for complete truncation. | |||
934 | if (aLink.m_nIndex0 == 0) | |||
935 | { | |||
936 | // Clear pointer to last single indirect page. | |||
937 | singleLink (aLink.m_nIndex1, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
938 | } | |||
939 | } | |||
940 | else if (eScope == page::SCOPE_DOUBLE) | |||
941 | { | |||
942 | // Truncate all triple indirect pages. | |||
943 | eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); | |||
944 | if (eErrCode != store_E_None) | |||
945 | return eErrCode; | |||
946 | ||||
947 | // Truncate double indirect pages, downto 'aLink.m_nIndex2'. | |||
948 | eErrCode = truncate (eScope, aLink.m_nIndex2 + 1, rBIOS); | |||
949 | if (eErrCode != store_E_None) | |||
950 | return eErrCode; | |||
951 | ||||
952 | // Truncate last double indirect page to ... pages. | |||
953 | eErrCode = store_truncate_Impl ( | |||
954 | doubleLink (aLink.m_nIndex2), aLink.m_nIndex1, aLink.m_nIndex0, rBIOS); | |||
955 | if (eErrCode != store_E_None) | |||
956 | return eErrCode; | |||
957 | ||||
958 | // Check for complete truncation. | |||
959 | if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0) | |||
960 | { | |||
961 | // Clear pointer to last double indirect page. | |||
962 | doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
963 | } | |||
964 | } | |||
965 | else if (eScope == page::SCOPE_TRIPLE) | |||
966 | { | |||
967 | // Truncate triple indirect pages, downto 'aLink.m_nIndex3'. | |||
968 | eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS); | |||
969 | if (eErrCode != store_E_None) | |||
970 | return eErrCode; | |||
971 | ||||
972 | // Truncate last triple indirect page to ... pages. | |||
973 | eErrCode = store_truncate_Impl ( | |||
974 | tripleLink (aLink.m_nIndex3), aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rBIOS); | |||
975 | if (eErrCode != store_E_None) | |||
976 | return eErrCode; | |||
977 | ||||
978 | // Check for complete truncation. | |||
979 | if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0) | |||
980 | { | |||
981 | // Clear pointer to last triple indirect page. | |||
982 | tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
983 | } | |||
984 | } | |||
985 | else if (eScope == page::SCOPE_UNREACHABLE) | |||
986 | { | |||
987 | // Out of scope. | |||
988 | eErrCode = store_E_CantSeek; | |||
989 | } | |||
990 | else | |||
991 | { | |||
992 | // Unknown scope. | |||
993 | OSL_TRACE("OStoreDirectoryPageObject::put(): scope failed")do { if (true && (1 > 0)) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_INFO), ("legacy.osl"), ("/usr/local/src/libreoffice/store/source/stordata.cxx" ":" "993" ": "), "OStoreDirectoryPageObject::put(): scope failed" ); } } while (false); | |||
994 | eErrCode = store_E_Unknown; | |||
995 | } | |||
996 | ||||
997 | // Leave. | |||
998 | return eErrCode; | |||
999 | } | |||
1000 | ||||
1001 | /* | |||
1002 | * truncate (external data page scope; private). | |||
1003 | */ | |||
1004 | storeError OStoreDirectoryPageObject::truncate ( | |||
1005 | page::ChunkScope eScope, | |||
1006 | sal_uInt16 nRemain, | |||
1007 | OStorePageBIOS &rBIOS) | |||
1008 | { | |||
1009 | OStoreDirectoryDataBlock const & rDataBlock = PAGE().m_aDataBlock; | |||
1010 | ||||
1011 | // Enter. | |||
1012 | storeError eErrCode = store_E_None; | |||
1013 | if (eScope == page::SCOPE_DIRECT) | |||
1014 | { | |||
1015 | // Truncate direct data pages. | |||
1016 | sal_uInt16 i, n = rDataBlock.directCount(); | |||
1017 | for (i = n; i > nRemain; i--) | |||
1018 | { | |||
1019 | // Obtain data page location. | |||
1020 | sal_uInt32 nAddr = directLink (i - 1); | |||
1021 | if (nAddr == STORE_PAGE_NULL((sal_uInt32)(~0))) continue; | |||
1022 | ||||
1023 | // Free data page. | |||
1024 | eErrCode = rBIOS.free (nAddr); | |||
1025 | if (eErrCode != store_E_None) | |||
1026 | break; | |||
1027 | ||||
1028 | // Clear pointer to data page. | |||
1029 | directLink (i - 1, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
1030 | } | |||
1031 | ||||
1032 | // Done. | |||
1033 | return eErrCode; | |||
1034 | } | |||
1035 | ||||
1036 | if (eScope == page::SCOPE_SINGLE) | |||
1037 | { | |||
1038 | // Truncate single indirect pages. | |||
1039 | sal_uInt16 i, n = rDataBlock.singleCount(); | |||
1040 | for (i = n; i > nRemain; i--) | |||
1041 | { | |||
1042 | // Truncate single indirect page to zero data pages. | |||
1043 | eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS); | |||
1044 | if (eErrCode != store_E_None) | |||
1045 | break; | |||
1046 | ||||
1047 | // Clear pointer to single indirect page. | |||
1048 | singleLink (i - 1, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
1049 | } | |||
1050 | ||||
1051 | // Done. | |||
1052 | return eErrCode; | |||
1053 | } | |||
1054 | ||||
1055 | if (eScope == page::SCOPE_DOUBLE) | |||
1056 | { | |||
1057 | // Truncate double indirect pages. | |||
1058 | sal_uInt16 i, n = rDataBlock.doubleCount(); | |||
1059 | for (i = n; i > nRemain; i--) | |||
1060 | { | |||
1061 | // Truncate double indirect page to zero single indirect pages. | |||
1062 | eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS); | |||
1063 | if (eErrCode != store_E_None) | |||
1064 | break; | |||
1065 | ||||
1066 | // Clear pointer to double indirect page. | |||
1067 | doubleLink (i - 1, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
1068 | } | |||
1069 | ||||
1070 | // Done. | |||
1071 | return eErrCode; | |||
1072 | } | |||
1073 | ||||
1074 | if (eScope == page::SCOPE_TRIPLE) | |||
1075 | { | |||
1076 | // Truncate triple indirect pages. | |||
1077 | sal_uInt16 i, n = rDataBlock.tripleCount(); | |||
1078 | for (i = n; i > nRemain; i--) | |||
1079 | { | |||
1080 | // Truncate to zero double indirect pages. | |||
1081 | eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS); | |||
1082 | if (eErrCode != store_E_None) | |||
1083 | break; | |||
1084 | ||||
1085 | // Clear pointer to triple indirect page. | |||
1086 | tripleLink (i - 1, STORE_PAGE_NULL((sal_uInt32)(~0))); | |||
1087 | } | |||
1088 | ||||
1089 | // Done. | |||
1090 | return eErrCode; | |||
1091 | } | |||
1092 | ||||
1093 | // Invalid scope. | |||
1094 | return store_E_InvalidAccess; | |||
1095 | } | |||
1096 | ||||
1097 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |