1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_store.hxx"
26
27 #include "stordir.hxx"
28
29 #ifndef _SAL_TYPES_H_
30 #include <sal/types.h>
31 #endif
32
33 #ifndef _RTL_TEXTCVT_H_
34 #include <rtl/textcvt.h>
35 #endif
36 #ifndef _RTL_REF_HXX_
37 #include <rtl/ref.hxx>
38 #endif
39
40 #ifndef _OSL_MUTEX_HXX_
41 #include <osl/mutex.hxx>
42 #endif
43
44 #ifndef _STORE_TYPES_H_
45 #include "store/types.h"
46 #endif
47 #ifndef _STORE_OBJECT_HXX_
48 #include "object.hxx"
49 #endif
50
51 #ifndef _STORE_STORBASE_HXX_
52 #include "storbase.hxx"
53 #endif
54 #ifndef _STORE_STORDATA_HXX_
55 #include "stordata.hxx"
56 #endif
57 #ifndef _STORE_STORPAGE_HXX_
58 #include "storpage.hxx"
59 #endif
60
61 using namespace store;
62
63 /*========================================================================
64 *
65 * OStore... internals.
66 *
67 *======================================================================*/
68 /*
69 * __store_convertTextToUnicode.
70 */
__store_convertTextToUnicode(rtl_TextToUnicodeConverter hConverter,const sal_Char * pSrcBuffer,sal_Size nSrcLength,sal_Unicode * pDstBuffer,sal_Size nDstLength)71 inline sal_Size __store_convertTextToUnicode (
72 rtl_TextToUnicodeConverter hConverter,
73 const sal_Char *pSrcBuffer, sal_Size nSrcLength,
74 sal_Unicode *pDstBuffer, sal_Size nDstLength)
75 {
76 sal_uInt32 nCvtInfo = 0;
77 sal_Size nCvtBytes = 0;
78 return rtl_convertTextToUnicode (
79 hConverter, 0,
80 pSrcBuffer, nSrcLength,
81 pDstBuffer, nDstLength,
82 OSTRING_TO_OUSTRING_CVTFLAGS,
83 &nCvtInfo, &nCvtBytes);
84 }
85
86 /*========================================================================
87 *
88 * OStoreDirectory_Impl implementation.
89 *
90 *======================================================================*/
91 const sal_uInt32 OStoreDirectory_Impl::m_nTypeId = sal_uInt32(0x89191107);
92
93 /*
94 * OStoreDirectory_Impl.
95 */
OStoreDirectory_Impl(void)96 OStoreDirectory_Impl::OStoreDirectory_Impl (void)
97 : m_xManager (),
98 m_aDescr (0, 0, 0),
99 m_nPath (0),
100 m_hTextCvt (NULL)
101 {}
102
103 /*
104 * ~OStoreDirectory_Impl.
105 */
~OStoreDirectory_Impl(void)106 OStoreDirectory_Impl::~OStoreDirectory_Impl (void)
107 {
108 if (m_xManager.is())
109 {
110 if (m_aDescr.m_nAddr != STORE_PAGE_NULL)
111 m_xManager->releasePage (m_aDescr, store_AccessReadOnly);
112 }
113 rtl_destroyTextToUnicodeConverter (m_hTextCvt);
114 }
115
116 /*
117 * isKindOf.
118 */
isKindOf(sal_uInt32 nTypeId)119 sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId)
120 {
121 return (nTypeId == m_nTypeId);
122 }
123
124 /*
125 * create.
126 */
create(OStorePageManager * pManager,rtl_String * pPath,rtl_String * pName,storeAccessMode eMode)127 storeError OStoreDirectory_Impl::create (
128 OStorePageManager *pManager,
129 rtl_String *pPath,
130 rtl_String *pName,
131 storeAccessMode eMode)
132 {
133 rtl::Reference<OStorePageManager> xManager (pManager);
134 if (!xManager.is())
135 return store_E_InvalidAccess;
136
137 if (!(pPath && pName))
138 return store_E_InvalidParameter;
139
140 OStoreDirectoryPageObject aPage;
141 storeError eErrCode = xManager->iget (
142 aPage, STORE_ATTRIB_ISDIR,
143 pPath, pName, eMode);
144 if (eErrCode != store_E_None)
145 return eErrCode;
146
147 if (!(aPage.attrib() & STORE_ATTRIB_ISDIR))
148 return store_E_NotDirectory;
149
150 inode_holder_type xNode (aPage.get());
151 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
152 if (eErrCode != store_E_None)
153 return eErrCode;
154
155 // Evaluate iteration path.
156 m_nPath = aPage.path();
157 m_nPath = rtl_crc32 (m_nPath, "/", 1);
158
159 // Save page manager, and descriptor.
160 m_xManager = xManager;
161 m_aDescr = xNode->m_aDescr;
162
163 return store_E_None;
164 }
165
166 /*
167 * iterate.
168 */
iterate(storeFindData & rFindData)169 storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData)
170 {
171 if (!m_xManager.is())
172 return store_E_InvalidAccess;
173
174 storeError eErrCode = store_E_NoMoreFiles;
175 if (!rFindData.m_nReserved)
176 return eErrCode;
177
178 // Acquire exclusive access.
179 osl::MutexGuard aGuard (*m_xManager);
180
181 // Check TextConverter.
182 if (m_hTextCvt == NULL)
183 m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8);
184
185 // Setup iteration key.
186 OStorePageKey aKey (rFindData.m_nReserved, m_nPath);
187
188 // Iterate.
189 for (;;)
190 {
191 OStorePageLink aLink;
192 eErrCode = m_xManager->iterate (aKey, aLink, rFindData.m_nAttrib);
193 if (!((eErrCode == store_E_None) && (aKey.m_nHigh == store::htonl(m_nPath))))
194 break;
195
196 if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK))
197 {
198 // Load page.
199 OStoreDirectoryPageObject aPage;
200 eErrCode = m_xManager->loadObjectAt (aPage, aLink.location());
201 if (eErrCode == store_E_None)
202 {
203 inode_holder_type xNode (aPage.get());
204
205 // Setup FindData.
206 sal_Char *p = xNode->m_aNameBlock.m_pData;
207 sal_Size n = rtl_str_getLength (p);
208 sal_Size k = rFindData.m_nLength;
209
210 n = __store_convertTextToUnicode (
211 m_hTextCvt, p, n,
212 rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1);
213 if (k > n)
214 {
215 k = (k - n) * sizeof(sal_Unicode);
216 memset (&rFindData.m_pszName[n], 0, k);
217 }
218
219 rFindData.m_nLength = n;
220 rFindData.m_nAttrib |= aPage.attrib();
221 rFindData.m_nSize = aPage.dataLength();
222
223 // Leave.
224 rFindData.m_nReserved = store::ntohl(aKey.m_nLow);
225 return store_E_None;
226 }
227 }
228
229 if (aKey.m_nLow == 0)
230 break;
231 aKey.m_nLow = store::htonl(store::ntohl(aKey.m_nLow) - 1);
232 }
233
234 // Finished.
235 memset (&rFindData, 0, sizeof (storeFindData));
236 return store_E_NoMoreFiles;
237 }
238