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