sal/inc/osl/file.h             |   45 ++++++++++++++++++++++++++++++++
 sal/osl/unx/file.cxx           |   56 ++++++++++++++++++++++++++++++++---------
 sal/osl/w32/file.cxx           |    7 +++++
 sal/util/sal.map               |    5 +++
 store/source/lockbyte.cxx      |   14 ++++++----
 xmlreader/source/xmlreader.cxx |    4 +-
 6 files changed, 112 insertions(+), 19 deletions(-)

New commits:
commit e3ab0fd9016bc24c5a0eb0807f171d5025c3bb79
Author: Tor Lillqvist <tlillqv...@suse.com>
Date:   Wed Dec 21 13:51:50 2011 +0200

    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.

diff --git a/sal/inc/osl/file.h b/sal/inc/osl/file.h
index cc12b1c..ecf9e60 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 f060413..458554e 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 da49f3a..5e73dbf 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 7ccc24c..e8a9ab5 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 f7b20f0..a91e470 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 0801c81..05782ee 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) {
_______________________________________________
Libreoffice-commits mailing list
Libreoffice-commits@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to