Line data Source code
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 "stordir.hxx"
22 :
23 : #include <sal/types.h>
24 :
25 : #include <rtl/textcvt.h>
26 : #include <rtl/ref.hxx>
27 :
28 : #include <osl/mutex.hxx>
29 :
30 : #include "store/types.h"
31 : #include "object.hxx"
32 :
33 : #include "storbase.hxx"
34 : #include "stordata.hxx"
35 : #include "storpage.hxx"
36 :
37 : using namespace store;
38 :
39 : /*========================================================================
40 : *
41 : * OStore... internals.
42 : *
43 : *======================================================================*/
44 : /*
45 : * __store_convertTextToUnicode.
46 : */
47 155617 : inline sal_Size __store_convertTextToUnicode (
48 : rtl_TextToUnicodeConverter hConverter,
49 : const sal_Char *pSrcBuffer, sal_Size nSrcLength,
50 : sal_Unicode *pDstBuffer, sal_Size nDstLength)
51 : {
52 155617 : sal_uInt32 nCvtInfo = 0;
53 155617 : sal_Size nCvtBytes = 0;
54 : return rtl_convertTextToUnicode (
55 : hConverter, 0,
56 : pSrcBuffer, nSrcLength,
57 : pDstBuffer, nDstLength,
58 : OSTRING_TO_OUSTRING_CVTFLAGS,
59 155617 : &nCvtInfo, &nCvtBytes);
60 : }
61 :
62 : /*========================================================================
63 : *
64 : * OStoreDirectory_Impl implementation.
65 : *
66 : *======================================================================*/
67 : const sal_uInt32 OStoreDirectory_Impl::m_nTypeId = sal_uInt32(0x89191107);
68 :
69 : /*
70 : * OStoreDirectory_Impl.
71 : */
72 666113 : OStoreDirectory_Impl::OStoreDirectory_Impl (void)
73 : : m_xManager (),
74 : m_aDescr (0, 0, 0),
75 : m_nPath (0),
76 666113 : m_hTextCvt (NULL)
77 666113 : {}
78 :
79 : /*
80 : * ~OStoreDirectory_Impl.
81 : */
82 1998339 : OStoreDirectory_Impl::~OStoreDirectory_Impl (void)
83 : {
84 666113 : if (m_xManager.is())
85 : {
86 282672 : if (m_aDescr.m_nAddr != STORE_PAGE_NULL)
87 282672 : m_xManager->releasePage (m_aDescr);
88 : }
89 666113 : rtl_destroyTextToUnicodeConverter (m_hTextCvt);
90 1332226 : }
91 :
92 : /*
93 : * isKindOf.
94 : */
95 238646 : sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId)
96 : {
97 238646 : return (nTypeId == m_nTypeId);
98 : }
99 :
100 : /*
101 : * create.
102 : */
103 666113 : storeError OStoreDirectory_Impl::create (
104 : OStorePageManager *pManager,
105 : rtl_String *pPath,
106 : rtl_String *pName,
107 : storeAccessMode eMode)
108 : {
109 666113 : rtl::Reference<OStorePageManager> xManager (pManager);
110 666113 : if (!xManager.is())
111 0 : return store_E_InvalidAccess;
112 :
113 666113 : if (!(pPath && pName))
114 0 : return store_E_InvalidParameter;
115 :
116 666113 : OStoreDirectoryPageObject aPage;
117 : storeError eErrCode = xManager->iget (
118 : aPage, STORE_ATTRIB_ISDIR,
119 666113 : pPath, pName, eMode);
120 666113 : if (eErrCode != store_E_None)
121 383441 : return eErrCode;
122 :
123 282672 : if (!(aPage.attrib() & STORE_ATTRIB_ISDIR))
124 0 : return store_E_NotDirectory;
125 :
126 282672 : inode_holder_type xNode (aPage.get());
127 282672 : eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly);
128 282672 : if (eErrCode != store_E_None)
129 0 : return eErrCode;
130 :
131 : // Evaluate iteration path.
132 282672 : m_nPath = aPage.path();
133 282672 : m_nPath = rtl_crc32 (m_nPath, "/", 1);
134 :
135 : // Save page manager, and descriptor.
136 282672 : m_xManager = xManager;
137 282672 : m_aDescr = xNode->m_aDescr;
138 :
139 282672 : return store_E_None;
140 : }
141 :
142 : /*
143 : * iterate.
144 : */
145 238646 : storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData)
146 : {
147 238646 : if (!m_xManager.is())
148 0 : return store_E_InvalidAccess;
149 :
150 238646 : storeError eErrCode = store_E_NoMoreFiles;
151 238646 : if (!rFindData.m_nReserved)
152 0 : return eErrCode;
153 :
154 : // Acquire exclusive access.
155 238646 : osl::MutexGuard aGuard (*m_xManager);
156 :
157 : // Check TextConverter.
158 238646 : if (m_hTextCvt == NULL)
159 83029 : m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8);
160 :
161 : // Setup iteration key.
162 238646 : OStorePageKey aKey (rFindData.m_nReserved, m_nPath);
163 :
164 : // Iterate.
165 0 : for (;;)
166 : {
167 238646 : OStorePageLink aLink;
168 238646 : eErrCode = m_xManager->iterate (aKey, aLink, rFindData.m_nAttrib);
169 238646 : if (!((eErrCode == store_E_None) && (aKey.m_nHigh == store::htonl(m_nPath))))
170 : break;
171 :
172 155617 : if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK))
173 : {
174 : // Load page.
175 155617 : OStoreDirectoryPageObject aPage;
176 155617 : eErrCode = m_xManager->loadObjectAt (aPage, aLink.location());
177 155617 : if (eErrCode == store_E_None)
178 : {
179 155617 : inode_holder_type xNode (aPage.get());
180 :
181 : // Setup FindData.
182 155617 : sal_Char *p = xNode->m_aNameBlock.m_pData;
183 155617 : sal_Size n = rtl_str_getLength (p);
184 155617 : sal_Size k = rFindData.m_nLength;
185 :
186 : n = __store_convertTextToUnicode (
187 : m_hTextCvt, p, n,
188 155617 : rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1);
189 155617 : if (k > n)
190 : {
191 29913 : k = (k - n) * sizeof(sal_Unicode);
192 29913 : memset (&rFindData.m_pszName[n], 0, k);
193 : }
194 :
195 155617 : rFindData.m_nLength = n;
196 155617 : rFindData.m_nAttrib |= aPage.attrib();
197 155617 : rFindData.m_nSize = aPage.dataLength();
198 :
199 : // Leave.
200 155617 : rFindData.m_nReserved = store::ntohl(aKey.m_nLow);
201 155617 : return store_E_None;
202 155617 : }
203 : }
204 :
205 0 : if (aKey.m_nLow == 0)
206 : break;
207 0 : aKey.m_nLow = store::htonl(store::ntohl(aKey.m_nLow) - 1);
208 : }
209 :
210 : // Finished.
211 83029 : memset (&rFindData, 0, sizeof (storeFindData));
212 83029 : return store_E_NoMoreFiles;
213 : }
214 :
215 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|