5个版本
使用旧的Rust 2015
0.1.4 | 2017年9月21日 |
---|---|
0.1.3 | 2016年7月13日 |
0.1.2 | 2016年6月20日 |
0.1.1 | 2016年6月13日 |
0.1.0 | 2016年6月11日 |
#688 in 压缩
在2个crate中使用(通过mayda_codec)
32KB
697 行
用于生成基本编码和解码函数的编译器插件。由encode!
和decode!
语法扩展生成的函数遵循encode_T_a_b
约定。由encode_simd!
和decode_simd!
语法扩展生成的函数遵循encode_simd_T_a
约定。由encode_util!
语法扩展生成的函数遵循encode_delta_T
和encode_zz_shift_T
约定。T
是未签名整数类型之一,a
是每个整数的位数,b
是编码的整数数量。
encode!
和decode!
以位宽和整数数量的步长(32的除数)作为参数。为位宽在0...max_bits
之间,以及整数数量为步长的倍数(最多32个)的函数生成。 encode_simd!
和decode_simd!
以位宽和相应simd模块的路径作为参数。为位宽在0...max_bits
之间,以及恰好128个整数的函数生成。encode_util!
以位宽和相应simd模块的路径作为参数。为类型位宽和任意数量的整数生成函数。
由 encode!
和 decode!
生成的函数指针分别位于 ENCODE_T
和 DECODE_T
中,其中 encode_T_a_b
的指针位于 ENCODE_T[a][b / c - 1]
,其中 c
表示步长。由 encode_simd!
和 decode_simd!
生成的函数指针分别位于 ENCODE_SIMD_T
和 DECODE_SIMD_T
中,其中 encode_simd_T_a
的指针位于 ENCODE_SIMD_T[a]
。由 encode_util!
生成的函数是公开的。所有数组都是公开的且是常量。
安全性
由本软件包生成的函数使用广泛的不安全指针操作。您必须验证在指针之后已经分配了足够的内存,以便偏移量有效。它们不打算在 mayda
软件包之外使用。
示例
本软件包中定义的语法扩展可以如下调用
encode!(u32, 32, 8);
decode!(u32, 32, 8);
这会被替换成 128 个编码 u32 整数的函数和 128 个解码 u32 整数的函数。例如,编码和解码 8 个 u32 整数的最低 24 位的函数是
unsafe fn encode_u32_24_8(mut i_ptr: *const u32, mut s_ptr: *mut u32) {
let mut out = *i_ptr as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 24usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 8usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 16usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 16usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 8usize;
i_ptr = i_ptr.offset(1);
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = *i_ptr as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 24usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 8usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 16usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 16usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 8usize;
*s_ptr = out;
}
unsafe fn decode_u32_24_8(mut s_ptr: *const u32, mut o_ptr: *mut u32) {
let mask: u32 = !0 >> 8usize;
let mut out;
out = *s_ptr as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 24usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 8usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 16usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 16usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 8usize) as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
s_ptr = s_ptr.offset(1);
out = *s_ptr as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 24usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 8usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 16usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 16usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 8usize) as u32;
*o_ptr = out & mask;
}