in cs/src/core/expressions/TaggedParser.cs [61:131]
public Expression Apply(ITransform transform)
{
var fieldId = Expression.Variable(typeof(UInt16), "fieldId");
var fieldType = Expression.Variable(typeof(BondDataType), "fieldType");
var endLabel = Expression.Label("end");
var breakLoop = Expression.Break(endLabel);
// (int)fieldType > (int)BT_STOP_BASE
var notEndOrEndBase = Expression.GreaterThan(
Expression.Convert(fieldType, typeof(int)),
Expression.Constant((int)BondDataType.BT_STOP_BASE));
var notEnd = isBase ? notEndOrEndBase : Expression.NotEqual(fieldType, Expression.Constant(BondDataType.BT_STOP));
var isEndBase = Expression.Equal(fieldType, Expression.Constant(BondDataType.BT_STOP_BASE));
var body = new List<Expression>
{
isBase ? reader.ReadBaseBegin() : reader.ReadStructBegin(),
transform.Begin,
transform.Base(baseParser),
reader.ReadFieldBegin(fieldType, fieldId)
};
// known fields
body.AddRange(
from f in transform.Fields select
Expression.Loop(
Expression.IfThenElse(notEndOrEndBase,
Expression.Block(
Expression.IfThenElse(
Expression.Equal(fieldId, Expression.Constant(f.Id)),
Expression.Block(
f.Value(fieldParser, fieldType),
reader.ReadFieldEnd(),
reader.ReadFieldBegin(fieldType, fieldId),
breakLoop),
Expression.IfThenElse(
Expression.GreaterThan(fieldId, Expression.Constant(f.Id)),
Expression.Block(
f.Omitted,
breakLoop),
transform.UnknownField(fieldParser, fieldType, fieldId) ?? Skip(fieldType))),
reader.ReadFieldEnd(),
reader.ReadFieldBegin(fieldType, fieldId),
Expression.IfThen(
Expression.GreaterThan(fieldId, Expression.Constant(f.Id)),
breakLoop)),
Expression.Block(
f.Omitted,
breakLoop)),
endLabel));
// unknown fields
body.Add(
ControlExpression.While(notEnd,
Expression.Block(
Expression.IfThenElse(
isEndBase,
transform.UnknownEnd,
Expression.Block(
transform.UnknownField(fieldParser, fieldType, fieldId) ?? Skip(fieldType),
reader.ReadFieldEnd())),
reader.ReadFieldBegin(fieldType, fieldId))));
body.Add(isBase ? reader.ReadBaseEnd() : reader.ReadStructEnd());
body.Add(transform.End);
return Expression.Block(
new[] { fieldType, fieldId },
body);
}