Browse Source

Implemented file_removeFile.

David Piuva 3 years ago
parent
commit
429230788a

+ 14 - 0
Source/DFPSR/api/fileAPI.cpp

@@ -658,4 +658,18 @@ bool file_removeEmptyFolder(const ReadableString& path) {
 	return result;
 }
 
+bool file_removeFile(const ReadableString& filename) {
+	bool result = false;
+	String optimizedPath = file_optimizePath(filename, LOCAL_PATH_SYNTAX);
+	Buffer buffer;
+	const NativeChar *nativePath = toNativeString(filename, buffer);
+	// Remove the empty folder.
+	#ifdef USE_MICROSOFT_WINDOWS
+		result = (DeleteFileW(nativePath) != 0);
+	#else
+		result = (unlink(nativePath) == 0);
+	#endif
+	return result;
+}
+
 }

+ 6 - 7
Source/DFPSR/api/fileAPI.h

@@ -21,13 +21,6 @@
 //    3. This notice may not be removed or altered from any source
 //    distribution.
 
-/*
-TODO:
-* Test that overwriting a large file with a smaller file does not leave anything from the overwritten file on any system.
-* bool file_removeFile(const ReadableString& path);
-	bool DeleteFileW (LPCWSTR lpFileName);
-*/
-
 #ifndef DFPSR_API_FILE
 #define DFPSR_API_FILE
 
@@ -270,6 +263,12 @@ namespace dsr {
 	// Side-effects: Removes the folder at path.
 	// Post-condition: Returns true iff the operation was successful.
 	bool file_removeEmptyFolder(const ReadableString& path);
+
+	// Path-syntax: According to the local computer.
+	// Pre-condition: The file at path must exist.
+	// Side-effects: Removes the file at path. If the same file exists at multiple paths in the system, only the link to the file will be removed.
+	// Post-condition: Returns true iff the operation was successful.
+	bool file_removeFile(const ReadableString& filename);
 }
 
 #endif

+ 4 - 2
Source/DFPSR/api/stringAPI.cpp

