public Expression Container(BondDataType?expectedType, ContainerHandler handler) { Debug.Assert(schema.IsContainer); var count = Expression.Variable(typeof(int), "count"); var loop = handler( new UntaggedParser <R>(this, schema.GetElementSchema()), Expression.Constant(schema.TypeDef.element.id), Expression.GreaterThan(Expression.PostDecrementAssign(count), Expression.Constant(0)), count); return(Expression.Block( new[] { count }, Expression.Assign(count, reader.ReadContainerBegin()), loop, reader.ReadContainerEnd())); }
Expression Map(IParser parser, RuntimeSchema schema) { var expectedValueType = schema.HasValue ? schema.TypeDef.element.id : (BondDataType?)null; var expectedKeyType = schema.HasValue ? schema.TypeDef.key.id : (BondDataType?)null; return(parser.Map(expectedKeyType, expectedValueType, (keyParser, valueParser, keyType, valueType, nextKey, nextValue, count) => Expression.Block( writer.WriteContainerBegin(count, keyType, valueType), ControlExpression.While(nextKey, Expression.Block( writer.WriteItemBegin(), schema.HasValue ? Value(keyParser, keyType, schema.GetKeySchema()) : Value(keyParser, keyType), writer.WriteItemEnd(), nextValue, writer.WriteItemBegin(), schema.HasValue ? Value(valueParser, valueType, schema.GetElementSchema()) : Value(valueParser, valueType), writer.WriteItemEnd())), writer.WriteContainerEnd()))); }
Expression Container(IParser parser, RuntimeSchema schema) { var expectedValueType = schema.HasValue ? schema.TypeDef.element.id : (BondDataType?)null; return(parser.Container(expectedValueType, (valueParser, elementType, next, count) => { 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) { body = PrunedExpression.IfThenElse( Expression.Equal(elementType, Expression.Constant(BondDataType.BT_INT8)), writer.WriteBytes(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(blob), body); } } return Expression.Block( writer.WriteContainerBegin(count, elementType), body, writer.WriteContainerEnd()); })); }