1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | #include "storlckb.hxx" |
22 | |
23 | #include "sal/types.h" |
24 | #include "sal/macros.h" |
25 | #include "rtl/string.h" |
26 | #include "rtl/ref.hxx" |
27 | #include "osl/mutex.hxx" |
28 | |
29 | #include "store/types.h" |
30 | #include "object.hxx" |
31 | |
32 | #include "storbase.hxx" |
33 | #include "stordata.hxx" |
34 | #include "storpage.hxx" |
35 | |
36 | using namespace store; |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | const sal_uInt32 OStoreLockBytes::m_nTypeId = sal_uInt32(0x94190310); |
44 | |
45 | |
46 | |
47 | |
48 | OStoreLockBytes::OStoreLockBytes (void) |
49 | : m_xManager (), |
50 | m_xNode (), |
51 | m_bWriteable (false) |
52 | { |
53 | } |
54 | |
55 | |
56 | |
57 | |
58 | OStoreLockBytes::~OStoreLockBytes (void) |
59 | { |
60 | if (m_xManager.is() && m_xNode.is()) |
61 | { |
62 | m_xManager->releasePage(m_xNode->m_aDescr); |
63 | } |
64 | } |
65 | |
66 | |
67 | |
68 | |
69 | sal_Bool SAL_CALL OStoreLockBytes::isKindOf (sal_uInt32 nTypeId) |
70 | { |
71 | return (nTypeId == m_nTypeId); |
72 | } |
73 | |
74 | |
75 | |
76 | |
77 | storeError OStoreLockBytes::create ( |
78 | OStorePageManager *pManager, |
79 | rtl_String *pPath, |
80 | rtl_String *pName, |
81 | storeAccessMode eMode) |
82 | { |
83 | rtl::Reference<OStorePageManager> xManager (pManager); |
84 | if (!xManager.is()) |
85 | return store_E_InvalidAccess; |
86 | |
87 | if (!(pPath && pName)) |
88 | return store_E_InvalidParameter; |
89 | |
90 | OStoreDirectoryPageObject aPage; |
91 | storeError eErrCode = xManager->iget ( |
92 | aPage, STORE_ATTRIB_ISFILE((sal_uInt32)0x40000000), |
93 | pPath, pName, eMode); |
94 | if (eErrCode != store_E_None) |
95 | return eErrCode; |
96 | |
97 | if (!(aPage.attrib() & STORE_ATTRIB_ISFILE((sal_uInt32)0x40000000))) |
98 | { |
99 | |
100 | if (aPage.attrib() & STORE_ATTRIB_ISLINK((sal_uInt32)0x10000000)) |
101 | return store_E_NotFile; |
102 | } |
103 | |
104 | |
105 | inode_holder_type xNode (aPage.get()); |
106 | if (eMode != store_AccessReadOnly) |
107 | eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite); |
108 | else |
109 | eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly); |
110 | if (eErrCode != store_E_None) |
111 | return eErrCode; |
112 | |
113 | |
114 | m_xManager = xManager; |
115 | m_xNode = xNode; |
116 | m_bWriteable = (eMode != store_AccessReadOnly); |
117 | |
118 | |
119 | if (eMode == store_AccessCreate) |
120 | { |
121 | |
122 | eErrCode = setSize(0); |
123 | } |
124 | return eErrCode; |
125 | } |
126 | |
127 | |
128 | |
129 | |
130 | storeError OStoreLockBytes::readAt ( |
131 | sal_uInt32 nOffset, |
132 | void *pBuffer, |
133 | sal_uInt32 nBytes, |
134 | sal_uInt32 &rnDone) |
135 | { |
136 | rnDone = 0; |
137 | |
138 | if (!m_xManager.is()) |
| |
139 | return store_E_InvalidAccess; |
140 | |
141 | if (!pBuffer) |
| |
142 | return store_E_InvalidParameter; |
143 | if (!nBytes) |
| |
144 | return store_E_None; |
145 | |
146 | |
147 | osl::MutexGuard aGuard (*m_xManager); |
148 | |
149 | |
150 | OStoreDirectoryPageObject aPage (m_xNode.get()); |
151 | |
152 | sal_uInt32 nDataLen = aPage.dataLength(); |
153 | if ((nOffset + nBytes) > nDataLen) |
| |
154 | nBytes = nDataLen - nOffset; |
155 | |
156 | |
157 | OStoreDataPageObject aData; |
158 | sal_uInt8 *pData = (sal_uInt8*)pBuffer; |
159 | while ((0 < nBytes) && (nOffset < nDataLen)) |
| 5 | | Loop condition is true. Entering loop body | |
|
160 | { |
161 | |
162 | inode::ChunkScope eScope = m_xNode->scope (nOffset); |
| 6 | | Called C++ object pointer is null |
|
163 | if (eScope == inode::SCOPE_INTERNAL) |
164 | { |
165 | |
166 | inode::ChunkDescriptor aDescr ( |
167 | nOffset, m_xNode->capacity()); |
168 | |
169 | sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); |
170 | nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes)); |
171 | |
172 | memcpy ( |
173 | &pData[rnDone], |
174 | &m_xNode->m_pData[aDescr.m_nOffset], |
175 | nLength); |
176 | |
177 | |
178 | rnDone += nLength; |
179 | nOffset += nLength; |
180 | nBytes -= nLength; |
181 | } |
182 | else |
183 | { |
184 | |
185 | inode::ChunkDescriptor aDescr ( |
186 | nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); |
187 | |
188 | sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); |
189 | nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes)); |
190 | |
191 | storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager); |
192 | if (eErrCode != store_E_None) |
193 | { |
194 | if (eErrCode != store_E_NotExists) |
195 | return eErrCode; |
196 | |
197 | memset ( |
198 | &pData[rnDone], |
199 | 0, |
200 | nLength); |
201 | } |
202 | else |
203 | { |
204 | PageHolderObject< data > xData (aData.makeHolder<data>()); |
205 | memcpy ( |
206 | &pData[rnDone], |
207 | &xData->m_pData[aDescr.m_nOffset], |
208 | nLength); |
209 | } |
210 | |
211 | |
212 | rnDone += nLength; |
213 | nOffset += nLength; |
214 | nBytes -= nLength; |
215 | } |
216 | } |
217 | |
218 | |
219 | return store_E_None; |
220 | } |
221 | |
222 | |
223 | |
224 | |
225 | storeError OStoreLockBytes::writeAt ( |
226 | sal_uInt32 nOffset, |
227 | const void *pBuffer, |
228 | sal_uInt32 nBytes, |
229 | sal_uInt32 &rnDone) |
230 | { |
231 | rnDone = 0; |
232 | |
233 | if (!m_xManager.is()) |
234 | return store_E_InvalidAccess; |
235 | if (!m_bWriteable) |
236 | return store_E_AccessViolation; |
237 | |
238 | if (!pBuffer) |
239 | return store_E_InvalidParameter; |
240 | if (!nBytes) |
241 | return store_E_None; |
242 | |
243 | |
244 | osl::MutexGuard aGuard (*m_xManager); |
245 | |
246 | |
247 | OStoreDirectoryPageObject aPage (m_xNode.get()); |
248 | const sal_uInt8 *pData = (const sal_uInt8*)pBuffer; |
249 | |
250 | storeError eErrCode = store_E_None; |
251 | while (nBytes > 0) |
252 | { |
253 | |
254 | inode::ChunkScope eScope = m_xNode->scope (nOffset); |
255 | if (eScope == inode::SCOPE_INTERNAL) |
256 | { |
257 | |
258 | inode::ChunkDescriptor aDescr ( |
259 | nOffset, m_xNode->capacity()); |
260 | |
261 | sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); |
262 | nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes)); |
263 | |
264 | memcpy ( |
265 | &m_xNode->m_pData[aDescr.m_nOffset], |
266 | &pData[rnDone], nLength); |
267 | |
268 | |
269 | aPage.touch(); |
270 | |
271 | |
272 | rnDone += nLength; |
273 | nOffset += nLength; |
274 | nBytes -= nLength; |
275 | |
276 | |
277 | if (aPage.dataLength() < nOffset) |
278 | aPage.dataLength (nOffset); |
279 | } |
280 | else |
281 | { |
282 | |
283 | OStoreDataPageObject aData; |
284 | |
285 | inode::ChunkDescriptor aDescr ( |
286 | nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); |
287 | |
288 | sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); |
289 | if ((aDescr.m_nOffset > 0) || (nBytes < nLength)) |
290 | { |
291 | |
292 | |
293 | eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager); |
294 | if (eErrCode != store_E_None) |
295 | { |
296 | if (eErrCode != store_E_NotExists) |
297 | return eErrCode; |
298 | |
299 | eErrCode = aData.construct<data>(m_xManager->allocator()); |
300 | if (eErrCode != store_E_None) |
301 | return eErrCode; |
302 | } |
303 | } |
304 | |
305 | PageHolderObject< data > xData (aData.makeHolder<data>()); |
306 | if (!xData.is()) |
307 | { |
308 | eErrCode = aData.construct<data>(m_xManager->allocator()); |
309 | if (eErrCode != store_E_None) |
310 | return eErrCode; |
311 | xData = aData.makeHolder<data>(); |
312 | } |
313 | |
314 | |
315 | nLength = SAL_MIN(nLength, nBytes)(((nLength) < (nBytes)) ? (nLength) : (nBytes)); |
316 | memcpy ( |
317 | &xData->m_pData[aDescr.m_nOffset], |
318 | &pData[rnDone], nLength); |
319 | |
320 | |
321 | eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager); |
322 | if (eErrCode != store_E_None) |
323 | return eErrCode; |
324 | |
325 | |
326 | rnDone += nLength; |
327 | nOffset += nLength; |
328 | nBytes -= nLength; |
329 | |
330 | |
331 | if (aPage.dataLength() < nOffset) |
332 | aPage.dataLength (nOffset); |
333 | } |
334 | } |
335 | |
336 | |
337 | if (aPage.dirty()) |
338 | return m_xManager->saveObjectAt (aPage, aPage.location()); |
339 | else |
340 | return store_E_None; |
341 | } |
342 | |
343 | |
344 | |
345 | |
346 | storeError OStoreLockBytes::flush (void) |
347 | { |
348 | if (!m_xManager.is()) |
349 | return store_E_InvalidAccess; |
350 | |
351 | return m_xManager->flush(); |
352 | } |
353 | |
354 | |
355 | |
356 | |
357 | storeError OStoreLockBytes::setSize (sal_uInt32 nSize) |
358 | { |
359 | if (!m_xManager.is()) |
360 | return store_E_InvalidAccess; |
361 | if (!m_bWriteable) |
362 | return store_E_AccessViolation; |
363 | |
364 | |
365 | osl::MutexGuard aGuard (*m_xManager); |
366 | |
367 | |
368 | OStoreDirectoryPageObject aPage (m_xNode.get()); |
369 | sal_uInt32 nDataLen = aPage.dataLength(); |
370 | |
371 | if (nSize == nDataLen) |
372 | return store_E_None; |
373 | |
374 | if (nSize < nDataLen) |
375 | { |
376 | |
377 | storeError eErrCode = store_E_None; |
378 | |
379 | |
380 | inode::ChunkScope eSizeScope = m_xNode->scope (nSize); |
381 | if (eSizeScope == inode::SCOPE_INTERNAL) |
382 | { |
383 | |
384 | inode::ChunkScope eDataScope = m_xNode->scope (nDataLen); |
385 | if (eDataScope == inode::SCOPE_EXTERNAL) |
386 | { |
387 | |
388 | eErrCode = aPage.truncate (0, *m_xManager); |
389 | if (eErrCode != store_E_None) |
390 | return eErrCode; |
391 | } |
392 | |
393 | |
394 | inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity()); |
395 | memset ( |
396 | &(m_xNode->m_pData[aDescr.m_nOffset]), |
397 | 0, aDescr.m_nLength); |
398 | } |
399 | else |
400 | { |
401 | |
402 | inode::ChunkDescriptor aDescr ( |
403 | nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); |
404 | |
405 | sal_uInt32 nPage = aDescr.m_nPage; |
406 | if (aDescr.m_nOffset) nPage += 1; |
407 | |
408 | eErrCode = aPage.truncate (nPage, *m_xManager); |
409 | if (eErrCode != store_E_None) |
410 | return eErrCode; |
411 | } |
412 | } |
413 | |
414 | |
415 | aPage.dataLength (nSize); |
416 | |
417 | |
418 | return m_xManager->saveObjectAt (aPage, aPage.location()); |
419 | } |
420 | |
421 | |
422 | |
423 | |
424 | storeError OStoreLockBytes::stat (sal_uInt32 &rnSize) |
425 | { |
426 | rnSize = 0; |
427 | |
428 | if (!m_xManager.is()) |
429 | return store_E_InvalidAccess; |
430 | |
431 | OStoreDirectoryPageObject aPage (m_xNode.get()); |
432 | rnSize = aPage.dataLength(); |
433 | return store_E_None; |
434 | } |
435 | |
436 | |