mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
compress: Add gzip module & refactor compress & compress.zlib module (#14599)
This commit is contained in:
parent
251716fa0e
commit
65066098d8
@ -1,4 +1,4 @@
|
|||||||
## Description:
|
## Description:
|
||||||
|
|
||||||
`compress` is a namespace for (multiple) compression algorithms supported by V.
|
`compress` is a namespace for (multiple) compression algorithms supported by V.
|
||||||
At the moment, only `compress.zlib` is implemented.
|
At the moment, only `compress.zlib` and `compress.gzip` are implemented.
|
||||||
|
44
vlib/compress/compress.v
Normal file
44
vlib/compress/compress.v
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
module compress
|
||||||
|
|
||||||
|
#flag -I @VEXEROOT/thirdparty/zip
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
|
pub const max_size = u64(1 << 31)
|
||||||
|
|
||||||
|
fn C.tdefl_compress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr
|
||||||
|
fn C.tinfl_decompress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr
|
||||||
|
|
||||||
|
// compresses an array of bytes based on providing flags and returns the compressed bytes in a new array
|
||||||
|
// see `gzip.compress([]u8)` and `zlib.compress([]u8)` for default implementations.
|
||||||
|
[manualfree]
|
||||||
|
pub fn compress(data []u8, flags int) ?[]u8 {
|
||||||
|
if u64(data.len) > compress.max_size {
|
||||||
|
return error('data too large ($data.len > $compress.max_size)')
|
||||||
|
}
|
||||||
|
mut out_len := usize(0)
|
||||||
|
|
||||||
|
address := C.tdefl_compress_mem_to_heap(data.data, data.len, &out_len, flags)
|
||||||
|
if address == 0 {
|
||||||
|
return error('compression failed')
|
||||||
|
}
|
||||||
|
if u64(out_len) > compress.max_size {
|
||||||
|
return error('compressed data is too large ($out_len > $compress.max_size)')
|
||||||
|
}
|
||||||
|
return unsafe { address.vbytes(int(out_len)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// decompresses an array of bytes based on providing flags and returns the decompressed bytes in a new array
|
||||||
|
// see `gzip.decompress([]u8)` and `zlib.decompress([]u8)` for default implementations.
|
||||||
|
[manualfree]
|
||||||
|
pub fn decompress(data []u8, flags int) ?[]u8 {
|
||||||
|
mut out_len := usize(0)
|
||||||
|
|
||||||
|
address := C.tinfl_decompress_mem_to_heap(data.data, data.len, &out_len, flags)
|
||||||
|
if address == 0 {
|
||||||
|
return error('decompression failed')
|
||||||
|
}
|
||||||
|
if u64(out_len) > compress.max_size {
|
||||||
|
return error('decompressed data is too large ($out_len > $compress.max_size)')
|
||||||
|
}
|
||||||
|
return unsafe { address.vbytes(int(out_len)) }
|
||||||
|
}
|
17
vlib/compress/gzip/README.md
Normal file
17
vlib/compress/gzip/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## Description:
|
||||||
|
|
||||||
|
`compress.gzip` is a module that assists in the compression and
|
||||||
|
decompression of binary data using `gzip` compression
|
||||||
|
|
||||||
|
## Examples:
|
||||||
|
|
||||||
|
```v
|
||||||
|
import compress.gzip
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
uncompressed := 'Hello world!'
|
||||||
|
compressed := gzip.compress(uncompressed.bytes())?
|
||||||
|
decompressed := gzip.decompress(compressed)?
|
||||||
|
assert decompressed == uncompressed.bytes()
|
||||||
|
}
|
||||||
|
```
|
16
vlib/compress/gzip/gzip.v
Normal file
16
vlib/compress/gzip/gzip.v
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module gzip
|
||||||
|
|
||||||
|
import compress
|
||||||
|
|
||||||
|
// compresses an array of bytes using gzip and returns the compressed bytes in a new array
|
||||||
|
// Example: compressed := gzip.compress(b)?
|
||||||
|
pub fn compress(data []u8) ?[]u8 {
|
||||||
|
return compress.compress(data, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
||||||
|
// Example: decompressed := zlib.decompress(b)?
|
||||||
|
[manualfree]
|
||||||
|
pub fn decompress(data []u8) ?[]u8 {
|
||||||
|
return compress.decompress(data, 0)
|
||||||
|
}
|
8
vlib/compress/gzip/gzip_test.v
Normal file
8
vlib/compress/gzip/gzip_test.v
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module gzip
|
||||||
|
|
||||||
|
fn test_gzip() ? {
|
||||||
|
uncompressed := 'Hello world!'
|
||||||
|
compressed := compress(uncompressed.bytes())?
|
||||||
|
decompressed := decompress(compressed)?
|
||||||
|
assert decompressed == uncompressed.bytes()
|
||||||
|
}
|
@ -1,60 +1,19 @@
|
|||||||
module zlib
|
module zlib
|
||||||
|
|
||||||
#flag -I @VEXEROOT/thirdparty/zip
|
import compress
|
||||||
#include "miniz.h"
|
|
||||||
|
|
||||||
pub const max_size = u64(1 << 31)
|
|
||||||
|
|
||||||
fn C.tdefl_compress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr
|
|
||||||
fn C.tinfl_decompress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr
|
|
||||||
|
|
||||||
// compresses an array of bytes using zlib and returns the compressed bytes in a new array
|
// compresses an array of bytes using zlib and returns the compressed bytes in a new array
|
||||||
// Example: compressed := zlib.compress(b)?
|
// Example: compressed := zlib.compress(b)?
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn compress(data []u8) ?[]u8 {
|
pub fn compress(data []u8) ?[]u8 {
|
||||||
if u64(data.len) > zlib.max_size {
|
|
||||||
return error('data too large ($data.len > $zlib.max_size)')
|
|
||||||
}
|
|
||||||
mut out_len := usize(0)
|
|
||||||
|
|
||||||
// flags = TDEFL_WRITE_ZLIB_HEADER (0x01000)
|
// flags = TDEFL_WRITE_ZLIB_HEADER (0x01000)
|
||||||
address := C.tdefl_compress_mem_to_heap(data.data, data.len, &out_len, 0x01000)
|
return compress.compress(data, 0x01000)
|
||||||
if address == 0 {
|
|
||||||
return error('compression failed')
|
|
||||||
}
|
|
||||||
if u64(out_len) > zlib.max_size {
|
|
||||||
return error('compressed data is too large ($out_len > $zlib.max_size)')
|
|
||||||
}
|
|
||||||
compressed := unsafe {
|
|
||||||
address.vbytes(int(out_len))
|
|
||||||
}
|
|
||||||
copy := compressed.clone()
|
|
||||||
unsafe {
|
|
||||||
free(address)
|
|
||||||
}
|
|
||||||
return copy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
||||||
// Example: decompressed := zlib.decompress(b)?
|
// Example: decompressed := zlib.decompress(b)?
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn decompress(data []u8) ?[]u8 {
|
pub fn decompress(data []u8) ?[]u8 {
|
||||||
mut out_len := usize(0)
|
|
||||||
|
|
||||||
// flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1)
|
// flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1)
|
||||||
address := C.tinfl_decompress_mem_to_heap(data.data, data.len, &out_len, 0x1)
|
return compress.decompress(data, 0x1)
|
||||||
if address == 0 {
|
|
||||||
return error('decompression failed')
|
|
||||||
}
|
|
||||||
if u64(out_len) > zlib.max_size {
|
|
||||||
return error('decompressed data is too large ($out_len > $zlib.max_size)')
|
|
||||||
}
|
|
||||||
decompressed := unsafe {
|
|
||||||
address.vbytes(int(out_len))
|
|
||||||
}
|
|
||||||
copy := decompressed.clone()
|
|
||||||
unsafe {
|
|
||||||
free(address)
|
|
||||||
}
|
|
||||||
return copy
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user