1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_store.hxx" 30 31 #include "stordir.hxx" 32 33 #ifndef _SAL_TYPES_H_ 34 #include <sal/types.h> 35 #endif 36 37 #ifndef _RTL_TEXTCVT_H_ 38 #include <rtl/textcvt.h> 39 #endif 40 #ifndef _RTL_REF_HXX_ 41 #include <rtl/ref.hxx> 42 #endif 43 44 #ifndef _OSL_MUTEX_HXX_ 45 #include <osl/mutex.hxx> 46 #endif 47 48 #ifndef _STORE_TYPES_H_ 49 #include "store/types.h" 50 #endif 51 #ifndef _STORE_OBJECT_HXX_ 52 #include "object.hxx" 53 #endif 54 55 #ifndef _STORE_STORBASE_HXX_ 56 #include "storbase.hxx" 57 #endif 58 #ifndef _STORE_STORDATA_HXX_ 59 #include "stordata.hxx" 60 #endif 61 #ifndef _STORE_STORPAGE_HXX_ 62 #include "storpage.hxx" 63 #endif 64 65 using namespace store; 66 67 /*======================================================================== 68 * 69 * OStore... internals. 70 * 71 *======================================================================*/ 72 /* 73 * __store_convertTextToUnicode. 74 */ 75 inline sal_Size __store_convertTextToUnicode ( 76 rtl_TextToUnicodeConverter hConverter, 77 const sal_Char *pSrcBuffer, sal_Size nSrcLength, 78 sal_Unicode *pDstBuffer, sal_Size nDstLength) 79 { 80 sal_uInt32 nCvtInfo = 0; 81 sal_Size nCvtBytes = 0; 82 return rtl_convertTextToUnicode ( 83 hConverter, 0, 84 pSrcBuffer, nSrcLength, 85 pDstBuffer, nDstLength, 86 OSTRING_TO_OUSTRING_CVTFLAGS, 87 &nCvtInfo, &nCvtBytes); 88 } 89 90 /*======================================================================== 91 * 92 * OStoreDirectory_Impl implementation. 93 * 94 *======================================================================*/ 95 const sal_uInt32 OStoreDirectory_Impl::m_nTypeId = sal_uInt32(0x89191107); 96 97 /* 98 * OStoreDirectory_Impl. 99 */ 100 OStoreDirectory_Impl::OStoreDirectory_Impl (void) 101 : m_xManager (), 102 m_aDescr (0, 0, 0), 103 m_nPath (0), 104 m_hTextCvt (NULL) 105 {} 106 107 /* 108 * ~OStoreDirectory_Impl. 109 */ 110 OStoreDirectory_Impl::~OStoreDirectory_Impl (void) 111 { 112 if (m_xManager.is()) 113 { 114 if (m_aDescr.m_nAddr != STORE_PAGE_NULL) 115 m_xManager->releasePage (m_aDescr, store_AccessReadOnly); 116 } 117 rtl_destroyTextToUnicodeConverter (m_hTextCvt); 118 } 119 120 /* 121 * isKindOf. 122 */ 123 sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId) 124 { 125 return (nTypeId == m_nTypeId); 126 } 127 128 /* 129 * create. 130 */ 131 storeError OStoreDirectory_Impl::create ( 132 OStorePageManager *pManager, 133 rtl_String *pPath, 134 rtl_String *pName, 135 storeAccessMode eMode) 136 { 137 rtl::Reference<OStorePageManager> xManager (pManager); 138 if (!xManager.is()) 139 return store_E_InvalidAccess; 140 141 if (!(pPath && pName)) 142 return store_E_InvalidParameter; 143 144 OStoreDirectoryPageObject aPage; 145 storeError eErrCode = xManager->iget ( 146 aPage, STORE_ATTRIB_ISDIR, 147 pPath, pName, eMode); 148 if (eErrCode != store_E_None) 149 return eErrCode; 150 151 if (!(aPage.attrib() & STORE_ATTRIB_ISDIR)) 152 return store_E_NotDirectory; 153 154 inode_holder_type xNode (aPage.get()); 155 eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly); 156 if (eErrCode != store_E_None) 157 return eErrCode; 158 159 // Evaluate iteration path. 160 m_nPath = aPage.path(); 161 m_nPath = rtl_crc32 (m_nPath, "/", 1); 162 163 // Save page manager, and descriptor. 164 m_xManager = xManager; 165 m_aDescr = xNode->m_aDescr; 166 167 return store_E_None; 168 } 169 170 /* 171 * iterate. 172 */ 173 storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData) 174 { 175 if (!m_xManager.is()) 176 return store_E_InvalidAccess; 177 178 storeError eErrCode = store_E_NoMoreFiles; 179 if (!rFindData.m_nReserved) 180 return eErrCode; 181 182 // Acquire exclusive access. 183 osl::MutexGuard aGuard (*m_xManager); 184 185 // Check TextConverter. 186 if (m_hTextCvt == NULL) 187 m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8); 188 189 // Setup iteration key. 190 OStorePageKey aKey (rFindData.m_nReserved, m_nPath); 191 192 // Iterate. 193 for (;;) 194 { 195 OStorePageLink aLink; 196 eErrCode = m_xManager->iterate (aKey, aLink, rFindData.m_nAttrib); 197 if (!((eErrCode == store_E_None) && (aKey.m_nHigh == store::htonl(m_nPath)))) 198 break; 199 200 if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK)) 201 { 202 // Load page. 203 OStoreDirectoryPageObject aPage; 204 eErrCode = m_xManager->loadObjectAt (aPage, aLink.location()); 205 if (eErrCode == store_E_None) 206 { 207 inode_holder_type xNode (aPage.get()); 208 209 // Setup FindData. 210 sal_Char *p = xNode->m_aNameBlock.m_pData; 211 sal_Size n = rtl_str_getLength (p); 212 sal_Size k = rFindData.m_nLength; 213 214 n = __store_convertTextToUnicode ( 215 m_hTextCvt, p, n, 216 rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1); 217 if (k > n) 218 { 219 k = (k - n) * sizeof(sal_Unicode); 220 memset (&rFindData.m_pszName[n], 0, k); 221 } 222 223 rFindData.m_nLength = n; 224 rFindData.m_nAttrib |= aPage.attrib(); 225 rFindData.m_nSize = aPage.dataLength(); 226 227 // Leave. 228 rFindData.m_nReserved = store::ntohl(aKey.m_nLow); 229 return store_E_None; 230 } 231 } 232 233 if (aKey.m_nLow == 0) 234 break; 235 aKey.m_nLow = store::htonl(store::ntohl(aKey.m_nLow) - 1); 236 } 237 238 // Finished. 239 memset (&rFindData, 0, sizeof (storeFindData)); 240 return store_E_NoMoreFiles; 241 } 242