@@ -736,10 +736,12 @@ static void encodeText(const ByteWriterFunction &receiver, String content, bool
 
 // Encoding to a buffer before saving all at once as a binary file.
 //   This tells the operating system how big the file is in advance and prevent the worst case of stalling for minutes!
-void dsr::string_save(const ReadableString& filename, const ReadableString& content, CharacterEncoding characterEncoding, LineEncoding lineEncoding) {
+bool dsr::string_save(const ReadableString& filename, const ReadableString& content, CharacterEncoding characterEncoding, LineEncoding lineEncoding) {
 	Buffer buffer = string_saveToMemory(content, characterEncoding, lineEncoding);
 	if (buffer_exists(buffer)) {
-		file_saveBuffer(filename, buffer);
+		return file_saveBuffer(filename, buffer);
+	} else {
+		return false;
 	}
 }
 

+ 2 - 1
Source/DFPSR/api/stringAPI.h

@@ -288,11 +288,12 @@ String string_loadFromMemory(Buffer fileContent);
 String string_dangerous_decodeFromData(const void* data, CharacterEncoding encoding);
 
 // Side-effect: Saves content to filename using the selected character and line encodings.
+// Post-condition: Returns true on success and false on failure.
 // Do not add carriage return characters yourself into strings, for these will be added automatically in the CrLf mode.
 // The internal String type should only use UTF-32 with single line feeds for breaking lines.
 //   This makes text processing algorithms a lot cleaner when a character or line break is always one element.
 // UTF-8 with BOM is default by being both compact and capable of storing 21 bits of unicode.
-void string_save(const ReadableString& filename, const ReadableString& content,
+bool string_save(const ReadableString& filename, const ReadableString& content,
   CharacterEncoding characterEncoding = CharacterEncoding::BOM_UTF8,
   LineEncoding lineEncoding = LineEncoding::CrLf
 );

+ 17 - 1
Source/test/tests/FileTest.cpp

@@ -121,7 +121,9 @@ START_TEST(File)
 	{ // Nested creation and removal
 		String childPathA = file_combinePaths(U"FooBarParent", U"FooBarChildA", LOCAL_PATH_SYNTAX);
 		String childPathB = file_combinePaths(U"FooBarParent", U"FooBarChildB", LOCAL_PATH_SYNTAX);
+		String filePathC = file_combinePaths(childPathA, U"testC.txt", LOCAL_PATH_SYNTAX);
 		// Prepare by removing any old folder from aborted tests.
+		if (file_getEntryType(filePathC) == EntryType::File) file_removeFile(filePathC);
 		if (file_getEntryType(childPathA) == EntryType::Folder) file_removeEmptyFolder(childPathA);
 		if (file_getEntryType(childPathB) == EntryType::Folder) file_removeEmptyFolder(childPathB);
 		if (file_getEntryType(U"FooBarParent") == EntryType::Folder) file_removeEmptyFolder(U"FooBarParent");
@@ -131,7 +133,7 @@ START_TEST(File)
 		ASSERT_EQUAL(file_createFolder(U"FooBarParent"), true); 
 		// Check that the folder does exist.
 		ASSERT_EQUAL(file_getEntryType(U"FooBarParent"), EntryType::Folder);
-		// Create a child folder.
+		// Create child folders.
 		ASSERT_EQUAL(file_getEntryType(childPathA), EntryType::NotFound);
 		ASSERT_EQUAL(file_getEntryType(childPathB), EntryType::NotFound);
 		ASSERT_EQUAL(file_createFolder(childPathA), true);
@@ -140,6 +142,19 @@ START_TEST(File)
 		ASSERT_EQUAL(file_createFolder(childPathB), true);
 		ASSERT_EQUAL(file_getEntryType(childPathA), EntryType::Folder);
 		ASSERT_EQUAL(file_getEntryType(childPathB), EntryType::Folder);
+		// Create a file in the FooBarParent/FooBarChildA folder.
+		ASSERT_EQUAL(string_save(filePathC, U"Testing", CharacterEncoding::Raw_Latin1), true);
+		ASSERT_EQUAL(file_getEntryType(filePathC), EntryType::File);
+		ASSERT_MATCH(string_load(filePathC, false), U"Testing");
+		ASSERT_EQUAL(file_getFileSize(filePathC), 7);
+		ASSERT_EQUAL(string_save(filePathC, U"Test", CharacterEncoding::Raw_Latin1), true);
+		ASSERT_MATCH(string_load(filePathC, false), U"Test");
+		ASSERT_EQUAL(file_getFileSize(filePathC), 4);
+		ASSERT_EQUAL(file_removeEmptyFolder(childPathA), false); // Trying to remove FooBarParent/FooBarChildA now should fail.
+		// Remove the file.
+		ASSERT_EQUAL(file_removeFile(filePathC), true);
+		ASSERT_EQUAL(file_getEntryType(filePathC), EntryType::NotFound);
+		// Remove the child folders.
 		ASSERT_EQUAL(file_removeEmptyFolder(U"FooBarParent"), false); // Trying to remove the parent now should fail.
 		ASSERT_EQUAL(file_removeEmptyFolder(childPathA), true);
 		ASSERT_EQUAL(file_getEntryType(childPathA), EntryType::NotFound);
@@ -148,6 +163,7 @@ START_TEST(File)
 		ASSERT_EQUAL(file_removeEmptyFolder(childPathB), true);
 		ASSERT_EQUAL(file_getEntryType(childPathA), EntryType::NotFound);
 		ASSERT_EQUAL(file_getEntryType(childPathB), EntryType::NotFound);
+		// Remove the parent folder.
 		ASSERT_EQUAL(file_removeEmptyFolder(U"FooBarParent"), true); // Trying to remove the parent now should succeed now that it's empty.
 		ASSERT_EQUAL(file_getEntryType(U"FooBarParent"), EntryType::NotFound); // Now the parent folder should no longer exist.
 	}