[FileAccess] Implement `resize` method.

This commit is contained in:
bruvzg 2024-04-08 22:09:34 +03:00
parent 029aadef56
commit 88b3e68f93
No known key found for this signature in database
GPG Key ID: 7960FCF39844EC38
19 changed files with 111 additions and 0 deletions

View File

@ -867,6 +867,7 @@ void FileAccess::_bind_methods() {
ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_bytes", "path"), &FileAccess::_get_file_as_bytes); ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_bytes", "path"), &FileAccess::_get_file_as_bytes);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_string", "path"), &FileAccess::_get_file_as_string); ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_string", "path"), &FileAccess::_get_file_as_string);
ClassDB::bind_method(D_METHOD("resize", "length"), &FileAccess::resize);
ClassDB::bind_method(D_METHOD("flush"), &FileAccess::flush); ClassDB::bind_method(D_METHOD("flush"), &FileAccess::flush);
ClassDB::bind_method(D_METHOD("get_path"), &FileAccess::get_path); ClassDB::bind_method(D_METHOD("get_path"), &FileAccess::get_path);
ClassDB::bind_method(D_METHOD("get_path_absolute"), &FileAccess::get_path_absolute); ClassDB::bind_method(D_METHOD("get_path_absolute"), &FileAccess::get_path_absolute);

View File

@ -166,6 +166,7 @@ public:
virtual Error get_error() const = 0; ///< get last error virtual Error get_error() const = 0; ///< get last error
virtual Error resize(int64_t p_length) = 0;
virtual void flush() = 0; virtual void flush() = 0;
virtual void store_8(uint8_t p_dest) = 0; ///< store a byte virtual void store_8(uint8_t p_dest) = 0; ///< store a byte
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint virtual void store_16(uint16_t p_dest); ///< store 16 bits uint

View File

@ -88,6 +88,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte virtual void store_8(uint8_t p_dest) override; ///< store a byte

View File

@ -78,6 +78,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte virtual void store_8(uint8_t p_dest) override; ///< store a byte
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes

View File

@ -61,6 +61,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_byte) override; ///< store a byte virtual void store_8(uint8_t p_byte) override; ///< store a byte
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes

View File

@ -177,6 +177,7 @@ public:
virtual Error get_error() const override; virtual Error get_error() const override;
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; virtual void store_8(uint8_t p_dest) override;

View File

@ -100,6 +100,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte virtual void store_8(uint8_t p_dest) override; ///< store a byte

View File

@ -324,6 +324,13 @@
Returns [code]null[/code] if opening the file failed. You can use [method get_open_error] to check the error that occurred. Returns [code]null[/code] if opening the file failed. You can use [method get_open_error] to check the error that occurred.
</description> </description>
</method> </method>
<method name="resize">
<return type="int" enum="Error" />
<param index="0" name="length" type="int" />
<description>
Resizes the file to a specified length. The file must be open in a mode that permits writing. If the file is extended, NUL characters are appended. If the file is truncated, all data from the end file to the original length of the file is lost.
</description>
</method>
<method name="seek"> <method name="seek">
<return type="void" /> <return type="void" />
<param index="0" name="position" type="int" /> <param index="0" name="position" type="int" />

View File

