You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
Merge pull request #106008 from beicause/cs-byte-array-compress
C#: Expose byte array compress and decompress
This commit is contained in:
@@ -682,5 +682,53 @@ namespace Godot
|
|||||||
{
|
{
|
||||||
return Marshaling.ConvertManagedTypeToVariantType(type, out bool _);
|
return Marshaling.ConvertManagedTypeToVariantType(type, out bool _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new byte array with the data compressed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The byte array to compress.</param>
|
||||||
|
/// <param name="compressionMode">The compression mode, one of <see cref="FileAccess.CompressionMode"/></param>
|
||||||
|
/// <returns>The compressed byte array.</returns>
|
||||||
|
public static byte[] Compress(this byte[] instance, FileAccess.CompressionMode compressionMode = 0)
|
||||||
|
{
|
||||||
|
using godot_packed_byte_array src = Marshaling.ConvertSystemArrayToNativePackedByteArray(instance);
|
||||||
|
NativeFuncs.godotsharp_packed_byte_array_compress(src, (int)compressionMode, out var ret);
|
||||||
|
using (ret)
|
||||||
|
return Marshaling.ConvertNativePackedByteArrayToSystemArray(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new byte array with the data decompressed.
|
||||||
|
/// <para>Note: Decompression is not guaranteed to work with data not compressed by Godot, for example if data compressed with the deflate compression mode lacks a checksum or header.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The byte array to decompress.</param>
|
||||||
|
/// <param name="bufferSize">The size of the uncompressed data.</param>
|
||||||
|
/// <param name="compressionMode">The compression mode, one of <see cref="FileAccess.CompressionMode"/></param>
|
||||||
|
/// <returns>The decompressed byte array.</returns>
|
||||||
|
public static byte[] Decompress(this byte[] instance, long bufferSize, FileAccess.CompressionMode compressionMode = 0)
|
||||||
|
{
|
||||||
|
using godot_packed_byte_array src = Marshaling.ConvertSystemArrayToNativePackedByteArray(instance);
|
||||||
|
NativeFuncs.godotsharp_packed_byte_array_decompress(src, bufferSize, (int)compressionMode, out var ret);
|
||||||
|
using (ret)
|
||||||
|
return Marshaling.ConvertNativePackedByteArrayToSystemArray(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new byte array with the data decompressed. <b>This method only accepts brotli, gzip, and deflate compression modes</b>.
|
||||||
|
/// <para>This method is potentially slower than <see cref="Decompress"/>, as it may have to re-allocate its output buffer multiple times while decompressing, whereas <see cref="Decompress"/> knows it's output buffer size from the beginning.</para>
|
||||||
|
/// <para>GZIP has a maximal compression ratio of 1032:1, meaning it's very possible for a small compressed payload to decompress to a potentially very large output. To guard against this, you may provide a maximum size this function is allowed to allocate in bytes via [param max_output_size]. Passing -1 will allow for unbounded output. If any positive value is passed, and the decompression exceeds that amount in bytes, then an error will be returned.</para>
|
||||||
|
/// <para>Note: Decompression is not guaranteed to work with data not compressed by Godot, for example if data compressed with the deflate compression mode lacks a checksum or header.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">The byte array to decompress.</param>
|
||||||
|
/// <param name="maxOutputSize">The maximum size this function is allowed to allocate in bytes.</param>
|
||||||
|
/// <param name="compressionMode">The compression mode, one of <see cref="FileAccess.CompressionMode"/></param>
|
||||||
|
/// <returns>The decompressed byte array.</returns>
|
||||||
|
public static byte[] DecompressDynamic(this byte[] instance, long maxOutputSize, FileAccess.CompressionMode compressionMode = 0)
|
||||||
|
{
|
||||||
|
using godot_packed_byte_array src = Marshaling.ConvertSystemArrayToNativePackedByteArray(instance);
|
||||||
|
NativeFuncs.godotsharp_packed_byte_array_decompress_dynamic(src, maxOutputSize, (int)compressionMode, out var ret);
|
||||||
|
using (ret)
|
||||||
|
return Marshaling.ConvertNativePackedByteArrayToSystemArray(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -433,6 +433,12 @@ namespace Godot.NativeInterop
|
|||||||
|
|
||||||
public static partial void godotsharp_array_to_string(ref godot_array p_self, out godot_string r_str);
|
public static partial void godotsharp_array_to_string(ref godot_array p_self, out godot_string r_str);
|
||||||
|
|
||||||
|
public static partial void godotsharp_packed_byte_array_compress(scoped in godot_packed_byte_array p_src, int p_mode, out godot_packed_byte_array r_dst);
|
||||||
|
|
||||||
|
public static partial void godotsharp_packed_byte_array_decompress(scoped in godot_packed_byte_array p_src, long p_buffer_size, int p_mode, out godot_packed_byte_array r_dst);
|
||||||
|
|
||||||
|
public static partial void godotsharp_packed_byte_array_decompress_dynamic(scoped in godot_packed_byte_array p_src, long p_buffer_size, int p_mode, out godot_packed_byte_array r_dst);
|
||||||
|
|
||||||
// Dictionary
|
// Dictionary
|
||||||
|
|
||||||
public static partial godot_bool godotsharp_dictionary_try_get_value(scoped ref godot_dictionary p_self,
|
public static partial godot_bool godotsharp_dictionary_try_get_value(scoped ref godot_dictionary p_self,
|
||||||
|
|||||||
@@ -1168,6 +1168,47 @@ void godotsharp_array_to_string(const Array *p_self, String *r_str) {
|
|||||||
*r_str = Variant(*p_self).operator String();
|
*r_str = Variant(*p_self).operator String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void godotsharp_packed_byte_array_compress(const PackedByteArray *p_src, int p_mode, PackedByteArray *r_dst) {
|
||||||
|
if (p_src->size() > 0) {
|
||||||
|
Compression::Mode mode = (Compression::Mode)(p_mode);
|
||||||
|
r_dst->resize(Compression::get_max_compressed_buffer_size(p_src->size(), mode));
|
||||||
|
int result = Compression::compress(r_dst->ptrw(), p_src->ptr(), p_src->size(), mode);
|
||||||
|
|
||||||
|
result = result >= 0 ? result : 0;
|
||||||
|
r_dst->resize(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void godotsharp_packed_byte_array_decompress(const PackedByteArray *p_src, int64_t p_buffer_size, int p_mode, PackedByteArray *r_dst) {
|
||||||
|
int64_t buffer_size = p_buffer_size;
|
||||||
|
Compression::Mode mode = (Compression::Mode)(p_mode);
|
||||||
|
|
||||||
|
if (buffer_size <= 0) {
|
||||||
|
ERR_FAIL_MSG("Decompression buffer size must be greater than zero.");
|
||||||
|
}
|
||||||
|
if (p_src->size() == 0) {
|
||||||
|
ERR_FAIL_MSG("Compressed buffer size must be greater than zero.");
|
||||||
|
}
|
||||||
|
|
||||||
|
r_dst->resize(buffer_size);
|
||||||
|
int result = Compression::decompress(r_dst->ptrw(), buffer_size, p_src->ptr(), p_src->size(), mode);
|
||||||
|
|
||||||
|
result = result >= 0 ? result : 0;
|
||||||
|
r_dst->resize(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void godotsharp_packed_byte_array_decompress_dynamic(const PackedByteArray *p_src, int64_t p_max_output_size, int p_mode, PackedByteArray *r_dst) {
|
||||||
|
int64_t max_output_size = p_max_output_size;
|
||||||
|
Compression::Mode mode = (Compression::Mode)(p_mode);
|
||||||
|
|
||||||
|
int result = Compression::decompress_dynamic(r_dst, max_output_size, p_src->ptr(), p_src->size(), mode);
|
||||||
|
|
||||||
|
if (result != OK) {
|
||||||
|
r_dst->clear();
|
||||||
|
ERR_FAIL_MSG("Decompression failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dictionary
|
// Dictionary
|
||||||
|
|
||||||
bool godotsharp_dictionary_try_get_value(const Dictionary *p_self, const Variant *p_key, Variant *r_value) {
|
bool godotsharp_dictionary_try_get_value(const Dictionary *p_self, const Variant *p_key, Variant *r_value) {
|
||||||
@@ -1683,6 +1724,9 @@ static const void *unmanaged_callbacks[]{
|
|||||||
(void *)godotsharp_array_slice,
|
(void *)godotsharp_array_slice,
|
||||||
(void *)godotsharp_array_sort,
|
(void *)godotsharp_array_sort,
|
||||||
(void *)godotsharp_array_to_string,
|
(void *)godotsharp_array_to_string,
|
||||||
|
(void *)godotsharp_packed_byte_array_compress,
|
||||||
|
(void *)godotsharp_packed_byte_array_decompress,
|
||||||
|
(void *)godotsharp_packed_byte_array_decompress_dynamic,
|
||||||
(void *)godotsharp_dictionary_try_get_value,
|
(void *)godotsharp_dictionary_try_get_value,
|
||||||
(void *)godotsharp_dictionary_set_value,
|
(void *)godotsharp_dictionary_set_value,
|
||||||
(void *)godotsharp_dictionary_keys,
|
(void *)godotsharp_dictionary_keys,
|
||||||
|
|||||||
Reference in New Issue
Block a user