package com.tom_roush.pdfbox.pdmodel.common.function.type4;
import java.util.Stack;
/**
* Provides the bitwise operators such as "and" and "xor".
*/
class BitwiseOperators
{
/** Abstract base class for logical operators. */
private abstract static class AbstractLogicalOperator implements Operator
{
public void execute(ExecutionContext context)
{
Stack<Object> stack = context.getStack();
Object op2 = stack.pop();
Object op1 = stack.pop();
if (op1 instanceof Boolean && op2 instanceof Boolean)
{
boolean bool1 = (Boolean)op1;
boolean bool2 = (Boolean)op2;
boolean result = applyForBoolean(bool1, bool2);
stack.push(result);
}
else if (op1 instanceof Integer && op2 instanceof Integer)
{
int int1 = (Integer)op1;
int int2 = (Integer)op2;
int result = applyforInteger(int1, int2);
stack.push(result);
}
else
{
throw new ClassCastException("Operands must be bool/bool or int/int");
}
}
protected abstract boolean applyForBoolean(boolean bool1, boolean bool2);
protected abstract int applyforInteger(int int1, int int2);
}
/** Implements the "and" operator. */
static class And extends AbstractLogicalOperator
{
@Override
protected boolean applyForBoolean(boolean bool1, boolean bool2)
{
return bool1 & bool2;
}
@Override
protected int applyforInteger(int int1, int int2)
{
return int1 & int2;
}
}
/** Implements the "bitshift" operator. */
static class Bitshift implements Operator
{
public void execute(ExecutionContext context)
{
Stack<Object> stack = context.getStack();
int shift = (Integer)stack.pop();
int int1 = (Integer)stack.pop();
if (shift < 0)
{
int result = int1 >> Math.abs(shift);
stack.push(result);
}
else
{
int result = int1 << shift;
stack.push(result);
}
}
}
/** Implements the "false" operator. */
static class False implements Operator
{
public void execute(ExecutionContext context)
{
Stack<Object> stack = context.getStack();
stack.push(Boolean.FALSE);
}
}
/** Implements the "not" operator. */
static class Not implements Operator
{
public void execute(ExecutionContext context)
{
Stack<Object> stack = context.getStack();
Object op1 = stack.pop();
if (op1 instanceof Boolean)
{
boolean bool1 = (Boolean)op1;
boolean result = !bool1;
stack.push(result);
}
else if (op1 instanceof Integer)
{
int int1 = (Integer)op1;
int result = -int1;
stack.push(result);
}
else
{
throw new ClassCastException("Operand must be bool or int");
}
}
}
/** Implements the "or" operator. */
static class Or extends AbstractLogicalOperator
{
@Override
protected boolean applyForBoolean(boolean bool1, boolean bool2)
{
return bool1 | bool2;
}
@Override
protected int applyforInteger(int int1, int int2)
{
return int1 | int2;
}
}
/** Implements the "true" operator. */
static class True implements Operator
{
public void execute(ExecutionContext context)
{
Stack<Object> stack = context.getStack();
stack.push(Boolean.TRUE);
}
}
/** Implements the "xor" operator. */
static class Xor extends AbstractLogicalOperator
{
@Override
protected boolean applyForBoolean(boolean bool1, boolean bool2)
{
return bool1 ^ bool2;
}
@Override
protected int applyforInteger(int int1, int int2)
{
return int1 ^ int2;
}
}
}