Expression Value(IParser parser, Expression valueType, RuntimeSchema schema) { Debug.Assert(schema.HasValue); if (parser.IsBonded || (untaggedWriter && schema.IsBonded)) { return(parser.Bonded(value => writer.WriteBonded(PrunedExpression.Convert(value, typeof(IBonded))))); } if (schema.IsStruct) { return(GenerateSerialize(Struct, parser, schema)); } if (schema.IsMap) { return(GenerateSerialize(Map, parser, schema)); } if (schema.IsContainer) { return(GenerateSerialize(Container, parser, schema)); } return(parser.Scalar(valueType, schema.TypeDef.id, value => writer.Write(value, schema.TypeDef.id))); }
Expression FieldValue(IParser parser, Expression var, Expression valueType, Type schemaType, bool initialize) { Expression body; if (schemaType.IsBondStruct() && var.Type.IsValueType()) { // Special handling for properties of struct types: we deserialize into // a temp variable and then assign the value to the property. var temp = Expression.Variable(var.Type, $"{var.Type.Name}_temp"); body = Expression.Block( new[] { temp }, Value(parser, temp, valueType, schemaType, true), Expression.Assign(var, temp)); } else { body = Value(parser, var, valueType, schemaType, initialize); } if (schemaType.IsBondContainer() || schemaType.IsBondStruct() || schemaType.IsBondNullable()) { var expectedType = Expression.Constant(schemaType.GetBondDataType()); return(PrunedExpression.IfThenElse( Expression.Equal(valueType, expectedType), body, ThrowExpression.InvalidTypeException(expectedType, valueType))); } return(body); }
public static Expression While(Expression whileCondition, Expression body, LabelTarget breakLabel) { return(Expression.Loop( PrunedExpression.IfThenElse( whileCondition, body, Expression.Break(breakLabel)), breakLabel)); }
Expression Value(IParser parser, Expression valueType) { if (parser.IsBonded) { return(parser.Bonded(value => writer.WriteBonded(PrunedExpression.Convert(value, typeof(IBonded))))); } var switchCases = new List <DeferredSwitchCase> { PrunedExpression.SwitchCase( () => GenerateSerialize(Container, parser), BondDataType.BT_LIST, BondDataType.BT_SET), PrunedExpression.SwitchCase( () => GenerateSerialize(Map, parser), BondDataType.BT_MAP), PrunedExpression.SwitchCase( () => GenerateSerialize(Struct, parser), BondDataType.BT_STRUCT) }; switchCases.AddRange( from type in new[] { BondDataType.BT_BOOL, BondDataType.BT_UINT8, BondDataType.BT_UINT16, BondDataType.BT_UINT32, BondDataType.BT_UINT64, BondDataType.BT_FLOAT, BondDataType.BT_DOUBLE, BondDataType.BT_STRING, BondDataType.BT_INT8, BondDataType.BT_INT16, BondDataType.BT_INT32, BondDataType.BT_INT64, BondDataType.BT_WSTRING } select PrunedExpression.SwitchCase( () => parser.Scalar(Expression.Constant(type), type, value => writer.Write(value, type)), type)); return(PrunedExpression.Switch( valueType, ThrowExpression.InvalidTypeException(valueType), switchCases)); }
public Expression Assign(Expression left, Expression right) { var leftType = left.Type; if (leftType != right.Type && leftType.IsGenericType() && leftType.GetGenericTypeDefinition() == typeof(Nullable <>)) { leftType = leftType.GetTypeInfo().GenericTypeArguments[0]; } var value = Convert(right, leftType); return(Expression.Assign(left, PrunedExpression.Convert(value, left.Type))); }
Expression Container(IParser parser, RuntimeSchema schema) { var expectedValueType = schema.HasValue ? schema.TypeDef.element.id : (BondDataType?)null; return(parser.Container(expectedValueType, (valueParser, elementType, next, count, arraySegment) => { var body = ControlExpression.While(next, Expression.Block( writer.WriteItemBegin(), schema.HasValue ? Value(valueParser, elementType, schema.GetElementSchema()) : Value(valueParser, elementType), writer.WriteItemEnd())); var blob = parser.Blob(count); if ((blob != null) || (arraySegment != null)) { body = PrunedExpression.IfThenElse( Expression.Equal(elementType, Expression.Constant(BondDataType.BT_INT8)), writer.WriteBytes(arraySegment ?? blob), body); // For binary protocols we can write blob directly using protocols's WriteBytes // even if the container is not a blob (blob is BT_LIST of BT_INT8). if (binaryWriter) { body = PrunedExpression.IfThenElse( Expression.Equal(elementType, Expression.Constant(BondDataType.BT_UINT8)), writer.WriteBytes(arraySegment ?? blob), body); } } return Expression.Block( writer.WriteContainerBegin(count, elementType), body, writer.WriteContainerEnd()); })); }
Expression Value(IParser parser, Expression var, Expression valueType, Type schemaType, bool initialize) { if (schemaType.IsBondNullable()) { return(Nullable(parser, var, schemaType.GetValueType(), initialize)); } if (schemaType.IsBonded()) { return(parser.Bonded(value => Expression.Assign(var, newBonded(var.Type, schemaType, PrunedExpression.Convert(value, typeof(IBonded)))))); } if (schemaType.IsBondStruct()) { if (parser.IsBonded) { var deserialize = bondedDeserialize.MakeGenericMethod(schemaType); return(parser.Bonded(value => Expression.Assign(var, Expression.Call(value, deserialize)))); } return(Deserialize(parser, var, var.Type, schemaType, initialize)); } if (schemaType.IsBondMap()) { return(Map(parser, var, schemaType, initialize)); } if (schemaType.IsBondContainer()) { return(Container(parser, var, schemaType, initialize)); } return(parser.Scalar(valueType, schemaType.GetBondDataType(), value => typeAlias.Assign(var, PrunedExpression.Convert(value, schemaType)))); }