diff options
author | Tor Lillqvist <tlillqvist@suse.com> | 2011-12-21 13:51:50 +0200 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@suse.com> | 2011-12-21 14:08:48 +0200 |
commit | e3ab0fd9016bc24c5a0eb0807f171d5025c3bb79 (patch) | |
tree | fe87e3d60bf522d0ccc469becacbb0191e129d75 /sal/osl/unx | |
parent | eeecf625351238f90c61c82b403bd65e35d7833e (diff) |
osl_unmapFile can't work for files bundled inside the .apk on Android
On Android, when an app is installed, arbitrary files bundled in the
app won't be unpacked into actual separate files in the file
system. They will exist only as archive entries in the .apk file
(which is a zip archive).
The SDK tooling puts such files under the /assets folder in the
.apk. The LibreOffice bootstrapping code for Android maps the .apk
file into memory.
osl_openFile() knows about the /assets special case, and uses a
separate abstraction for such memory-mapped files.
Obviously, when producing an .apk, one needs to make sure these
bundled files are not compressed, if one wants to be able to use them
directly from the memory-mapped .apk file. We do that in our test and
sample Android projects.
When mapping such files under /assets , just return a pointer to the
file's location inside the mapped .apk archive.
We can't use the old osl_unmapFile() on such mapped files, as that
would unexpectedly unmap fairly arbitrary pages of the .apk mapping,
wreaking havoc on later use of the same pages.
So, introduce a new osl_unmapMappedFile() function that takes also the
oslFileHandle originally passed to osl_mapFile(). Use this instead in
the few places where the code actually called osl_unmapFile(). Make
sure osl_mapFile() is nonexistent on Android.
Diffstat (limited to 'sal/osl/unx')
-rw-r--r-- | sal/osl/unx/file.cxx | 56 |
1 files changed, 44 insertions, 12 deletions
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 ********************************************/ |