use crate::expressions::{ExpOp, ExpType, Expression, ExpressionArgument, MODIFY};
use crate::operations::bitwise::{BitPolicy, BitwiseOverflowActions, BitwiseResizeFlags};
use crate::Value;
const MODULE: i64 = 1;
const INT_FLAGS_SIGNED: i64 = 1;
pub(crate) enum BitExpOp {
Resize = 0,
Insert = 1,
Remove = 2,
Set = 3,
Or = 4,
Xor = 5,
And = 6,
Not = 7,
LShift = 8,
RShift = 9,
Add = 10,
Subtract = 11,
SetInt = 12,
Get = 50,
Count = 51,
LScan = 52,
RScan = 53,
GetInt = 54,
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn resize(
policy: &BitPolicy,
byte_size: Expression,
resize_flags: BitwiseResizeFlags,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Resize as i64)),
ExpressionArgument::FilterExpression(byte_size),
ExpressionArgument::Value(Value::from(policy.flags)),
ExpressionArgument::Value(Value::from(resize_flags as u8)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn insert(
policy: &BitPolicy,
byte_offset: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Insert as i64)),
ExpressionArgument::FilterExpression(byte_offset),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn remove(
policy: &BitPolicy,
byte_offset: Expression,
byte_size: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Remove as i64)),
ExpressionArgument::FilterExpression(byte_offset),
ExpressionArgument::FilterExpression(byte_size),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn set(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Set as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn or(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Or as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn xor(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Xor as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn and(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::And as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn not(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Not as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn lshift(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
shift: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::LShift as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(shift),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn rshift(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
shift: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::RShift as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(shift),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn add(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
signed: bool,
action: BitwiseOverflowActions,
bin: Expression,
) -> Expression {
let mut flags = action as u8;
if signed {
flags |= INT_FLAGS_SIGNED as u8;
}
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Add as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
ExpressionArgument::Value(Value::from(flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn subtract(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
signed: bool,
action: BitwiseOverflowActions,
bin: Expression,
) -> Expression {
let mut flags = action as u8;
if signed {
flags |= INT_FLAGS_SIGNED as u8;
}
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Subtract as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
ExpressionArgument::Value(Value::from(flags)),
];
add_write(bin, args)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn set_int(
policy: &BitPolicy,
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::SetInt as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
ExpressionArgument::Value(Value::from(policy.flags)),
];
add_write(bin, args)
}
pub fn get(bit_offset: Expression, bit_size: Expression, bin: Expression) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Get as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
];
add_read(bin, ExpType::BLOB, args)
}
pub fn count(bit_offset: Expression, bit_size: Expression, bin: Expression) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::Count as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
];
add_read(bin, ExpType::INT, args)
}
pub fn lscan(
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::LScan as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
];
add_read(bin, ExpType::INT, args)
}
pub fn rscan(
bit_offset: Expression,
bit_size: Expression,
value: Expression,
bin: Expression,
) -> Expression {
let args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::RScan as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
ExpressionArgument::FilterExpression(value),
];
add_read(bin, ExpType::INT, args)
}
pub fn get_int(
bit_offset: Expression,
bit_size: Expression,
signed: bool,
bin: Expression,
) -> Expression {
let mut args = vec![
ExpressionArgument::Value(Value::from(BitExpOp::GetInt as i64)),
ExpressionArgument::FilterExpression(bit_offset),
ExpressionArgument::FilterExpression(bit_size),
];
if signed {
args.push(ExpressionArgument::Value(Value::from(INT_FLAGS_SIGNED)));
}
add_read(bin, ExpType::INT, args)
}
pub(crate) fn add_write(bin: Expression, arguments: Vec<ExpressionArgument>) -> Expression {
Expression {
cmd: Some(ExpOp::Call),
val: None,
bin: Some(Box::new(bin)),
flags: Some(MODULE | MODIFY),
module: Some(ExpType::BLOB),
exps: None,
arguments: Some(arguments),
bytes: None,
}
}
pub(crate) fn add_read(
bin: Expression,
return_type: ExpType,
arguments: Vec<ExpressionArgument>,
) -> Expression {
Expression {
cmd: Some(ExpOp::Call),
val: None,
bin: Some(Box::new(bin)),
flags: Some(MODULE),
module: Some(return_type),
exps: None,
arguments: Some(arguments),
bytes: None,
}
}