AbstractExpression* AbstractExpression::buildExpressionTree_recurse(json_spirit::Object &obj) { // build a tree recursively from the bottom upwards. // when the expression node is instantiated, its type, // value and child types will have been discovered. ExpressionType peek_type = EXPRESSION_TYPE_INVALID; ValueType value_type = VALUE_TYPE_INVALID; AbstractExpression *left_child = NULL; AbstractExpression *right_child = NULL; std::vector<AbstractExpression*>* argsVector = NULL; // read the expression type json_spirit::Value expressionTypeValue = json_spirit::find_value(obj, "TYPE"); if (expressionTypeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find TYPE value"); } assert(stringToExpression(expressionTypeValue.get_str()) != EXPRESSION_TYPE_INVALID); peek_type = stringToExpression(expressionTypeValue.get_str()); // and the value type json_spirit::Value valueTypeValue = json_spirit::find_value(obj, "VALUE_TYPE"); if (valueTypeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find VALUE_TYPE value"); } std::string valueTypeString = valueTypeValue.get_str(); value_type = stringToValue(valueTypeString); assert(value_type != VALUE_TYPE_INVALID); // add the value size json_spirit::Value valueSizeValue = json_spirit::find_value(obj, "VALUE_SIZE"); if (valueSizeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find VALUE_SIZE value"); } int valueSize = valueSizeValue.get_int(); // recurse to children try { json_spirit::Value leftValue = json_spirit::find_value(obj, "LEFT"); if (!(leftValue == json_spirit::Value::null)) { left_child = AbstractExpression::buildExpressionTree_recurse(leftValue.get_obj()); } json_spirit::Value rightValue = json_spirit::find_value( obj, "RIGHT"); if (!(rightValue == json_spirit::Value::null)) { right_child = AbstractExpression::buildExpressionTree_recurse(rightValue.get_obj()); } // NULL argsVector corresponds to a missing ARGS value // vs. an empty argsVector which corresponds to an empty array ARGS value. // Different expression types could assert either a NULL or non-NULL argsVector initializer. json_spirit::Value argsValue = json_spirit::find_value(obj, "ARGS"); if (!(argsValue == json_spirit::Value::null)) { argsVector = new std::vector<AbstractExpression*>(); json_spirit::Array argsArray = argsValue.get_array(); for (int ii = 0; ii < argsArray.size(); ii++) { json_spirit::Value argValue = argsArray[ii]; AbstractExpression* argExpr = AbstractExpression::buildExpressionTree_recurse(argValue.get_obj()); argsVector->push_back(argExpr); } } // invoke the factory. obviously it has to handle null children. // pass it the serialization stream in case a subclass has more // to read. yes, the per-class data really does follow the // child serializations. return ExpressionUtil::expressionFactory(obj, peek_type, value_type, valueSize, left_child, right_child, argsVector); } catch (const SerializableEEException &ex) { delete left_child; delete right_child; delete argsVector; throw; } }
AbstractExpression* AbstractExpression::buildExpressionTree_recurse(json_spirit::Object &obj) { // build a tree recursively from the bottom upwards. // when the expression node is instantiated, its type, // value and child types will have been discovered. ExpressionType peek_type = EXPRESSION_TYPE_INVALID; ValueType value_type = VALUE_TYPE_INVALID; AbstractExpression *left_child = NULL; AbstractExpression *right_child = NULL; // read the expression type json_spirit::Value expressionTypeValue = json_spirit::find_value(obj, "TYPE"); if (expressionTypeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find TYPE value"); } assert(stringToExpression(expressionTypeValue.get_str()) != EXPRESSION_TYPE_INVALID); peek_type = stringToExpression(expressionTypeValue.get_str()); // and the value type json_spirit::Value valueTypeValue = json_spirit::find_value(obj, "VALUE_TYPE"); if (valueTypeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find VALUE_TYPE value"); } std::string valueTypeString = valueTypeValue.get_str(); value_type = stringToValue(valueTypeString); // this should be relatively safe, though it ignores overflow. if ((value_type == VALUE_TYPE_TINYINT) || (value_type == VALUE_TYPE_SMALLINT) || (value_type == VALUE_TYPE_INTEGER)) { value_type = VALUE_TYPE_BIGINT; } assert(value_type != VALUE_TYPE_INVALID); // add the value size json_spirit::Value valueSizeValue = json_spirit::find_value(obj, "VALUE_SIZE"); if (valueSizeValue == json_spirit::Value::null) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AbstractExpression::" "buildExpressionTree_recurse:" " Couldn't find VALUE_SIZE value"); } int valueSize = valueSizeValue.get_int(); // recurse to children try { json_spirit::Value leftValue = json_spirit::find_value(obj, "LEFT"); if (!(leftValue == json_spirit::Value::null)) { left_child = AbstractExpression::buildExpressionTree_recurse(leftValue.get_obj()); } else { left_child = NULL; } json_spirit::Value rightValue = json_spirit::find_value( obj, "RIGHT"); if (!(rightValue == json_spirit::Value::null)) { right_child = AbstractExpression::buildExpressionTree_recurse(rightValue.get_obj()); } else { right_child = NULL; } // invoke the factory. obviously it has to handle null children. // pass it the serialization stream in case a subclass has more // to read. yes, the per-class data really does follow the // child serializations. return expressionFactory(obj, peek_type, value_type, valueSize, left_child, right_child); } catch (SerializableEEException &ex) { delete left_child; delete right_child; throw; } }