static int shift_right_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { int r = 0; if (port == SOL_FLOW_NODE_TYPE_BYTE_SHIFT_RIGHT__IN__SHIFT) r = validate_shift(packet); if (r < 0) return r; return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_BYTE_SHIFT_RIGHT__OUT__OUT, packet, shift_right_func); }
static int shift_left_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { if (port == SOL_FLOW_NODE_TYPE_BYTE_SHIFT_LEFT__IN__SHIFT) { int r = validate_shift(packet); if (r < 0) { int err; unsigned char in; err = sol_flow_packet_get_byte(packet, &in); SOL_INT_CHECK(err, < 0, err); sol_flow_send_error_packet(node, -r, "Invalid values for a shift left operation: operation: %d. " "Maximum is %d", in, (CHAR_BIT - 1)); return 0; }
static int two_port_process(struct sol_flow_node *node, void *data, uint16_t port_in, uint16_t port_out, const struct sol_flow_packet *packet, int (*func)(int, int)) { struct bitwise_data *mdata = data; int r; struct sol_irange in_value; struct sol_irange out_value = { .min = INT32_MIN, .step = 1, .max = INT32_MAX }; r = sol_flow_packet_get_irange(packet, &in_value); SOL_INT_CHECK(r, < 0, r); if (port_in) { mdata->in1 = in_value.val; mdata->in1_init = true; } else { mdata->in0 = in_value.val; mdata->in0_init = true; } if (!(mdata->in0_init && mdata->in1_init)) return 0; out_value.val = func(mdata->in0, mdata->in1); if (out_value.val == mdata->result && mdata->sent_first) return 0; mdata->result = out_value.val; mdata->sent_first = true; return sol_flow_send_irange_packet(node, port_out, &out_value); } static int and_func(int in0, int in1) { return in0 & in1; } static int and_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_AND__OUT__OUT, packet, and_func); } static int or_func(int in0, int in1) { return in0 | in1; } static int or_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_OR__OUT__OUT, packet, or_func); } static int xor_func(int in0, int in1) { return in0 ^ in1; } static int xor_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_XOR__OUT__OUT, packet, xor_func); } static int validate_shift(const struct sol_flow_packet *packet) { struct sol_irange in; int r; r = sol_flow_packet_get_irange(packet, &in); SOL_INT_CHECK(r, < 0, r); if ((unsigned)in.val > (sizeof(in.val) * CHAR_BIT - 1) || in.val < 0) return -EINVAL; return 0; } static int shift_left_func(int in0, int in1) { return in0 << in1; } static int shift_left_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { int r = 0; if (port == SOL_FLOW_NODE_TYPE_INT_SHIFT_LEFT__IN__SHIFT) r = validate_shift(packet); if (r < 0) return r; return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_SHIFT_LEFT__OUT__OUT, packet, shift_left_func); }