in cs/src/core/expressions/ObjectParser.cs [97:179]
Expression Field(ITransform transform, Expression structVar, UInt16 id, ISchemaField schemaField, IField field)
{
var fieldSchemaType = schemaField.GetSchemaType();
var fieldId = Expression.Constant(id);
var fieldType = Expression.Constant(fieldSchemaType.GetBondDataType());
var fieldValue = DataExpression.PropertyOrField(structVar, schemaField.Name);
ObjectParser parser = null;
Expression blob = null;
ParameterExpression convertedBlob = null;
// To avoid calling Convert multiple times on the same aliased Blob
// we must construct a new ObjectParser with the expected return type of
// of Convert
if (fieldSchemaType.IsBondBlob())
{
blob = typeAlias.Convert(fieldValue, fieldSchemaType);
convertedBlob = Expression.Variable(blob.Type, "convertedBlob");
if (blob.Type != fieldValue.Type)
{
parser = new ObjectParser(this, convertedBlob, convertedBlob.Type);
}
}
parser = parser ?? new ObjectParser(this, fieldValue, fieldSchemaType);
var processField = field != null
? field.Value(parser, fieldType)
: transform.UnknownField(parser, fieldType, fieldId) ?? Expression.Empty();
var omitField = field != null
? field.Omitted : Expression.Empty();
Expression cannotOmit;
if (fieldSchemaType.IsBondStruct() || fieldSchemaType.IsBonded() || schemaField.GetModifier() != Modifier.Optional)
{
cannotOmit = Expression.Constant(true);
if (fieldSchemaType.IsBondBlob())
{
return Expression.Block(
new[] { convertedBlob },
Expression.Assign(convertedBlob, blob),
processField);
}
}
else if (fieldSchemaType.IsBondBlob())
{
var notEqual = Expression.NotEqual(
convertedBlob,
Expression.Default(typeof(ArraySegment<byte>)));
return Expression.Block(
new[] { convertedBlob },
Expression.Assign(convertedBlob, blob),
PrunedExpression.IfThenElse(notEqual, processField, omitField));
}
else
{
var defaultValue = schemaField.GetDefaultValue();
if (defaultValue == null)
{
cannotOmit = Expression.NotEqual(fieldValue, Expression.Constant(null));
}
else if (fieldSchemaType.IsBondContainer())
{
cannotOmit = Expression.NotEqual(ContainerCount(fieldValue), Expression.Constant(0));
}
else
{
var comparand = defaultValue.GetType() != fieldValue.Type
? (Expression)Expression.Default(fieldValue.Type)
: Expression.Constant(defaultValue);
cannotOmit = Expression.NotEqual(fieldValue, comparand);
}
}
return PrunedExpression.IfThenElse(cannotOmit, processField, omitField);
}