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 */ 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 */ 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 */ 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 */ 119 sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId) 120 { 121 return (nTypeId == m_nTypeId); 122 } 123 124 /* 125 * create. 126 */ 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 */ 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