| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_store.hxx" |
| |
| #include "stordir.hxx" |
| |
| #ifndef _SAL_TYPES_H_ |
| #include <sal/types.h> |
| #endif |
| |
| #ifndef _RTL_TEXTCVT_H_ |
| #include <rtl/textcvt.h> |
| #endif |
| #ifndef _RTL_REF_HXX_ |
| #include <rtl/ref.hxx> |
| #endif |
| |
| #ifndef _OSL_MUTEX_HXX_ |
| #include <osl/mutex.hxx> |
| #endif |
| |
| #ifndef _STORE_TYPES_H_ |
| #include "store/types.h" |
| #endif |
| #ifndef _STORE_OBJECT_HXX_ |
| #include "object.hxx" |
| #endif |
| |
| #ifndef _STORE_STORBASE_HXX_ |
| #include "storbase.hxx" |
| #endif |
| #ifndef _STORE_STORDATA_HXX_ |
| #include "stordata.hxx" |
| #endif |
| #ifndef _STORE_STORPAGE_HXX_ |
| #include "storpage.hxx" |
| #endif |
| |
| using namespace store; |
| |
| /*======================================================================== |
| * |
| * OStore... internals. |
| * |
| *======================================================================*/ |
| /* |
| * __store_convertTextToUnicode. |
| */ |
| inline sal_Size __store_convertTextToUnicode ( |
| rtl_TextToUnicodeConverter hConverter, |
| const sal_Char *pSrcBuffer, sal_Size nSrcLength, |
| sal_Unicode *pDstBuffer, sal_Size nDstLength) |
| { |
| sal_uInt32 nCvtInfo = 0; |
| sal_Size nCvtBytes = 0; |
| return rtl_convertTextToUnicode ( |
| hConverter, 0, |
| pSrcBuffer, nSrcLength, |
| pDstBuffer, nDstLength, |
| OSTRING_TO_OUSTRING_CVTFLAGS, |
| &nCvtInfo, &nCvtBytes); |
| } |
| |
| /*======================================================================== |
| * |
| * OStoreDirectory_Impl implementation. |
| * |
| *======================================================================*/ |
| const sal_uInt32 OStoreDirectory_Impl::m_nTypeId = sal_uInt32(0x89191107); |
| |
| /* |
| * OStoreDirectory_Impl. |
| */ |
| OStoreDirectory_Impl::OStoreDirectory_Impl (void) |
| : m_xManager (), |
| m_aDescr (0, 0, 0), |
| m_nPath (0), |
| m_hTextCvt (NULL) |
| {} |
| |
| /* |
| * ~OStoreDirectory_Impl. |
| */ |
| OStoreDirectory_Impl::~OStoreDirectory_Impl (void) |
| { |
| if (m_xManager.is()) |
| { |
| if (m_aDescr.m_nAddr != STORE_PAGE_NULL) |
| m_xManager->releasePage (m_aDescr, store_AccessReadOnly); |
| } |
| rtl_destroyTextToUnicodeConverter (m_hTextCvt); |
| } |
| |
| /* |
| * isKindOf. |
| */ |
| sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId) |
| { |
| return (nTypeId == m_nTypeId); |
| } |
| |
| /* |
| * create. |
| */ |
| storeError OStoreDirectory_Impl::create ( |
| OStorePageManager *pManager, |
| rtl_String *pPath, |
| rtl_String *pName, |
| storeAccessMode eMode) |
| { |
| rtl::Reference<OStorePageManager> xManager (pManager); |
| if (!xManager.is()) |
| return store_E_InvalidAccess; |
| |
| if (!(pPath && pName)) |
| return store_E_InvalidParameter; |
| |
| OStoreDirectoryPageObject aPage; |
| storeError eErrCode = xManager->iget ( |
| aPage, STORE_ATTRIB_ISDIR, |
| pPath, pName, eMode); |
| if (eErrCode != store_E_None) |
| return eErrCode; |
| |
| if (!(aPage.attrib() & STORE_ATTRIB_ISDIR)) |
| return store_E_NotDirectory; |
| |
| inode_holder_type xNode (aPage.get()); |
| eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly); |
| if (eErrCode != store_E_None) |
| return eErrCode; |
| |
| // Evaluate iteration path. |
| m_nPath = aPage.path(); |
| m_nPath = rtl_crc32 (m_nPath, "/", 1); |
| |
| // Save page manager, and descriptor. |
| m_xManager = xManager; |
| m_aDescr = xNode->m_aDescr; |
| |
| return store_E_None; |
| } |
| |
| /* |
| * iterate. |
| */ |
| storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData) |
| { |
| if (!m_xManager.is()) |
| return store_E_InvalidAccess; |
| |
| storeError eErrCode = store_E_NoMoreFiles; |
| if (!rFindData.m_nReserved) |
| return eErrCode; |
| |
| // Acquire exclusive access. |
| osl::MutexGuard aGuard (*m_xManager); |
| |
| // Check TextConverter. |
| if (m_hTextCvt == NULL) |
| m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8); |
| |
| // Setup iteration key. |
| OStorePageKey aKey (rFindData.m_nReserved, m_nPath); |
| |
| // Iterate. |
| for (;;) |
| { |
| OStorePageLink aLink; |
| eErrCode = m_xManager->iterate (aKey, aLink, rFindData.m_nAttrib); |
| if (!((eErrCode == store_E_None) && (aKey.m_nHigh == store::htonl(m_nPath)))) |
| break; |
| |
| if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK)) |
| { |
| // Load page. |
| OStoreDirectoryPageObject aPage; |
| eErrCode = m_xManager->loadObjectAt (aPage, aLink.location()); |
| if (eErrCode == store_E_None) |
| { |
| inode_holder_type xNode (aPage.get()); |
| |
| // Setup FindData. |
| sal_Char *p = xNode->m_aNameBlock.m_pData; |
| sal_Size n = rtl_str_getLength (p); |
| sal_Size k = rFindData.m_nLength; |
| |
| n = __store_convertTextToUnicode ( |
| m_hTextCvt, p, n, |
| rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1); |
| if (k > n) |
| { |
| k = (k - n) * sizeof(sal_Unicode); |
| memset (&rFindData.m_pszName[n], 0, k); |
| } |
| |
| rFindData.m_nLength = n; |
| rFindData.m_nAttrib |= aPage.attrib(); |
| rFindData.m_nSize = aPage.dataLength(); |
| |
| // Leave. |
| rFindData.m_nReserved = store::ntohl(aKey.m_nLow); |
| return store_E_None; |
| } |
| } |
| |
| if (aKey.m_nLow == 0) |
| break; |
| aKey.m_nLow = store::htonl(store::ntohl(aKey.m_nLow) - 1); |
| } |
| |
| // Finished. |
| memset (&rFindData, 0, sizeof (storeFindData)); |
| return store_E_NoMoreFiles; |
| } |