summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sal/inc/osl/file.h45
-rw-r--r--sal/osl/unx/file.cxx56
-rw-r--r--sal/osl/w32/file.cxx7
-rw-r--r--sal/util/sal.map5
-rw-r--r--store/source/lockbyte.cxx14
-rw-r--r--xmlreader/source/xmlreader.cxx4
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) {