Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FileAccess] Implement resize method. #90403

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/io/file_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_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("get_path"), &FileAccess::get_path);
ClassDB::bind_method(D_METHOD("get_path_absolute"), &FileAccess::get_path_absolute);
Expand Down
1 change: 1 addition & 0 deletions core/io/file_access.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class FileAccess : public RefCounted {

virtual Error get_error() const = 0; ///< get last error

virtual Error resize(int64_t p_length) = 0;
virtual void flush() = 0;
virtual void store_8(uint8_t p_dest) = 0; ///< store a byte
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
Expand Down
1 change: 1 addition & 0 deletions core/io/file_access_compressed.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class FileAccessCompressed : public FileAccess {

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 store_8(uint8_t p_dest) override; ///< store a byte

Expand Down
1 change: 1 addition & 0 deletions core/io/file_access_encrypted.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class FileAccessEncrypted : public FileAccess {

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 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
Expand Down
1 change: 1 addition & 0 deletions core/io/file_access_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class FileAccessMemory : public FileAccess {

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 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
Expand Down
1 change: 1 addition & 0 deletions core/io/file_access_pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ class FileAccessPack : public FileAccess {

virtual Error get_error() const override;

virtual Error resize(int64_t p_length) override { return ERR_UNAVAILABLE; }
virtual void flush() override;
virtual void store_8(uint8_t p_dest) override;

Expand Down
1 change: 1 addition & 0 deletions core/io/file_access_zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class FileAccessZip : public FileAccess {

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 store_8(uint8_t p_dest) override; ///< store a byte

Expand Down
7 changes: 7 additions & 0 deletions doc/classes/FileAccess.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</description>
</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">
<return type="void" />
<param index="0" name="position" type="int" />
Expand Down
17 changes: 17 additions & 0 deletions drivers/unix/file_access_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,23 @@ Error FileAccessUnix::get_error() const {
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() {
ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
fflush(f);
Expand Down
1 change: 1 addition & 0 deletions drivers/unix/file_access_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class FileAccessUnix : public FileAccess {

virtual Error get_error() const override; ///< get last error

virtual Error resize(int64_t p_length) override;
virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte
virtual void store_16(uint16_t p_dest) override;
Expand Down
1 change: 1 addition & 0 deletions drivers/unix/file_access_unix_pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class FileAccessUnixPipe : public FileAccess {

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 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
Expand Down
19 changes: 19 additions & 0 deletions drivers/windows/file_access_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <windows.h>

#include <errno.h>
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <tchar.h>
Expand Down Expand Up @@ -369,6 +370,24 @@ Error FileAccessWindows::get_error() const {
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() {
ERR_FAIL_NULL(f);

Expand Down
1 change: 1 addition & 0 deletions drivers/windows/file_access_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class FileAccessWindows : public FileAccess {

virtual Error get_error() const override; ///< get last error

virtual Error resize(int64_t p_length) override;
virtual void flush() override;
virtual void store_8(uint8_t p_dest) override; ///< store a byte
virtual void store_16(uint16_t p_dest) override;
Expand Down
1 change: 1 addition & 0 deletions drivers/windows/file_access_windows_pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class FileAccessWindowsPipe : public FileAccess {

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 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
Expand Down
1 change: 1 addition & 0 deletions platform/android/file_access_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class FileAccessAndroid : public FileAccess {

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 uint16_t get_16() const override;
virtual uint32_t get_32() const override;
Expand Down
23 changes: 23 additions & 0 deletions platform/android/file_access_filesystem_jandroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_exists = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_last_modified = nullptr;
jmethodID FileAccessFilesystemJAndroid::_file_resize = nullptr;

String FileAccessFilesystemJAndroid::get_path() const {
return path_src;
Expand Down Expand Up @@ -324,6 +325,27 @@ Error FileAccessFilesystemJAndroid::get_error() const {
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() {
if (_file_flush) {
JNIEnv *env = get_jni_env();
Expand Down Expand Up @@ -383,6 +405,7 @@ void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
_file_flush = env->GetMethodID(cls, "fileFlush", "(I)V");
_file_exists = env->GetMethodID(cls, "fileExists", "(Ljava/lang/String;)Z");
_file_last_modified = env->GetMethodID(cls, "fileLastModified", "(Ljava/lang/String;)J");
_file_resize = env->GetMethodID(cls, "fileResize", "(IJ)I");
}

void FileAccessFilesystemJAndroid::close() {
Expand Down
2 changes: 2 additions & 0 deletions platform/android/file_access_filesystem_jandroid.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class FileAccessFilesystemJAndroid : public FileAccess {
static jmethodID _file_close;
static jmethodID _file_exists;
static jmethodID _file_last_modified;
static jmethodID _file_resize;

int id;
String absolute_path;
Expand All @@ -76,6 +77,7 @@ class FileAccessFilesystemJAndroid : public FileAccess {

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 uint16_t get_16() const override;
virtual uint32_t get_32() const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ import android.util.Log
import org.godotengine.godot.io.StorageScope
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.channels.ClosedChannelException
import java.nio.channels.FileChannel
import java.nio.channels.NonWritableChannelException
import kotlin.math.max

/**
Expand All @@ -50,6 +52,11 @@ internal abstract class DataAccess(private val filePath: String) {
companion object {
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(
storageScope: StorageScope,
context: Context,
Expand Down Expand Up @@ -135,6 +142,21 @@ internal abstract class DataAccess(private val filePath: String) {
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 {
return try {
fileChannel.position()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class FileAccessHandler(val context: Context) {
companion object {
private val TAG = FileAccessHandler::class.java.simpleName

private const val FAILED_ERROR_ID = -1;
private const val FILE_NOT_FOUND_ERROR_ID = -1
internal const val INVALID_FILE_ID = 0
private const val STARTING_FILE_ID = 1
Expand Down Expand Up @@ -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 {
if (!hasFileId(fileId)) {
return 0L
Expand Down
Loading