Kinetica   C#   API  Version 7.2.3.0
PreresolvingDatumWriter.cs
Go to the documentation of this file.
1 
18 using System;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Linq;
23 
24 namespace Avro.Generic
25 {
31  public abstract class PreresolvingDatumWriter<T> : DatumWriter<T>
32  {
33  public Schema Schema { get; private set; }
34 
35  protected delegate void WriteItem(Object value, Encoder encoder);
36 
37  private readonly WriteItem _writer;
38  private readonly ArrayAccess _arrayAccess;
39  private readonly MapAccess _mapAccess;
40 
41  private readonly Dictionary<RecordSchema,WriteItem> _recordWriters = new Dictionary<RecordSchema,WriteItem>();
42 
43  public void Write(T datum, Encoder encoder)
44  {
45  _writer( datum, encoder );
46  }
47 
48  protected PreresolvingDatumWriter(Schema schema, ArrayAccess arrayAccess, MapAccess mapAccess)
49  {
50  Schema = schema;
51  _arrayAccess = arrayAccess;
52  _mapAccess = mapAccess;
53  _writer = ResolveWriter(schema);
54  }
55 
56  private WriteItem ResolveWriter( Schema schema )
57  {
58  switch (schema.Tag)
59  {
60  case Schema.Type.Null:
61  return WriteNull;
62  case Schema.Type.Boolean:
63  return (v, e) => Write<bool>( v, schema.Tag, e.WriteBoolean );
64  case Schema.Type.Int:
65  return (v, e) => Write<int>( v, schema.Tag, e.WriteInt );
66  case Schema.Type.Long:
67  return (v, e) => Write<long>( v, schema.Tag, e.WriteLong );
68  case Schema.Type.Float:
69  return (v, e) => Write<float>( v, schema.Tag, e.WriteFloat );
70  case Schema.Type.Double:
71  return (v, e) => Write<double>( v, schema.Tag, e.WriteDouble );
72  case Schema.Type.String:
73  return (v, e) => Write<string>( v, schema.Tag, e.WriteString );
74  case Schema.Type.Bytes:
75  return (v, e) => Write<byte[]>( v, schema.Tag, e.WriteBytes );
76  case Schema.Type.Error:
77  case Schema.Type.Record:
78  return ResolveRecord((RecordSchema) schema);
79  case Schema.Type.Enumeration:
80  return ResolveEnum(schema as EnumSchema);
81  case Schema.Type.Fixed:
82  return (v, e) => WriteFixed(schema as FixedSchema, v, e);
83  case Schema.Type.Array:
84  return ResolveArray((ArraySchema)schema);
85  case Schema.Type.Map:
86  return ResolveMap((MapSchema)schema);
87  case Schema.Type.Union:
88  return ResolveUnion((UnionSchema)schema);
89  default:
90  return (v, e) => error(schema, v);
91  }
92  }
93 
99  protected void WriteNull(object value, Encoder encoder)
100  {
101  if (value != null) throw TypeMismatch(value, "null", "null");
102  }
103 
111  protected void Write<S>(object value, Schema.Type tag, Writer<S> writer)
112  {
113  if (!(value is S)) throw TypeMismatch(value, tag.ToString(), typeof(S).ToString());
114  writer((S)value);
115  }
116 
117 
123  private WriteItem ResolveRecord(RecordSchema recordSchema)
124  {
125  WriteItem recordResolver;
126  if (_recordWriters.TryGetValue(recordSchema, out recordResolver))
127  {
128  return recordResolver;
129  }
130  var writeSteps = new RecordFieldWriter[recordSchema.Fields.Count];
131  recordResolver = (v, e) => WriteRecordFields(v, writeSteps, e);
132 
133  _recordWriters.Add(recordSchema, recordResolver);
134 
135  int index = 0;
136  foreach (Field field in recordSchema)
137  {
138  var record = new RecordFieldWriter
139  {
140  WriteField = ResolveWriter(field.Schema),
141  Field = field
142  };
143  writeSteps[index++] = record;
144  }
145 
146  return recordResolver;
147  }
148 
149  protected abstract void WriteRecordFields(object record, RecordFieldWriter[] writers, Encoder encoder);
150 
151 
152  protected class RecordFieldWriter
153  {
154  public WriteItem WriteField { get; set; }
155  public Field Field { get; set; }
156  }
157 
158  protected abstract void EnsureRecordObject(RecordSchema recordSchema, object value);
159 
167  protected abstract void WriteField(object record, string fieldName, int fieldPos, WriteItem writer, Encoder encoder );
168 
173  protected abstract WriteItem ResolveEnum(EnumSchema es);
174 
184  {
185  var itemWriter = ResolveWriter(schema.ItemSchema);
186  return (d,e) => WriteArray(itemWriter, d, e);
187  }
188 
189  private void WriteArray(WriteItem itemWriter, object array, Encoder encoder)
190  {
191  _arrayAccess.EnsureArrayObject(array);
192  long l = _arrayAccess.GetArrayLength(array);
193  encoder.WriteArrayStart();
194  encoder.SetItemCount(l);
195  _arrayAccess.WriteArrayValues(array, itemWriter, encoder);
196  encoder.WriteArrayEnd();
197  }
198 
199  private WriteItem ResolveMap(MapSchema mapSchema)
200  {
201  var itemWriter = ResolveWriter(mapSchema.ValueSchema);
202  return (v, e) => WriteMap(itemWriter, v, e);
203  }
204 
212  protected void WriteMap(WriteItem itemWriter, object value, Encoder encoder)
213  {
214  _mapAccess.EnsureMapObject(value);
215  encoder.WriteMapStart();
216  encoder.SetItemCount(_mapAccess.GetMapSize(value));
217  _mapAccess.WriteMapValues(value, itemWriter, encoder);
218  encoder.WriteMapEnd();
219  }
220 
221 
222  private WriteItem ResolveUnion(UnionSchema unionSchema)
223  {
224  var branchSchemas = unionSchema.Schemas.ToArray();
225  var branchWriters = new WriteItem[branchSchemas.Length];
226  int branchIndex = 0;
227  foreach (var branch in branchSchemas)
228  {
229  branchWriters[branchIndex++] = ResolveWriter(branch);
230  }
231 
232 
233  return (v, e) => WriteUnion(unionSchema, branchSchemas, branchWriters, v, e);
234  }
235 
243  private void WriteUnion(UnionSchema unionSchema, Schema[] branchSchemas, WriteItem[] branchWriters, object value, Encoder encoder)
244  {
245  int index = ResolveUnion(unionSchema, branchSchemas, value);
246  encoder.WriteUnionIndex(index);
247  branchWriters[index](value, encoder);
248  }
249 
258  protected int ResolveUnion(UnionSchema us, Schema[] branchSchemas, object obj)
259  {
260  for (int i = 0; i < branchSchemas.Length; i++)
261  {
262  if (UnionBranchMatches(branchSchemas[i], obj)) return i;
263  }
264  throw new AvroException("Cannot find a match for " + obj.GetType() + " in " + us);
265  }
266 
274  protected abstract void WriteFixed(FixedSchema es, object value, Encoder encoder);
275 
276  protected static AvroException TypeMismatch(object obj, string schemaType, string type)
277  {
278  return new AvroException(type + " required to write against " + schemaType + " schema but found " + (null == obj ? "null" : obj.GetType().ToString()) );
279  }
280 
281  private void error(Schema schema, Object value)
282  {
283  throw new AvroTypeException("Not a " + schema + ": " + value);
284  }
285 
286  protected abstract bool UnionBranchMatches(Schema sc, object obj);
287 
288  protected interface EnumAccess
289  {
290  void WriteEnum(object value);
291  }
292 
293  protected interface ArrayAccess
294  {
300  void EnsureArrayObject(object value);
301 
310  long GetArrayLength(object value);
311 
321  void WriteArrayValues(object array, WriteItem valueWriter, Encoder encoder);
322  }
323 
324  protected interface MapAccess
325  {
331  void EnsureMapObject(object value);
332 
340  long GetMapSize(object value);
341 
349  void WriteMapValues(object map, WriteItem valueWriter, Encoder encoder);
350  }
351 
352  protected class DictionaryMapAccess : MapAccess
353  {
354  public void EnsureMapObject( object value )
355  {
356  if( value == null || !( value is IDictionary ) ) throw TypeMismatch( value, "map", "IDictionary" );
357  }
358 
359  public long GetMapSize( object value )
360  {
361  return ( (IDictionary) value ).Count;
362  }
363 
364  public void WriteMapValues(object map, WriteItem valueWriter, Encoder encoder)
365  {
366  foreach (DictionaryEntry entry in ((IDictionary)map))
367  {
368  encoder.StartItem();
369  encoder.WriteString(entry.Key.ToString());
370  valueWriter(entry.Value, encoder);
371  }
372  }
373  }
374  }
375 }
void WriteMapValues(object map, WriteItem valueWriter, Encoder encoder)
Returns the contents of the given map object.
Class for record schemas
Definition: RecordSchema.cs:31
abstract void WriteRecordFields(object record, RecordFieldWriter[] writers, Encoder encoder)
Schema Schema
Field type's schema
Definition: Field.cs:75
Class for fields defined in a record
Definition: Field.cs:30
void Write(T datum, Encoder encoder)
Class for enum type schemas
Definition: EnumSchema.cs:28
abstract void EnsureRecordObject(RecordSchema recordSchema, object value)
void WriteArrayValues(object array, WriteItem valueWriter, Encoder encoder)
Returns the element at the given index from the given array object.
Schema ValueSchema
Schema for map values type
Definition: MapSchema.cs:33
Base class for all schema types
Definition: Schema.cs:29
Class for union schemas
Definition: UnionSchema.cs:29
Avro.IO.Encoder Encoder
IList< Schema > Schemas
List of schemas in the union
Definition: UnionSchema.cs:34
Class for fixed schemas
Definition: FixedSchema.cs:28
long GetArrayLength(object value)
Returns the length of an array.
Type
Enum for schema types
Definition: Schema.cs:34
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
WriteItem ResolveArray(ArraySchema schema)
Serialized an array.
void EnsureMapObject(object value)
Checks if the given object is a map.
abstract WriteItem ResolveEnum(EnumSchema es)
Serializes an enumeration.
Class for array type schemas
Definition: ArraySchema.cs:27
void WriteNull(object value, Encoder encoder)
Serializes a "null"
abstract void WriteFixed(FixedSchema es, object value, Encoder encoder)
Serialized a fixed object.
void EnsureArrayObject(object value)
Checks if the given object is an array.
Class for map schemas
Definition: MapSchema.cs:28
abstract void WriteField(object record, string fieldName, int fieldPos, WriteItem writer, Encoder encoder)
Extracts the field value from the given object.
int ResolveUnion(UnionSchema us, Schema[] branchSchemas, object obj)
Finds the branch within the given UnionSchema that matches the given object.
long GetMapSize(object value)
Returns the size of the map object.
abstract bool UnionBranchMatches(Schema sc, object obj)
A general purpose writer of data from avro streams.
long GetMapSize(object value)
Returns the size of the map object.
void Write< S >(object value, Schema.Type tag, Writer< S > writer)
A generic method to serialize primitive Avro types.
Schema ItemSchema
Schema for the array 'type' attribute
Definition: ArraySchema.cs:32
PreresolvingDatumWriter(Schema schema, ArrayAccess arrayAccess, MapAccess mapAccess)
Type Tag
Schema type property
Definition: Schema.cs:56
List< Field > Fields
List of fields in the record
Definition: RecordSchema.cs:36
static AvroException TypeMismatch(object obj, string schemaType, string type)
void WriteMap(WriteItem itemWriter, object value, Encoder encoder)
Serialized a map.
delegate void WriteItem(Object value, Encoder encoder)
void WriteMapValues(object map, WriteItem valueWriter, Encoder encoder)
Returns the contents of the given map object.
void EnsureMapObject(object value)
Checks if the given object is a map.