Restore functionality on Android 2.2
* java/Makefile.in (install_temp): Do not compress directory-tree and generate such files in a special format that stores file sizes. * lib-src/asset-directory-tool.c (struct directory_tree): New field st_size. (need_file_size): New variable. (main_1, main_2, main): Write file sizes before sibling offsets if `--api-8' is specified. * src/android-asset.h (struct android_asset_manager): New field open. (struct android_asset): New field name. (AAssetManager_fromJava): Load AssetManager#open. (AAssetManager_open): If a directory tree has already been loaded, search for a matching asset and load its size thence, to avoid the requirement of an AssetFileDescriptor. (AAsset_close): Don't assume asset->fd exists. Release asset->name. (AAsset_getLength): Likewise. (android_asset_create_stream): If asset->name exists, call AssetManager#open, in order to open compressed files. * src/androidvfs.c (OLD_ANDROID_ASSETS): Define to 1 on API 8. (android_extract_long, android_scan_directory_tree): Mark arguments as const. Adjust offsets when OLD_ANDROID_ASSETS. (android_is_directory, android_init_assets, android_afs_readdir): Likewise. * src/lread.c (lread_fstat): Define to sys_fstat, not fstat.
This commit is contained in:
parent
f543ec18f4
commit
02e70821b3
5 changed files with 230 additions and 75 deletions
|
@ -258,7 +258,8 @@ install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES)
|
|||
{ hostname; date +%s; } > install_temp/assets/build_info
|
||||
# Produce the file index.
|
||||
$(AM_V_SILENT) $(libsrc)/asset-directory-tool \
|
||||
install_temp/assets install_temp/assets/directory-tree
|
||||
install_temp/assets install_temp/assets/directory-tree\
|
||||
$(if $(ANDROID_SDK_8_OR_EARLIER),--api-8)
|
||||
# If the package targets Android 2.2, move compressable and
|
||||
# non-compressable assets to separate directories.
|
||||
$(AM_V_SILENT) \
|
||||
|
@ -266,6 +267,7 @@ install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES)
|
|||
echo "Moving large and gzipped files to separate directories...">&2;\
|
||||
mkdir -p install_temp/assets_raw; \
|
||||
cd install_temp/assets; \
|
||||
mv directory-tree ../assets_raw; \
|
||||
find . \( -size +1536 -o -size 1536 \) \
|
||||
\( \! -name '*.gz' \) -type f > files.txt; \
|
||||
tar cf ../assets_raw/largefiles.tar -T files.txt; \
|
||||
|
|
|
@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <verify.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
|
@ -35,17 +36,19 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
application package.
|
||||
|
||||
Such a file records the layout of the `assets' directory in the
|
||||
package. Emacs records this information itself and uses it in the
|
||||
Android emulation of readdir, because the system asset manager APIs
|
||||
are routinely buggy, and are often unable to locate directories or
|
||||
files.
|
||||
package, and, in packages targeting Android 2.2, the size of each of
|
||||
its members. Emacs records this information itself and uses it in
|
||||
the Android emulation of readdir, because the system asset manager
|
||||
APIs are often unable to locate directories or files, or provide
|
||||
corresponding metadata.
|
||||
|
||||
The file is packed, with no data alignment guarantees made. The
|
||||
file starts with the bytes "EMACS", following which is the name of
|
||||
the first file or directory, a NULL byte and an unsigned int
|
||||
indicating the offset from the start of the file to the start of
|
||||
the next sibling. Following that is a list of subdirectories or
|
||||
files in the same format. The long is stored LSB first.
|
||||
The file is packed, with no data alignment guarantees made. The file
|
||||
starts with the bytes "EMACS", or EMACS____ on Android 2.2, following
|
||||
which is the name of the first file or directory, a NULL byte, an
|
||||
unsigned int holding its size (on Android 2.2), and an unsigned int
|
||||
indicating the offset from the start of the file to the start of the
|
||||
next sibling. Following that is a list of subdirectories or files in
|
||||
the same format. The long is stored LSB first.
|
||||
|
||||
Directories can be distinguished from ordinary files through the
|
||||
last bytes of their file names (immediately previous to their
|
||||
|
@ -62,10 +65,19 @@ struct directory_tree
|
|||
/* The name of this directory or file. */
|
||||
char *name;
|
||||
|
||||
/* st_size of this entry. */
|
||||
off_t st_size;
|
||||
|
||||
/* Subdirectories and files inside this directory. */
|
||||
struct directory_tree *children, *next;
|
||||
};
|
||||
|
||||
/* Whether the size of each entry should be prepended to the start
|
||||
pointer. */
|
||||
static bool need_file_size;
|
||||
|
||||
|
||||
|
||||
/* Exit with EXIT_FAILURE, after printing a description of a failing
|
||||
function WHAT along with the details of the error. */
|
||||
|
||||
|
@ -138,11 +150,14 @@ main_1 (DIR *dir, struct directory_tree *parent)
|
|||
last = &this->next;
|
||||
this->name = xmalloc (length + 2);
|
||||
strcpy (this->name, dirent->d_name);
|
||||
this->st_size = 0;
|
||||
|
||||
/* Now record the offset to the end of this directory. This
|
||||
is length + 1, for the file name, and 5 more bytes for
|
||||
the trailing NULL and long. */
|
||||
this->offset = parent->offset + length + 6;
|
||||
is length + 1, for the file name, 5 more bytes for the
|
||||
trailing NULL and long, and 4 further bytes if a file size
|
||||
is required. */
|
||||
this->offset = (parent->offset
|
||||
+ length + 6 + (need_file_size ? 4 : 0));
|
||||
|
||||
/* Terminate that with a slash and trailing NULL byte. */
|
||||
this->name[length] = '/';
|
||||
|
@ -175,11 +190,22 @@ main_1 (DIR *dir, struct directory_tree *parent)
|
|||
*last = this;
|
||||
last = &this->next;
|
||||
this->name = xmalloc (length + 1);
|
||||
this->st_size = statb.st_size;
|
||||
strcpy (this->name, dirent->d_name);
|
||||
|
||||
/* This is one byte shorter because there is no trailing
|
||||
if (this->st_size >= 0x1ffffff)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"asset-directory-tool: file size exceeds maximum"
|
||||
" representable in a directory-tree: %s\n",
|
||||
dirent->d_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* This is one byte the shorter because there is no trailing
|
||||
slash. */
|
||||
this->offset = parent->offset + length + 5;
|
||||
this->offset = (parent->offset + length + 5
|
||||
+ (need_file_size ? 4 : 0));
|
||||
parent->offset = this->offset;
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +220,7 @@ main_2 (int fd, struct directory_tree *tree, size_t *offset)
|
|||
{
|
||||
ssize_t size;
|
||||
struct directory_tree *child;
|
||||
unsigned int output;
|
||||
unsigned int output[2];
|
||||
|
||||
/* Write tree->name with the trailing NULL byte. */
|
||||
size = strlen (tree->name) + 1;
|
||||
|
@ -203,13 +229,26 @@ main_2 (int fd, struct directory_tree *tree, size_t *offset)
|
|||
|
||||
/* Write the offset. */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
output = bswap_32 (tree->offset);
|
||||
#else
|
||||
output = tree->offset;
|
||||
#endif
|
||||
if (write (fd, &output, 4) < 1)
|
||||
croak ("write");
|
||||
size += 4;
|
||||
output[1] = bswap_32 (tree->offset);
|
||||
output[0] = bswap_32 ((unsigned int) tree->st_size);
|
||||
#else /* !WORDS_BIGENDIAN */
|
||||
output[1] = tree->offset;
|
||||
output[0] = (unsigned int) tree->st_size;
|
||||
#endif /* !WORDS_BIGENDIAN */
|
||||
|
||||
verify (sizeof output == 8 && sizeof output[0] == 4);
|
||||
if (!need_file_size)
|
||||
{
|
||||
if (write (fd, output + 1, 4) < 1)
|
||||
croak ("write");
|
||||
size += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write (fd, output, 8) < 1)
|
||||
croak ("write");
|
||||
size += 8;
|
||||
}
|
||||
|
||||
/* Now update offset. */
|
||||
*offset += size;
|
||||
|
@ -240,13 +279,16 @@ main (int argc, char **argv)
|
|||
struct directory_tree tree;
|
||||
size_t offset;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc != 3 && argc != 4)
|
||||
{
|
||||
fprintf (stderr, "usage: %s directory output-file\n",
|
||||
argv[0]);
|
||||
fprintf (stderr, "usage: %s directory output-file "
|
||||
"[--api-8]\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp (argv[3], "--api-8"))
|
||||
need_file_size = true;
|
||||
|
||||
fd = open (argv[2], O_CREAT | O_TRUNC | O_RDWR,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
|
||||
|
@ -272,16 +314,23 @@ main (int argc, char **argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* And a further 4 bytes of padding if need_file_size. */
|
||||
if (need_file_size && write (fd, "____", 4) < 4)
|
||||
{
|
||||
perror ("write");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Now iterate through children of INDIR, building the directory
|
||||
tree. */
|
||||
tree.offset = 5;
|
||||
tree.offset = 5 + (need_file_size ? 4 : 0);
|
||||
tree.children = NULL;
|
||||
|
||||
main_1 (indir, &tree);
|
||||
closedir (indir);
|
||||
|
||||
/* Finally, write the directory tree to the output file. */
|
||||
offset = 5;
|
||||
offset = 5 + (need_file_size ? 4 : 0);
|
||||
for (; tree.children; tree.children = tree.children->next)
|
||||
main_2 (fd, tree.children, &offset);
|
||||
|
||||
|
|
|
@ -19,6 +19,17 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <android/log.h>
|
||||
|
||||
|
||||
|
||||
/* Forward declarations. */
|
||||
|
||||
static const char *directory_tree;
|
||||
|
||||
static const char *android_scan_directory_tree (const char *, size_t *);
|
||||
static unsigned int android_extract_long (const char *);
|
||||
|
||||
|
||||
|
||||
/* This file contains an emulation of the Android asset manager API
|
||||
used on builds for Android 2.2. It is included by android.c
|
||||
whenever appropriate.
|
||||
|
@ -34,6 +45,7 @@ struct android_asset_manager
|
|||
/* Asset manager class and functions. */
|
||||
jclass class;
|
||||
jmethodID open_fd;
|
||||
jmethodID open;
|
||||
|
||||
/* Asset file descriptor class and functions. */
|
||||
jclass fd_class;
|
||||
|
@ -63,6 +75,9 @@ struct android_asset
|
|||
/* The asset file descriptor and input stream. */
|
||||
jobject fd, stream;
|
||||
|
||||
/* Alternatively, the name of the file. */
|
||||
jstring name;
|
||||
|
||||
/* The mode. */
|
||||
int mode;
|
||||
};
|
||||
|
@ -98,6 +113,12 @@ AAssetManager_fromJava (JNIEnv *env, jobject java_manager)
|
|||
= (*env)->GetMethodID (env, manager->class, "openFd",
|
||||
"(Ljava/lang/String;)"
|
||||
"Landroid/content/res/AssetFileDescriptor;");
|
||||
assert (manager->open_fd);
|
||||
|
||||
manager->open
|
||||
= (*env)->GetMethodID (env, manager->class, "open",
|
||||
"(Ljava/lang/String;)"
|
||||
"Ljava/io/InputStream;");
|
||||
assert (manager->open);
|
||||
|
||||
manager->fd_class
|
||||
|
@ -168,6 +189,8 @@ AAssetManager_open (AAssetManager *manager, const char *c_name,
|
|||
jobject desc;
|
||||
jstring name;
|
||||
AAsset *asset;
|
||||
const char *asset_dir;
|
||||
jlong st_size = -1;
|
||||
|
||||
/* Push a local frame. */
|
||||
asset = NULL;
|
||||
|
@ -177,53 +200,86 @@ AAssetManager_open (AAssetManager *manager, const char *c_name,
|
|||
if ((*(manager->env))->ExceptionCheck (manager->env))
|
||||
goto fail;
|
||||
|
||||
/* Encoding issues can be ignored for now as there are only ASCII
|
||||
file names in Emacs. */
|
||||
/* If the directory tree has been initialized, it is possible to avoid
|
||||
opening an AssetFileDescriptor and thereby access compressed
|
||||
assets, without sacrificing the possibility of reading the file
|
||||
size. */
|
||||
if (directory_tree)
|
||||
{
|
||||
/* Search for a matching asset. */
|
||||
asset_dir = android_scan_directory_tree (c_name, NULL);
|
||||
if (!asset_dir)
|
||||
goto fail;
|
||||
|
||||
/* Extract the size of the asset from this directory. */
|
||||
st_size = android_extract_long (asset_dir - 8);
|
||||
}
|
||||
|
||||
/* Encoding issues can be ignored for the time being as there are only
|
||||
ASCII file names in Emacs. */
|
||||
name = (*(manager->env))->NewStringUTF (manager->env, c_name);
|
||||
|
||||
if (!name)
|
||||
goto fail;
|
||||
|
||||
/* Now try to open an ``AssetFileDescriptor''. */
|
||||
desc = (*(manager->env))->CallObjectMethod (manager->env,
|
||||
manager->asset_manager,
|
||||
manager->open_fd,
|
||||
name);
|
||||
/* If st_size has been set, it ought to be possible to open an input
|
||||
stream directly upon the first attempt to read from the asset,
|
||||
sidestepping the intermediate AssetFileDescriptor. */
|
||||
|
||||
if (!desc)
|
||||
goto fail;
|
||||
desc = NULL;
|
||||
|
||||
if (st_size < 0)
|
||||
/* Otherwise attempt to open an ``AssetFileDescriptor''. */
|
||||
desc = (*(manager->env))->CallObjectMethod (manager->env,
|
||||
manager->asset_manager,
|
||||
manager->open_fd,
|
||||
name);
|
||||
|
||||
/* Allocate the asset. */
|
||||
asset = calloc (1, sizeof *asset);
|
||||
|
||||
if (!asset)
|
||||
{
|
||||
(*(manager->env))->CallVoidMethod (manager->env,
|
||||
desc,
|
||||
manager->close);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Pop the local frame and return desc. */
|
||||
desc = (*(manager->env))->NewGlobalRef (manager->env, desc);
|
||||
|
||||
if (!desc)
|
||||
goto fail;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
/* Pop the local frame and return desc. */
|
||||
desc = (*(manager->env))->NewGlobalRef (manager->env, desc);
|
||||
|
||||
if (!desc)
|
||||
goto fail;
|
||||
|
||||
/* Will be released by PopLocalFrame. */
|
||||
name = NULL;
|
||||
}
|
||||
else /* if (name) */
|
||||
{
|
||||
/* Pop the local frame and return name. */
|
||||
name = (*(manager->env))->NewGlobalRef (manager->env, name);
|
||||
|
||||
if (!name)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
(*(manager->env))->PopLocalFrame (manager->env, NULL);
|
||||
|
||||
asset->manager = manager;
|
||||
asset->length = -1;
|
||||
asset->length = st_size;
|
||||
asset->fd = desc;
|
||||
asset->name = name;
|
||||
asset->mode = mode;
|
||||
|
||||
return asset;
|
||||
|
||||
fail:
|
||||
if (desc)
|
||||
(*(manager->env))->CallVoidMethod (manager->env,
|
||||
desc,
|
||||
manager->close);
|
||||
|
||||
(*(manager->env))->ExceptionClear (manager->env);
|
||||
(*(manager->env))->PopLocalFrame (manager->env, NULL);
|
||||
free (asset);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -234,11 +290,14 @@ AAsset_close (AAsset *asset)
|
|||
|
||||
env = asset->manager->env;
|
||||
|
||||
(*env)->CallVoidMethod (asset->manager->env,
|
||||
asset->fd,
|
||||
asset->manager->close);
|
||||
(*env)->DeleteGlobalRef (asset->manager->env,
|
||||
asset->fd);
|
||||
if (asset->fd)
|
||||
{
|
||||
(*env)->CallVoidMethod (asset->manager->env,
|
||||
asset->fd,
|
||||
asset->manager->close);
|
||||
(*env)->DeleteGlobalRef (asset->manager->env,
|
||||
asset->fd);
|
||||
}
|
||||
|
||||
if (asset->stream)
|
||||
{
|
||||
|
@ -249,6 +308,10 @@ AAsset_close (AAsset *asset)
|
|||
asset->stream);
|
||||
}
|
||||
|
||||
if (asset->name)
|
||||
(*env)->DeleteGlobalRef (asset->manager->env,
|
||||
asset->name);
|
||||
|
||||
free (asset);
|
||||
}
|
||||
|
||||
|
@ -264,10 +327,17 @@ android_asset_create_stream (AAsset *asset)
|
|||
jobject stream;
|
||||
JNIEnv *env;
|
||||
|
||||
assert (asset->fd || asset->name);
|
||||
|
||||
env = asset->manager->env;
|
||||
stream
|
||||
= (*env)->CallObjectMethod (env, asset->fd,
|
||||
asset->manager->create_input_stream);
|
||||
|
||||
if (asset->name)
|
||||
stream = (*env)->CallObjectMethod (env, asset->manager->asset_manager,
|
||||
asset->manager->open, asset->name);
|
||||
else
|
||||
stream
|
||||
= (*env)->CallObjectMethod (env, asset->fd,
|
||||
asset->manager->create_input_stream);
|
||||
|
||||
if (!stream)
|
||||
{
|
||||
|
@ -380,6 +450,8 @@ AAsset_getLength (AAsset *asset)
|
|||
|
||||
if (asset->length != -1)
|
||||
return asset->length;
|
||||
if (!asset->fd)
|
||||
return 0;
|
||||
|
||||
env = asset->manager->env;
|
||||
asset->length
|
||||
|
|
|
@ -46,8 +46,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#if __ANDROID_API__ >= 9
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/asset_manager_jni.h>
|
||||
#define OLD_ANDROID_ASSETS 0
|
||||
#else /* __ANDROID_API__ < 9 */
|
||||
#include "android-asset.h"
|
||||
#define OLD_ANDROID_ASSETS 1
|
||||
#endif /* __ANDROID_API__ >= 9 */
|
||||
|
||||
#include <android/log.h>
|
||||
|
@ -1001,7 +1003,7 @@ static AAssetManager *asset_manager;
|
|||
/* Read an unaligned (32-bit) long from the address POINTER. */
|
||||
|
||||
static unsigned int
|
||||
android_extract_long (char *pointer)
|
||||
android_extract_long (const char *pointer)
|
||||
{
|
||||
unsigned int number;
|
||||
|
||||
|
@ -1022,16 +1024,20 @@ android_extract_long (char *pointer)
|
|||
directory. */
|
||||
|
||||
static const char *
|
||||
android_scan_directory_tree (char *file, size_t *limit_return)
|
||||
android_scan_directory_tree (const char *file, size_t *limit_return)
|
||||
{
|
||||
char *token, *saveptr, *copy, *start, *max, *limit;
|
||||
size_t token_length, ntokens, i, len;
|
||||
char *tokens[10];
|
||||
char *tokens[20];
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* Skip past the 5 byte header. */
|
||||
/* Skip past the 5 or 9 byte header. */
|
||||
#if !OLD_ANDROID_ASSETS
|
||||
start = (char *) directory_tree + 5;
|
||||
#else /* OLD_ANDROID_ASSETS */
|
||||
start = (char *) directory_tree + 9;
|
||||
#endif /* OLD_ANDROID_ASSETS */
|
||||
|
||||
/* Figure out the current limit. */
|
||||
limit = (char *) directory_tree + directory_tree_size;
|
||||
|
@ -1098,9 +1104,9 @@ android_scan_directory_tree (char *file, size_t *limit_return)
|
|||
{
|
||||
/* They probably match. Find the NULL byte. It must be
|
||||
either one byte past start + token_length, with the last
|
||||
byte a trailing slash (indicating that it is a
|
||||
directory), or just start + token_length. Return 4 bytes
|
||||
past the next NULL byte. */
|
||||
byte a trailing slash (indicating that it is a directory),
|
||||
or just start + token_length. Return 4 or 8 bytes past the
|
||||
next NULL byte. */
|
||||
|
||||
max = memchr (start, 0, limit - start);
|
||||
|
||||
|
@ -1113,13 +1119,14 @@ android_scan_directory_tree (char *file, size_t *limit_return)
|
|||
last token. Otherwise, set it as start and the limit as
|
||||
start + the offset and continue the loop. */
|
||||
|
||||
if (max && max + 5 <= limit)
|
||||
if (max && max + (OLD_ANDROID_ASSETS ? 9 : 5) <= limit)
|
||||
{
|
||||
if (i < ntokens - 1)
|
||||
{
|
||||
start = max + 5;
|
||||
start = max + (OLD_ANDROID_ASSETS ? 9 : 5);
|
||||
limit = ((char *) directory_tree
|
||||
+ android_extract_long (max + 1));
|
||||
+ android_extract_long (max + (OLD_ANDROID_ASSETS
|
||||
? 5 : 1)));
|
||||
|
||||
/* Make sure limit is still in range. */
|
||||
if (limit > directory_tree + directory_tree_size
|
||||
|
@ -1137,10 +1144,12 @@ android_scan_directory_tree (char *file, size_t *limit_return)
|
|||
{
|
||||
/* Figure out the limit. */
|
||||
if (limit_return)
|
||||
*limit_return = android_extract_long (max + 1);
|
||||
*limit_return
|
||||
= android_extract_long (max + (OLD_ANDROID_ASSETS
|
||||
? 5 : 1));
|
||||
|
||||
/* Go to the end of this file. */
|
||||
max += 5;
|
||||
max += (OLD_ANDROID_ASSETS ? 9 : 5);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
|
@ -1161,11 +1170,12 @@ android_scan_directory_tree (char *file, size_t *limit_return)
|
|||
|
||||
start = memchr (start, 0, limit - start);
|
||||
|
||||
if (!start || start + 5 > limit)
|
||||
if (!start || start + (OLD_ANDROID_ASSETS ? 9 : 5) > limit)
|
||||
goto fail;
|
||||
|
||||
start = ((char *) directory_tree
|
||||
+ android_extract_long (start + 1));
|
||||
+ android_extract_long (start
|
||||
+ (OLD_ANDROID_ASSETS ? 5 : 1)));
|
||||
|
||||
/* Make sure start is still in bounds. */
|
||||
|
||||
|
@ -1192,13 +1202,20 @@ android_is_directory (const char *dir)
|
|||
{
|
||||
/* If the directory is the directory tree, then it is a
|
||||
directory. */
|
||||
if (dir == directory_tree + 5)
|
||||
if (dir == directory_tree + (OLD_ANDROID_ASSETS ? 9 : 5))
|
||||
return true;
|
||||
|
||||
#if !OLD_ANDROID_ASSETS
|
||||
/* Otherwise, look 5 bytes behind. If it is `/', then it is a
|
||||
directory. */
|
||||
return (dir - 6 >= directory_tree
|
||||
&& *(dir - 6) == '/');
|
||||
#else /* OLD_ANDROID_ASSETS */
|
||||
/* Otherwise, look 9 bytes behind. If it is `/', then it is a
|
||||
directory. */
|
||||
return (dir - 10 >= directory_tree
|
||||
&& *(dir - 10) == '/');
|
||||
#endif /* OLD_ANDROID_ASSETS */
|
||||
}
|
||||
|
||||
/* Initialize asset retrieval. ENV should be a JNI environment for
|
||||
|
@ -1232,6 +1249,7 @@ android_init_assets (JNIEnv *env, jobject manager)
|
|||
/* Now figure out how big the directory tree is, and compare the
|
||||
first few bytes. */
|
||||
directory_tree_size = AAsset_getLength (asset);
|
||||
#if !OLD_ANDROID_ASSETS
|
||||
if (directory_tree_size < 5
|
||||
|| memcmp (directory_tree, "EMACS", 5))
|
||||
{
|
||||
|
@ -1239,6 +1257,15 @@ android_init_assets (JNIEnv *env, jobject manager)
|
|||
"Directory tree has bad magic");
|
||||
emacs_abort ();
|
||||
}
|
||||
#else /* OLD_ANDROID_ASSETS */
|
||||
if (directory_tree_size < 9
|
||||
|| memcmp (directory_tree, "EMACS____", 9))
|
||||
{
|
||||
__android_log_print (ANDROID_LOG_FATAL, __func__,
|
||||
"Directory tree has bad magic");
|
||||
emacs_abort ();
|
||||
}
|
||||
#endif /* OLD_ANDROID_ASSETS */
|
||||
|
||||
/* Hold a VM reference to the asset manager to prevent the native
|
||||
object from being deleted. */
|
||||
|
@ -2287,8 +2314,13 @@ android_afs_readdir (struct android_vdir *vdir)
|
|||
dirent.d_type = DT_REG;
|
||||
|
||||
/* Forward dir->asset_dir to the file past last. */
|
||||
#if !OLD_ANDROID_ASSETS
|
||||
dir->asset_dir = ((char *) directory_tree
|
||||
+ android_extract_long ((char *) last));
|
||||
#else /* OLD_ANDROID_ASSETS */
|
||||
dir->asset_dir = ((char *) directory_tree
|
||||
+ android_extract_long ((char *) last + 4));
|
||||
#endif /* OLD_ANDROID_ASSETS */
|
||||
|
||||
return &dirent;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#define lread_fd_cmp(n) (fd == (n))
|
||||
#define lread_fd_p (fd >= 0)
|
||||
#define lread_close emacs_close
|
||||
#define lread_fstat fstat
|
||||
#define lread_fstat sys_fstat
|
||||
#define lread_read_quit emacs_read_quit
|
||||
#define lread_lseek lseek
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue