From 37f68e8696200895832ee1f18b0cd1c0998bb207 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 30 Jul 2023 13:39:27 +0800 Subject: Partially implement rename operations on SAF files * java/org/gnu/emacs/EmacsSafThread.java (postInvalidateCacheDir): * java/org/gnu/emacs/EmacsService.java (renameDocument): New functions. * src/android.c (android_init_emacs_service): * src/android.h (struct android_emacs_service): Link to new JNI function. * src/androidvfs.c (android_saf_rename_document): New function. (android_saf_tree_rename): Implement in terms of that function if possible. --- java/org/gnu/emacs/EmacsSafThread.java | 78 +++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'java/org/gnu/emacs/EmacsSafThread.java') diff --git a/java/org/gnu/emacs/EmacsSafThread.java b/java/org/gnu/emacs/EmacsSafThread.java index b0d014ffe94..007ea9acfbd 100644 --- a/java/org/gnu/emacs/EmacsSafThread.java +++ b/java/org/gnu/emacs/EmacsSafThread.java @@ -134,7 +134,7 @@ public final class EmacsSafThread extends HandlerThread } - private final class CacheToplevel + private static final class CacheToplevel { /* Map between document names and children. */ HashMap children; @@ -232,7 +232,7 @@ public final class EmacsSafThread extends HandlerThread } }; - private final class CacheEntry + private static final class CacheEntry { /* The type of this document. */ String type; @@ -545,6 +545,80 @@ public final class EmacsSafThread extends HandlerThread }); } + /* Invalidate the cache entry denoted by DOCUMENT_ID, within the + document tree URI. + Call this after deleting a document or directory. + + At the same time, remove the child referring to DOCUMENTID from + within CACHENAME's cache entry if it exists. */ + + public void + postInvalidateCacheDir (final Uri uri, final String documentId, + final String cacheName) + { + handler.post (new Runnable () { + @Override + public void + run () + { + CacheToplevel toplevel; + HashMap children; + String[] components; + CacheEntry entry; + DocIdEntry idEntry; + Iterator iter; + + toplevel = getCache (uri); + toplevel.idCache.remove (documentId); + + /* Now remove DOCUMENTID from CACHENAME's cache entry, if + any. */ + + children = toplevel.children; + components = cacheName.split ("/"); + + for (String component : components) + { + /* Java `split' removes trailing empty matches but not + leading or intermediary ones. */ + if (component.isEmpty ()) + continue; + + /* Search for this component within the last level + of the cache. */ + + idEntry = children.get (component); + + if (idEntry == null) + /* Not cached, so return. */ + return; + + entry = toplevel.idCache.get (idEntry.documentId); + + if (entry == null) + /* Not cached, so return. */ + return; + + /* Locate the next component within this + directory. */ + children = entry.children; + } + + iter = children.values ().iterator (); + while (iter.hasNext ()) + { + idEntry = iter.next (); + + if (idEntry.documentId.equals (documentId)) + { + iter.remove (); + break; + } + } + } + }); + } + /* ``Prototypes'' for nested functions that are run within the SAF -- cgit v1.3