summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@suse.com>2011-11-19 02:47:22 +0200
committerTor Lillqvist <tlillqvist@suse.com>2011-11-19 02:55:13 +0200
commit552f521070bf5ff4e031206968463cd99061edc5 (patch)
treecc32d2e70629da65ee6e5b14d86f9aef796804a7
parent2ad14b0e0380c390f09256b3f4f70f733e310df2 (diff)
Add read-only pseudo-files representing a memory block
For Android only for now. To be used to read raw asset files from the application package (.apk file, a zip archive).
-rw-r--r--sal/osl/unx/file.cxx99
1 files changed, 91 insertions, 8 deletions
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index d57820b5798e..7a36e69fbdbf 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -79,6 +79,12 @@ struct FileHandle_Impl
rtl_String * m_strFilePath; /* holds native file path */
int m_fd;
+ enum Kind
+ {
+ KIND_FD = 1,
+ KIND_MEM = 2
+ };
+ int m_kind;
/** State
*/
enum StateBits
@@ -242,6 +248,7 @@ FileHandle_Impl::Guard::~Guard()
FileHandle_Impl::FileHandle_Impl (int fd, char const * path)
: m_strFilePath (0),
m_fd (fd),
+ m_kind (KIND_FD),
m_state (STATE_SEEKABLE | STATE_READABLE),
m_size (0),
m_offset (0),
@@ -356,6 +363,24 @@ oslFileError FileHandle_Impl::readAt (
if (!(m_state & STATE_READABLE))
return osl_File_E_BADF;
+ if (m_kind == KIND_MEM)
+ {
+ ssize_t nBytes;
+
+ m_offset = nOffset;
+
+ if ((sal_uInt64) m_offset >= m_size)
+ nBytes = 0;
+ else
+ {
+ nBytes = std::min(nBytesRequested, (size_t) (m_size - m_offset));
+ memmove(pBuffer, m_buffer + m_offset, nBytes);
+ m_offset += nBytes;
+ }
+ *pBytesRead = nBytes;
+ return osl_File_E_None;
+ }
+
#if defined(LINUX) || defined(SOLARIS)
ssize_t nBytes = ::pread (m_fd, pBuffer, nBytesRequested, nOffset);
@@ -449,7 +474,7 @@ oslFileError FileHandle_Impl::readFileAt (
*pBytesRead = nBytes;
return osl_File_E_None;
}
- else if (0 == m_buffer)
+ else if (m_kind == KIND_MEM || 0 == m_buffer)
{
// not buffered
return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
@@ -825,6 +850,34 @@ static int osl_file_queryLocking (sal_uInt32 uFlags)
return 0;
}
+#ifdef ANDROID
+
+static oslFileError
+SAL_CALL osl_openMemoryAsFile( void *address, size_t size, oslFileHandle *pHandle )
+{
+ oslFileError eRet;
+ FileHandle_Impl * pImpl = new FileHandle_Impl (-1, "");
+ if (!pImpl)
+ {
+ 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);
+
+ pImpl->m_bufptr = 0;
+ pImpl->m_buflen = size;
+
+ pImpl->m_bufsiz = size;
+ pImpl->m_buffer = (sal_uInt8*) address;
+
+ return osl_File_E_None;
+}
+
+#endif
+
/****************************************************************************
* osl_openFile
***************************************************************************/
@@ -854,6 +907,21 @@ SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uIn
return oslTranslateFileError (OSL_FET_ERROR, errno);
#endif /* MACOSX */
+#ifdef ANDROID
+ /* Opening a file from /assets read-only means
+ * we should mmap it from the .apk file
+ */
+ if (!(uFlags & osl_File_OpenFlag_Write) &&
+ strncmp (buffer, "/assets/", strlen ("/assets/")) == 0)
+ {
+ void *address;
+ size_t size;
+ void *(*lo_apkentry)(const char *, size_t *) = (void *(*)(const char *, size_t *)) dlsym(RTLD_DEFAULT, "lo_apkentry");
+ address = (*lo_apkentry)(buffer, &size);
+ return osl_openMemoryAsFile(address, size, pHandle);
+ }
+#endif
+
/* set mode and flags */
int mode = S_IRUSR | S_IRGRP | S_IROTH;
int flags = O_RDONLY;
@@ -976,6 +1044,12 @@ SAL_CALL osl_closeFile( oslFileHandle Handle )
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if (pImpl->m_kind == FileHandle_Impl::KIND_MEM)
+ {
+ delete pImpl;
+ return osl_File_E_None;
+ }
+
if ((pImpl == 0) || (pImpl->m_fd < 0))
return osl_File_E_INVAL;
@@ -1008,6 +1082,9 @@ SAL_CALL osl_syncFile(oslFileHandle Handle)
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
+ if (pImpl->m_kind == FileHandle_Impl::KIND_MEM)
+ return osl_File_E_None;
+
if ((0 == pImpl) || (-1 == pImpl->m_fd))
return osl_File_E_INVAL;
@@ -1037,6 +1114,12 @@ 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))
return osl_File_E_INVAL;
*ppAddr = 0;
@@ -1140,7 +1223,7 @@ SAL_CALL osl_readLine (
{
FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppSequence))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == ppSequence))
return osl_File_E_INVAL;
sal_uInt64 uBytesRead = 0;
@@ -1165,7 +1248,7 @@ SAL_CALL osl_readFile (
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == pBuffer) || (0 == pBytesRead))
return osl_File_E_INVAL;
static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
@@ -1226,7 +1309,7 @@ SAL_CALL osl_readFileAt (
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == pBuffer) || (0 == pBytesRead))
return osl_File_E_INVAL;
if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
return osl_File_E_SPIPE;
@@ -1289,7 +1372,7 @@ SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pIsEOF))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == pIsEOF))
return osl_File_E_INVAL;
FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
@@ -1305,7 +1388,7 @@ SAL_CALL osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pPos))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == pPos))
return osl_File_E_INVAL;
FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
@@ -1321,7 +1404,7 @@ SAL_CALL osl_setFilePos (oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffse
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)))
return osl_File_E_INVAL;
static sal_Int64 const g_limit_off_t = std::numeric_limits< off_t >::max();
@@ -1368,7 +1451,7 @@ SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
{
FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
- if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pSize))
+ if ((0 == pImpl) || ((pImpl->m_kind == FileHandle_Impl::KIND_FD) && (-1 == pImpl->m_fd)) || (0 == pSize))
return osl_File_E_INVAL;
FileHandle_Impl::Guard lock (&(pImpl->m_mutex));