/** * Gets the token representation of this item in RPN. The Attribute token is a special case, which * overrides anything useful we could do in the base class * * @return the bytes applicable to this formula */ byte[] getBytes() { byte[] data = new byte[0]; if (isSum()) { // Get the data for the operands ParseItem[] operands = getOperands(); // Get the operands in reverse order to get the RPN for (int i = operands.length - 1; i >= 0; i--) { byte[] opdata = operands[i].getBytes(); // Grow the array byte[] newdata = new byte[data.length + opdata.length]; System.arraycopy(data, 0, newdata, 0, data.length); System.arraycopy(opdata, 0, newdata, data.length, opdata.length); data = newdata; } // Add on the operator byte byte[] newdata = new byte[data.length + 4]; System.arraycopy(data, 0, newdata, 0, data.length); newdata[data.length] = Token.ATTRIBUTE.getCode(); newdata[data.length + 1] = sumMask; data = newdata; } else if (isIf()) { return getIf(); } return data; }
/** * Gets the associated if conditions with this attribute * * @return the associated if conditions */ private byte[] getIf() { ParseItem[] operands = ifConditions.getOperands(); // The position of the offset to the false portion of the expression int falseOffsetPos = 0; int gotoEndPos = 0; int numArgs = operands.length; // First, write out the conditions byte[] data = operands[0].getBytes(); // Grow the array by three and write out the optimized if attribute int pos = data.length; byte[] newdata = new byte[data.length + 4]; System.arraycopy(data, 0, newdata, 0, data.length); data = newdata; data[pos] = Token.ATTRIBUTE.getCode(); data[pos + 1] = 0x2; falseOffsetPos = pos + 2; // Get the true portion of the expression and add it to the array byte[] truedata = operands[1].getBytes(); newdata = new byte[data.length + truedata.length]; System.arraycopy(data, 0, newdata, 0, data.length); System.arraycopy(truedata, 0, newdata, data.length, truedata.length); data = newdata; // Grow the array by three and write out the goto end attribute pos = data.length; newdata = new byte[data.length + 4]; System.arraycopy(data, 0, newdata, 0, data.length); data = newdata; data[pos] = Token.ATTRIBUTE.getCode(); data[pos + 1] = 0x8; gotoEndPos = pos + 2; // If the false condition exists, then add that to the array if (numArgs > 2) { // Set the offset to the false expression to be the current position IntegerHelper.getTwoBytes(data.length - falseOffsetPos - 2, data, falseOffsetPos); // Copy in the false expression byte[] falsedata = operands[numArgs - 1].getBytes(); newdata = new byte[data.length + falsedata.length]; System.arraycopy(data, 0, newdata, 0, data.length); System.arraycopy(falsedata, 0, newdata, data.length, falsedata.length); data = newdata; // Write the goto to skip over the varargs token pos = data.length; newdata = new byte[data.length + 4]; System.arraycopy(data, 0, newdata, 0, data.length); data = newdata; data[pos] = Token.ATTRIBUTE.getCode(); data[pos + 1] = 0x8; data[pos + 2] = 0x3; } // Grow the array and write out the varargs function pos = data.length; newdata = new byte[data.length + 4]; System.arraycopy(data, 0, newdata, 0, data.length); data = newdata; data[pos] = Token.FUNCTIONVARARG.getCode(); data[pos + 1] = (byte) numArgs; data[pos + 2] = 1; data[pos + 3] = 0; // indicates the end of the expression // Position the final offsets int endPos = data.length - 1; if (numArgs < 3) { // Set the offset to the false expression to be the current position IntegerHelper.getTwoBytes(endPos - falseOffsetPos - 5, data, falseOffsetPos); } // Set the offset after the true expression IntegerHelper.getTwoBytes(endPos - gotoEndPos - 2, data, gotoEndPos); return data; }