diff options
-rw-r--r-- | sal/inc/osl/file.h | 45 | ||||
-rw-r--r-- | sal/osl/unx/file.cxx | 56 | ||||
-rw-r--r-- | sal/osl/w32/file.cxx | 7 | ||||
-rw-r--r-- | sal/util/sal.map | 5 | ||||
-rw-r--r-- | store/source/lockbyte.cxx | 14 | ||||
-rw-r--r-- | xmlreader/source/xmlreader.cxx | 4 |
6 files changed, 112 insertions, 19 deletions
diff --git a/sal/inc/osl/file.h b/sal/inc/osl/file.h index cc12b1c616f8..ecf9e60a4d68 100644 --- a/sal/inc/osl/file.h +++ b/sal/inc/osl/file.h @@ -680,6 +680,12 @@ typedef void *oslFileHandle; @param uFlags [in] Specifies the open mode. + On Android, if the file path is below the /assets folder, the file + exists only as a hopefully uncompressed element inside the app + package (.apk), which has been mapped into memory as a whole by + the LibreOffice Android bootstrapping code. So files "opened" from + there aren't actually files in the OS sense. + @return osl_File_E_None on success<br> osl_File_E_NOMEM not enough memory for allocating structures <br> @@ -837,6 +843,15 @@ SAL_DLLPUBLIC oslFileError SAL_CALL osl_getFileSize( /** Map a shared file into memory. + Don't know what the "shared" is supposed to mean there? Also, + obviously this API can be used to map *part* of a file into + memory, and different parts can be mapped separately even. + + On Android, if the Handle refers to a file that is actually inside + the app package (.apk zip archive), no new mapping is created, + just a pointer to the file inside the already mapped .apk is + returned. + @since UDK 3.2.10 */ SAL_DLLPUBLIC oslFileError SAL_CALL osl_mapFile ( @@ -848,8 +863,19 @@ SAL_DLLPUBLIC oslFileError SAL_CALL osl_mapFile ( ); +#ifndef ANDROID + /** Unmap a shared file from memory. + Ditto here, why do we need to mention "shared"? + + This function just won't work on Android in general where for + (uncompressed) files inside the .apk, per SDK conventions in the + /assets folder, osl_mapFile() returns a pointer to the file inside + the already by LibreOffice Android-specific bootstrapping code + mmapped .apk archive. We can't go and randomly munmap part of the + .apk archive. So this function is not present on Android. + @since UDK 3.2.10 */ SAL_DLLPUBLIC oslFileError SAL_CALL osl_unmapFile ( @@ -857,6 +883,25 @@ SAL_DLLPUBLIC oslFileError SAL_CALL osl_unmapFile ( sal_uInt64 uLength ); +#endif + +/** Unmap a file segment from memory. + + Like osl_unmapFile(), but takes also the oslFileHandle argument + passed to osl_mapFile() when creating this mapping. + + On Android, for files below /assets, i.e. located inside the app + archive (.apk), this won't actually unmap anything; all the .apk + stays mapped. + + @since UDK 3.6 + */ +SAL_DLLPUBLIC oslFileError SAL_CALL osl_unmapMappedFile ( + oslFileHandle Handle, + void* pAddr, + sal_uInt64 uLength +); + /** Read a number of bytes from a file. diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx index f0604131e34a..458554ea9e4f 100644 --- a/sal/osl/unx/file.cxx +++ b/sal/osl/unx/file.cxx @@ -865,7 +865,6 @@ SAL_CALL osl_openMemoryAsFile( void *address, size_t size, oslFileHandle *pHandl eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM); return eRet; } - pImpl->m_kind = FileHandle_Impl::KIND_MEM; pImpl->m_size = sal::static_int_cast< sal_uInt64 >(size); *pHandle = (oslFileHandle)(pImpl); @@ -1116,13 +1115,7 @@ SAL_CALL osl_mapFile ( { FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); - if (pImpl->m_kind == FileHandle_Impl::KIND_MEM) - { - *ppAddr = pImpl->m_buffer; - return osl_File_E_None; - } - - if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppAddr)) + if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == ppAddr)) return osl_File_E_INVAL; *ppAddr = 0; @@ -1134,6 +1127,13 @@ SAL_CALL osl_mapFile ( static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); if (g_limit_off_t < uOffset) return osl_File_E_OVERFLOW; + + if (pImpl->m_kind == FileHandle_Impl::KIND_MEM) + { + *ppAddr = pImpl->m_buffer + uOffset; + return osl_File_E_None; + } + off_t const nOffset = sal::static_int_cast< off_t >(uOffset); void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pImpl->m_fd, nOffset); @@ -1195,11 +1195,9 @@ SAL_CALL osl_mapFile ( return osl_File_E_None; } -/******************************************* - osl_unmapFile -********************************************/ +static oslFileError -SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength) +unmapFile (void* pAddr, sal_uInt64 uLength) { if (0 == pAddr) return osl_File_E_INVAL; @@ -1215,6 +1213,40 @@ SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength) return osl_File_E_None; } +#ifndef ANDROID + +// Note that osl_unmapFile() just won't work on Android in general +// where for (uncompressed) files inside the .apk, in the /assets +// folder osl_mapFile just returns a pointer to the file inside the +// already mmapped .apk archive. + +/******************************************* + osl_unmapFile +********************************************/ +oslFileError +SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength) +{ + return unmapFile (pAddr, uLength); +} + +#endif + +/******************************************* + osl_unmapMappedFile +********************************************/ +oslFileError +SAL_CALL osl_unmapMappedFile (oslFileHandle Handle, void* pAddr, sal_uInt64 uLength) +{ + FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); + + if (pImpl->m_kind == FileHandle_Impl::KIND_FD) + return unmapFile (pAddr, uLength); + + // For parts of already mmapped "parent" files, whose mapping we + // can't change, not much we can or should do... + return osl_File_E_None; +} + /******************************************* osl_readLine ********************************************/ diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx index da49f3a75b2c..5e73dbf62f3a 100644 --- a/sal/osl/w32/file.cxx +++ b/sal/osl/w32/file.cxx @@ -882,6 +882,13 @@ SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */) //############################################# oslFileError +SAL_CALL osl_unmapMappedFile(oslFileHandle /* Handle */, void* pAddr, sal_uInt64 uLength) +{ + return osl_unmapFile( pAddr, uLength ); +} + +//############################################# +oslFileError SAL_CALL osl_readLine( oslFileHandle Handle, sal_Sequence ** ppSequence) diff --git a/sal/util/sal.map b/sal/util/sal.map index 7ccc24ca631b..e8a9ab520477 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -610,6 +610,11 @@ LIBO_UDK_3.5 { # symbols available in >= LibO 3.5 rtl_uStringbuffer_remove; } UDK_3.10; +LIBO_UDK_3.6 { # symbols available in >= LibO 3.6 + global: + osl_unmapMappedFile; +} UDK_3.10; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; diff --git a/store/source/lockbyte.cxx b/store/source/lockbyte.cxx index f7b20f002f7b..a91e470cc38d 100644 --- a/store/source/lockbyte.cxx +++ b/store/source/lockbyte.cxx @@ -476,6 +476,7 @@ struct FileMapping { sal_uInt8 * m_pAddr; sal_uInt32 m_nSize; + oslFileHandle m_hFile; FileMapping() : m_pAddr(0), m_nSize(0) {} @@ -497,15 +498,17 @@ struct FileMapping return osl_File_E_OVERFLOW; m_nSize = sal::static_int_cast<sal_uInt32>(uSize); + m_hFile = hFile; + // Acquire mapping. return osl_mapFile (hFile, reinterpret_cast<void**>(&m_pAddr), m_nSize, 0, osl_File_MapFlag_RandomAccess); } /** @see MappedLockBytes::destructor. */ - static void unmapFile (sal_uInt8 * pAddr, sal_uInt32 nSize) + static void unmapFile (oslFileHandle hFile, sal_uInt8 * pAddr, sal_uInt32 nSize) { - (void) osl_unmapFile (pAddr, nSize); + (void) osl_unmapMappedFile (hFile, pAddr, nSize); } /** @see ResourceHolder<T>::destructor_type @@ -515,7 +518,7 @@ struct FileMapping void operator ()(FileMapping & rMapping) const { // Release mapping. - unmapFile (rMapping.m_pAddr, rMapping.m_nSize); + unmapFile (rMapping.m_hFile, rMapping.m_pAddr, rMapping.m_nSize); rMapping.m_pAddr = 0, rMapping.m_nSize = 0; } }; @@ -532,6 +535,7 @@ class MappedLockBytes : sal_uInt8 * m_pData; sal_uInt32 m_nSize; sal_uInt16 m_nPageSize; + oslFileHandle m_hFile; /** PageData::Allocator implementation. */ @@ -577,13 +581,13 @@ protected: } // namespace store MappedLockBytes::MappedLockBytes (FileMapping & rMapping) - : m_pData (rMapping.m_pAddr), m_nSize (rMapping.m_nSize), m_nPageSize(0) + : m_pData (rMapping.m_pAddr), m_nSize (rMapping.m_nSize), m_nPageSize(0), m_hFile (rMapping.m_hFile) { } MappedLockBytes::~MappedLockBytes() { - FileMapping::unmapFile (m_pData, m_nSize); + FileMapping::unmapFile (m_hFile, m_pData, m_nSize); } oslInterlockedCount SAL_CALL MappedLockBytes::acquire() diff --git a/xmlreader/source/xmlreader.cxx b/xmlreader/source/xmlreader.cxx index 0801c8137474..05782eeb70dd 100644 --- a/xmlreader/source/xmlreader.cxx +++ b/xmlreader/source/xmlreader.cxx @@ -115,11 +115,11 @@ XmlReader::XmlReader(rtl::OUString const & fileUrl) } XmlReader::~XmlReader() { - oslFileError e = osl_unmapFile(fileAddress_, fileSize_); + oslFileError e = osl_unmapMappedFile(fileHandle_, fileAddress_, fileSize_); if (e != osl_File_E_None) { SAL_WARN( "xmlreader", - "osl_unmapFile of \"" << fileUrl_ << "\" failed with " << +e); + "osl_unmapMappedFile of \"" << fileUrl_ << "\" failed with " << +e); } e = osl_closeFile(fileHandle_); if (e != osl_File_E_None) { |