@ -286,6 +286,23 @@ Error FileAccessUnix::get_error() const {
return last_error; return last_error;
} }
Error FileAccessUnix::resize(int64_t p_length) {
ERR_FAIL_NULL_V_MSG(f, FAILED, "File must be opened before use.");
int res = ::ftruncate(fileno(f), p_length);
switch (res) {
case 0:
return OK;
case EBADF:
return ERR_FILE_CANT_OPEN;
case EFBIG:
return ERR_OUT_OF_MEMORY;
case EINVAL:
return ERR_INVALID_PARAMETER;
default:
return FAILED;
}
}
void FileAccessUnix::flush() { void FileAccessUnix::flush() {
ERR_FAIL_NULL_MSG(f, "File must be opened before use."); ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
fflush(f); fflush(f);

View File

@ -75,6 +75,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override;
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte virtual void store_8(uint8_t p_dest) override; ///< store a byte
virtual void store_16(uint16_t p_dest) override; virtual void store_16(uint16_t p_dest) override;

View File

@ -70,6 +70,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override {} virtual void flush() override {}
virtual void store_8(uint8_t p_src) override; ///< store a byte virtual void store_8(uint8_t p_src) override; ///< store a byte
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes

View File

@ -41,6 +41,7 @@
#include <windows.h> #include <windows.h>
#include <errno.h> #include <errno.h>
#include <io.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <tchar.h> #include <tchar.h>
@ -369,6 +370,24 @@ Error FileAccessWindows::get_error() const {
return last_error; return last_error;
} }
Error FileAccessWindows::resize(int64_t p_length) {
ERR_FAIL_NULL_V_MSG(f, FAILED, "File must be opened before use.");
errno_t res = _chsize_s(_fileno(f), p_length);
switch (res) {
case 0:
return OK;
case EACCES:
case EBADF:
return ERR_FILE_CANT_OPEN;
case ENOSPC:
return ERR_OUT_OF_MEMORY;
case EINVAL:
return ERR_INVALID_PARAMETER;
default:
return FAILED;
}
}
void FileAccessWindows::flush() { void FileAccessWindows::flush() {
ERR_FAIL_NULL(f); ERR_FAIL_NULL(f);

View File

@ -77,6 +77,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override;
virtual void flush() override; virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte virtual void store_8(uint8_t p_dest) override; ///< store a byte
virtual void store_16(uint16_t p_dest) override; virtual void store_16(uint16_t p_dest) override;

View File

@ -69,6 +69,7 @@ public:
virtual Error get_error() const override; ///< get last error virtual Error get_error() const override; ///< get last error
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override {} virtual void flush() override {}
virtual void store_8(uint8_t p_src) override; ///< store a byte virtual void store_8(uint8_t p_src) override; ///< store a byte
virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes virtual void store_buffer(const uint8_t *p_src, uint64_t p_length) override; ///< store an array of bytes

View File

@ -65,6 +65,7 @@ public:
virtual bool eof_reached() const override; // reading passed EOF virtual bool eof_reached() const override; // reading passed EOF
virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual uint8_t get_8() const override; // get a byte virtual uint8_t get_8() const override; // get a byte
virtual uint16_t get_16() const override; virtual uint16_t get_16() const override;
virtual uint32_t get_32() const override; virtual uint32_t get_32() const override;

View File

@ -53,6 +53,7 @@ jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr; jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr; jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr; jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_resize = nullptr;
String FileAccessFilesystemJAndroid::get_path() const { String FileAccessFilesystemJAndroid::get_path() const {
return path_src; return path_src;
@ -324,6 +325,27 @@ Error FileAccessFilesystemJAndroid::get_error() const {
return OK; return OK;
} }
Error FileAccessFilesystemJAndroid::resize(int64_t p_length) {
if (_file_resize) {
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL_V(env, FAILED);
ERR_FAIL_COND_V_MSG(!is_open(), FAILED, "File must be opened before use.");
int res = env->CallIntMethod(file_access_handler, _file_resize, id, p_length);
switch (res) {
case 0:
return OK;
case -3:
return ERR_INVALID_PARAMETER;
case -2:
return ERR_FILE_CANT_OPEN;
default:
return FAILED;
}
} else {
return ERR_UNAVAILABLE;
}
}
void FileAccessFilesystemJAndroid::flush() { void FileAccessFilesystemJAndroid::flush() {
if (_file_flush) { if (_file_flush) {
JNIEnv *env = get_jni_env(); JNIEnv *env = get_jni_env();
@ -383,6 +405,7 @@ void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
_file_flush = env->GetMethodID(cls, "fileFlush", "(I)V"); _file_flush = env->GetMethodID(cls, "fileFlush", "(I)V");
_file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z"); _file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z");
_file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J"); _file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J");
_file_resize = env->GetMethodID(cls, "fileResize", "(IJ)I");
} }
void FileAccessFilesystemJAndroid::close() { void FileAccessFilesystemJAndroid::close() {

View File

@ -52,6 +52,7 @@ class FileAccessFilesystemJAndroid : public FileAccess {
static jmethodID _file_close; static jmethodID _file_close;
static jmethodID _file_exists; static jmethodID _file_exists;
static jmethodID _file_last_modified; static jmethodID _file_last_modified;
static jmethodID _file_resize;
int id; int id;
String absolute_path; String absolute_path;
@ -76,6 +77,7 @@ public:
virtual bool eof_reached() const override; ///< reading passed EOF virtual bool eof_reached() const override; ///< reading passed EOF
virtual Error resize(int64_t p_length) override;
virtual uint8_t get_8() const override; ///< get a byte virtual uint8_t get_8() const override; ///< get a byte
virtual uint16_t get_16() const override; virtual uint16_t get_16() const override;
virtual uint32_t get_32() const override; virtual uint32_t get_32() const override;

View File

@ -36,7 +36,9 @@ import android.util.Log
import org.godotengine.godot.io.StorageScope import org.godotengine.godot.io.StorageScope
import java.io.IOException import java.io.IOException
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.channels.ClosedChannelException
import java.nio.channels.FileChannel import java.nio.channels.FileChannel
import java.nio.channels.NonWritableChannelException
import kotlin.math.max import kotlin.math.max
/** /**
@ -50,6 +52,11 @@ internal abstract class DataAccess(private val filePath: String) {
companion object { companion object {
private val TAG = DataAccess::class.java.simpleName private val TAG = DataAccess::class.java.simpleName
private const val OK_ERROR_ID = 0;
private const val FAILED_ERROR_ID = -1;
private const val FILE_CANT_OPEN_ERROR_ID = -2;
private const val INVALID_PARAMETER_ERROR_ID = -3;
fun generateDataAccess( fun generateDataAccess(
storageScope: StorageScope, storageScope: StorageScope,
context: Context, context: Context,
@ -135,6 +142,21 @@ internal abstract class DataAccess(private val filePath: String) {
seek(positionFromBeginning) seek(positionFromBeginning)
} }
fun resize(length: Long): Int {
return try {
fileChannel.truncate(length)
OK_ERROR_ID
} catch (e: NonWritableChannelException) {
FILE_CANT_OPEN_ERROR_ID
} catch (e: ClosedChannelException) {
FILE_CANT_OPEN_ERROR_ID
} catch (e: IllegalArgumentException) {
INVALID_PARAMETER_ERROR_ID
} catch (e: IOException) {
FAILED_ERROR_ID
}
}
fun position(): Long { fun position(): Long {
return try { return try {
fileChannel.position() fileChannel.position()

View File

@ -45,6 +45,7 @@ class FileAccessHandler(val context: Context) {
companion object { companion object {
private val TAG = FileAccessHandler::class.java.simpleName private val TAG = FileAccessHandler::class.java.simpleName
private const val FAILED_ERROR_ID = -1;
private const val FILE_NOT_FOUND_ERROR_ID = -1 private const val FILE_NOT_FOUND_ERROR_ID = -1
internal const val INVALID_FILE_ID = 0 internal const val INVALID_FILE_ID = 0
private const val STARTING_FILE_ID = 1 private const val STARTING_FILE_ID = 1
@ -190,6 +191,14 @@ class FileAccessHandler(val context: Context) {
} }
} }
fun fileResize(fileId: Int, length: Long): Int {
if (!hasFileId(fileId)) {
return FAILED_ERROR_ID
}
return files[fileId].resize(length)
}
fun fileGetPosition(fileId: Int): Long { fun fileGetPosition(fileId: Int): Long {
if (!hasFileId(fileId)) { if (!hasFileId(fileId)) {
return 0L return 0L