introduce ES_PATH_MOVE_ALLOW_COPY_AND_DELETE

This commit is contained in:
nakst 2021-08-31 21:01:04 +01:00
parent 35d4f727f9
commit 5d9a6f72dc
5 changed files with 20 additions and 4 deletions

View File

@ -172,6 +172,10 @@ void InitialiseInstance(EsInstance *instance) {
EsMemoryCopy(nullptr, nullptr, 1);
});
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Move file"), [] (EsInstance *, EsElement *, EsCommand *) {
EsPathMove("0:/A Study in Scarlet.txt", -1, "0:/moved.txt", -1, ES_PATH_MOVE_ALLOW_COPY_AND_DELETE);
});
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Announcement 1"), [] (EsInstance *, EsElement *element, EsCommand *) {
EsRectangle bounds = EsElementGetWindowBounds(element);
EsAnnouncementShow(element->window, ES_FLAGS_DEFAULT, (bounds.l + bounds.r) / 2, (bounds.t + bounds.b) / 2, "Hello, world!", -1);

View File

@ -2,6 +2,7 @@
name=Test
icon=icon_system_software_install
use_single_process=1
permission_all_files=1
[build]
source=apps/test.cpp

View File

@ -1455,7 +1455,7 @@ void ApplicationInstanceCompleteSave(ApplicationInstance *fromInstance) {
// TODO What should happen if the old file is deleted, but the new file isn't moved?
EsPathDelete(document->path, document->pathBytes);
EsPathMove(document->temporarySavePath, document->temporarySavePathBytes, document->path, document->pathBytes);
EsPathMove(document->temporarySavePath, document->temporarySavePathBytes, document->path, document->pathBytes, ES_PATH_MOVE_ALLOW_COPY_AND_DELETE);
// Re-open the read handle.

View File

@ -727,6 +727,8 @@ define ES_DRAW_BITMAP_BLEND (0)
define ES_VOLUME_READ_ONLY (1 << 0)
define ES_PATH_MOVE_ALLOW_COPY_AND_DELETE (1 << 0) // Copy and delete the file if a direct move is not possible.
include desktop/icons.header
enum EsFatalError {
@ -1928,7 +1930,7 @@ function EsError EsFileWriteAllFromHandle(EsHandle handle, const void *data, siz
function EsError EsFileWriteAllGather(STRING filePath, const void **data, size_t *fileSize, size_t gatherCount);
function EsError EsFileWriteAllGatherFromHandle(EsHandle handle, const void **data, size_t *fileSize, size_t gatherCount);
function void *EsFileMap(STRING filePath, size_t *fileSize, uint32_t flags);
function EsError EsFileCopy(STRING source, STRING destination, void **copyBuffer); // If you are copying lots of files, you can reuse the temporary copy buffer by storing the output copyBuffer; call EsHeapFree on it after the last copy.
function EsError EsFileCopy(STRING source, STRING destination, void **copyBuffer = nullptr); // If you are copying lots of files, you can reuse the temporary copy buffer by storing the output copyBuffer; call EsHeapFree on it after the last copy.
function EsError EsFileControl(EsHandle file, uint32_t flags);
function EsFileInformation EsFileOpen(STRING path, uint32_t flags);
@ -1940,7 +1942,7 @@ function EsError EsFileDelete(EsHandle file);
function EsError EsPathDelete(STRING path);
function size_t EsPathFindUniqueName(char *buffer, size_t originalBytes, size_t bufferBytes);
function EsError EsPathMove(STRING oldPath, STRING newPath);
function EsError EsPathMove(STRING oldPath, STRING newPath, uint32_t flags = ES_FLAGS_DEFAULT);
function bool EsPathExists(STRING filePath, EsNodeType *type = ES_NULL); // Returns true if the file/directory exists.
function EsError EsPathCreate(STRING filePath, EsNodeType type, bool createLeadingDirectories);
function bool EsPathQueryInformation(STRING filePath, EsDirectoryChild *information);

View File

@ -491,7 +491,7 @@ void *EsFileMap(const char *path, ptrdiff_t pathBytes, size_t *fileSize, uint32_
return base;
}
EsError EsPathMove(const char *oldPath, ptrdiff_t oldPathBytes, const char *newPath, ptrdiff_t newPathBytes) {
EsError EsPathMove(const char *oldPath, ptrdiff_t oldPathBytes, const char *newPath, ptrdiff_t newPathBytes, uint32_t flags) {
if (oldPathBytes == -1) oldPathBytes = EsCStringLength(oldPath);
if (newPathBytes == -1) newPathBytes = EsCStringLength(newPath);
@ -508,6 +508,15 @@ EsError EsPathMove(const char *oldPath, ptrdiff_t oldPathBytes, const char *newP
if (error != ES_SUCCESS) { EsHandleClose(node.handle); return error; }
error = EsSyscall(ES_SYSCALL_NODE_MOVE, node.handle, directory.handle, (uintptr_t) newPath + s, newPathBytes - s);
if (error == ES_ERROR_VOLUME_MISMATCH && (flags & ES_PATH_MOVE_ALLOW_COPY_AND_DELETE) && (node.type == ES_NODE_FILE)) {
// The paths are on different file systems, so we cannot directly move the file.
// Instead we need to copy the file to the new path, and then delete the old file.
// TODO Does it matter that this isn't atomic?
error = EsFileCopy(oldPath, oldPathBytes, newPath, newPathBytes);
if (error == ES_SUCCESS) error = EsPathDelete(oldPath, oldPathBytes);
}
EsHandleClose(node.handle);
EsHandleClose(directory.handle);
return error;