Kinetica   C#   API  Version 7.2.3.0
GenericWriter.cs
Go to the documentation of this file.
1 
18 using System;
19 using System.Collections.Generic;
20 using Avro.IO;
21 
22 namespace Avro.Generic
23 {
24  public delegate void Writer<T>(T t);
31  public class GenericWriter<T> : DatumWriter<T>
32  {
33  private readonly DefaultWriter writer;
34  public GenericWriter(Schema schema) : this(new DefaultWriter(schema))
35  {
36 
37  }
38 
39  public Schema Schema { get { return writer.Schema; } }
40 
42  {
43  this.writer = writer;
44  }
45 
51  public void Write(T value, Encoder encoder)
52  {
53  writer.Write(value, encoder);
54  }
55  }
56 
63  public class DefaultWriter
64  {
65  public Schema Schema { get; private set; }
66 
71  public DefaultWriter(Schema schema)
72  {
73  this.Schema = schema;
74  }
75 
76  public void Write<T>(T value, Encoder encoder)
77  {
78  Write(Schema, value, encoder);
79  }
88  public virtual void Write(Schema schema, object value, Encoder encoder)
89  {
90  switch (schema.Tag)
91  {
92  case Schema.Type.Null:
93  WriteNull(value, encoder);
94  break;
95  case Schema.Type.Boolean:
96  Write<bool>(value, schema.Tag, encoder.WriteBoolean);
97  break;
98  case Schema.Type.Int:
99  Write<int>(value, schema.Tag, encoder.WriteInt);
100  break;
101  case Schema.Type.Long:
102  Write<long>(value, schema.Tag, encoder.WriteLong);
103  break;
104  case Schema.Type.Float:
105  Write<float>(value, schema.Tag, encoder.WriteFloat);
106  break;
107  case Schema.Type.Double:
108  Write<double>(value, schema.Tag, encoder.WriteDouble);
109  break;
110  case Schema.Type.String:
111  Write<string>(value, schema.Tag, encoder.WriteString);
112  break;
113  case Schema.Type.Bytes:
114  Write<byte[]>(value, schema.Tag, encoder.WriteBytes);
115  break;
116  case Schema.Type.Record:
117  case Schema.Type.Error:
118  WriteRecord(schema as RecordSchema, value, encoder);
119  break;
120  case Schema.Type.Enumeration:
121  WriteEnum(schema as EnumSchema, value, encoder);
122  break;
123  case Schema.Type.Fixed:
124  WriteFixed(schema as FixedSchema, value, encoder);
125  break;
126  case Schema.Type.Array:
127  WriteArray(schema as ArraySchema, value, encoder);
128  break;
129  case Schema.Type.Map:
130  WriteMap(schema as MapSchema, value, encoder);
131  break;
132  case Schema.Type.Union:
133  WriteUnion(schema as UnionSchema, value, encoder);
134  break;
135  default:
136  error(schema, value);
137  break;
138  }
139  }
140 
146  protected virtual void WriteNull(object value, Encoder encoder)
147  {
148  if (value != null) throw TypeMismatch(value, "null", "null");
149  }
150 
158  protected virtual void Write<S>(object value, Schema.Type tag, Writer<S> writer)
159  {
160  if (!(value is S)) throw TypeMismatch(value, tag.ToString(), typeof(S).ToString());
161  writer((S)value);
162  }
163 
171 
172  protected virtual void WriteRecord(RecordSchema schema, object value, Encoder encoder)
173  {
174  EnsureRecordObject(schema, value);
175  foreach (Field field in schema)
176  {
177  try
178  {
179  object obj = GetField(value, field.Name, field.Pos);
180  Write(field.Schema, obj, encoder);
181  }
182  catch (Exception ex)
183  {
184  throw new AvroException(ex.Message + " in field " + field.Name);
185  }
186  }
187  }
188 
189  protected virtual void EnsureRecordObject(RecordSchema s, object value)
190  {
191  if (value == null || !(value is GenericRecord) || !((value as GenericRecord).Schema.Equals(s)))
192  {
193  throw TypeMismatch(value, "record", "GenericRecord");
194  }
195  }
196 
205  protected virtual object GetField(object value, string fieldName, int fieldPos)
206  {
207  GenericRecord d = value as GenericRecord;
208  return d[fieldName];
209  }
210 
218  protected virtual void WriteEnum(EnumSchema es, object value, Encoder encoder)
219  {
220  if (value == null || !(value is GenericEnum) || !((value as GenericEnum).Schema.Equals(es)))
221  throw TypeMismatch(value, "enum", "GenericEnum");
222  encoder.WriteEnum(es.Ordinal((value as GenericEnum).Value));
223  }
224 
233  protected virtual void WriteArray(ArraySchema schema, object value, Encoder encoder)
234  {
235  EnsureArrayObject(value);
236  long l = GetArrayLength(value);
237  encoder.WriteArrayStart();
238  encoder.SetItemCount(l);
239  for (long i = 0; i < l; i++)
240  {
241  encoder.StartItem();
242  Write(schema.ItemSchema, GetArrayElement(value, i), encoder);
243  }
244  encoder.WriteArrayEnd();
245  }
246 
252  protected virtual void EnsureArrayObject(object value)
253  {
254  if (value == null || !(value is Array)) throw TypeMismatch(value, "array", "Array");
255  }
256 
265  protected virtual long GetArrayLength(object value)
266  {
267  return (value as Array).Length;
268  }
269 
279  protected virtual object GetArrayElement(object value, long index)
280  {
281  return (value as Array).GetValue(index);
282  }
283 
291  protected virtual void WriteMap(MapSchema schema, object value, Encoder encoder)
292  {
293  EnsureMapObject(value);
294  IDictionary<string, object> vv = (IDictionary<string, object>)value;
295  encoder.WriteMapStart();
296  encoder.SetItemCount(GetMapSize(value));
297  foreach (KeyValuePair<string, object> obj in GetMapValues(vv))
298  {
299  encoder.StartItem();
300  encoder.WriteString(obj.Key);
301  Write(schema.ValueSchema, obj.Value, encoder);
302  }
303  encoder.WriteMapEnd();
304  }
305 
311  protected virtual void EnsureMapObject(object value)
312  {
313  if (value == null || !(value is IDictionary<string, object>)) throw TypeMismatch(value, "map", "IDictionary<string, object>");
314  }
315 
323  protected virtual long GetMapSize(object value)
324  {
325  return (value as IDictionary<string, object>).Count;
326  }
327 
335  protected virtual IEnumerable<KeyValuePair<string, object>> GetMapValues(object value)
336  {
337  return value as IDictionary<string, object>;
338  }
339 
348  protected virtual void WriteUnion(UnionSchema us, object value, Encoder encoder)
349  {
350  int index = ResolveUnion(us, value);
351  encoder.WriteUnionIndex(index);
352  Write(us[index], value, encoder);
353  }
354 
363  protected virtual int ResolveUnion(UnionSchema us, object obj)
364  {
365  for (int i = 0; i < us.Count; i++)
366  {
367  if (Matches(us[i], obj)) return i;
368  }
369  throw new AvroException("Cannot find a match for " + obj.GetType() + " in " + us);
370  }
371 
379  protected virtual void WriteFixed(FixedSchema es, object value, Encoder encoder)
380  {
381  if (value == null || !(value is GenericFixed) || !(value as GenericFixed).Schema.Equals(es))
382  {
383  throw TypeMismatch(value, "fixed", "GenericFixed");
384  }
385  GenericFixed ba = (GenericFixed)value;
386  encoder.WriteFixed(ba.Value);
387  }
388 
389  protected AvroException TypeMismatch(object obj, string schemaType, string type)
390  {
391  return new AvroException(type + " required to write against " + schemaType + " schema but found " + (null == obj ? "null" : obj.GetType().ToString()) );
392  }
393 
394  private void error(Schema schema, Object value)
395  {
396  throw new AvroTypeException("Not a " + schema + ": " + value);
397  }
398 
399  /*
400  * FIXME: This method of determining the Union branch has problems. If the data is IDictionary<string, object>
401  * if there are two branches one with record schema and the other with map, it choose the first one. Similarly if
402  * the data is byte[] and there are fixed and bytes schemas as branches, it choose the first one that matches.
403  * Also it does not recognize the arrays of primitive types.
404  */
405  protected virtual bool Matches(Schema sc, object obj)
406  {
407  if (obj == null && sc.Tag != Avro.Schema.Type.Null) return false;
408  switch (sc.Tag)
409  {
410  case Schema.Type.Null:
411  return obj == null;
412  case Schema.Type.Boolean:
413  return obj is bool;
414  case Schema.Type.Int:
415  return obj is int;
416  case Schema.Type.Long:
417  return obj is long;
418  case Schema.Type.Float:
419  return obj is float;
420  case Schema.Type.Double:
421  return obj is double;
422  case Schema.Type.Bytes:
423  return obj is byte[];
424  case Schema.Type.String:
425  return obj is string;
426  case Schema.Type.Record:
427  //return obj is GenericRecord && (obj as GenericRecord).Schema.Equals(s);
428  return obj is GenericRecord && (obj as GenericRecord).Schema.SchemaName.Equals((sc as RecordSchema).SchemaName);
429  case Schema.Type.Enumeration:
430  //return obj is GenericEnum && (obj as GenericEnum).Schema.Equals(s);
431  return obj is GenericEnum && (obj as GenericEnum).Schema.SchemaName.Equals((sc as EnumSchema).SchemaName);
432  case Schema.Type.Array:
433  return obj is Array && !(obj is byte[]);
434  case Schema.Type.Map:
435  return obj is IDictionary<string, object>;
436  case Schema.Type.Union:
437  return false; // Union directly within another union not allowed!
438  case Schema.Type.Fixed:
439  //return obj is GenericFixed && (obj as GenericFixed).Schema.Equals(s);
440  return obj is GenericFixed && (obj as GenericFixed).Schema.SchemaName.Equals((sc as FixedSchema).SchemaName);
441  default:
442  throw new AvroException("Unknown schema type: " + sc.Tag);
443  }
444  }
445  }
446 }
virtual void EnsureArrayObject(object value)
Checks if the given object is an array.
Class for record schemas
Definition: RecordSchema.cs:31
virtual void WriteNull(object value, Encoder encoder)
Serializes a "null"
virtual void Write< S >(object value, Schema.Type tag, Writer< S > writer)
A generic method to serialize primitive Avro types.
Schema Schema
Field type's schema
Definition: Field.cs:75
Class for fields defined in a record
Definition: Field.cs:30
The defualt class to hold values for enum schema in GenericReader and GenericWriter.
Definition: GenericEnum.cs:27
void WriteBytes(byte[] value)
virtual void WriteUnion(UnionSchema us, object value, Encoder encoder)
Resolves the given value against the given UnionSchema and serializes the object against the resolved...
Class for enum type schemas
Definition: EnumSchema.cs:28
void WriteInt(int value)
void WriteArrayStart()
void WriteDouble(double value)
int Pos
Position of the field within its record.
Definition: Field.cs:55
Base class for all schema types
Definition: Schema.cs:29
void WriteMapStart()
virtual object GetArrayElement(object value, long index)
Returns the element at the given index from the given array object.
virtual IEnumerable< KeyValuePair< string, object > > GetMapValues(object value)
Returns the contents of the given map object.
void SetItemCount(long value)
Class for union schemas
Definition: UnionSchema.cs:29
void WriteLong(long value)
readonly string Name
Name of the field.
Definition: Field.cs:45
virtual void EnsureMapObject(object value)
Checks if the given object is a map.
void WriteArrayEnd()
virtual long GetMapSize(object value)
Returns the size of the map object.
Class for fixed schemas
Definition: FixedSchema.cs:28
A General purpose writer for serializing objects into a Stream using Avro.
virtual void WriteEnum(EnumSchema es, object value, Encoder encoder)
Serializes an enumeration.
Type
Enum for schema types
Definition: Schema.cs:34
virtual object GetField(object value, string fieldName, int fieldPos)
Extracts the field value from the given object.
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
int Ordinal(string symbol)
Returns the position of the given symbol within this enum.
Definition: EnumSchema.cs:116
The default type used by GenericReader and GenericWriter for RecordSchema.
AvroException TypeMismatch(object obj, string schemaType, string type)
virtual void WriteFixed(FixedSchema es, object value, Encoder encoder)
Serialized a fixed object.
virtual void Write(Schema schema, object value, Encoder encoder)
Examines the schema and dispatches the actual work to one of the other methods of this class.
void WriteBoolean(bool value)
void WriteEnum(int value)
void WriteFixed(byte[] data)
virtual void WriteRecord(RecordSchema schema, object value, Encoder encoder)
Serialized a record using the given RecordSchema.
void WriteFloat(float value)
DefaultWriter(Schema schema)
Constructs a generic writer for the given schema.
Class for array type schemas
Definition: ArraySchema.cs:27
virtual void WriteArray(ArraySchema schema, object value, Encoder encoder)
Serialized an array.
Class for map schemas
Definition: MapSchema.cs:28
virtual void EnsureRecordObject(RecordSchema s, object value)
void Write< T >(T value, Encoder encoder)
Schema(Type type, PropertyMap props)
Constructor for schema class
Definition: Schema.cs:67
A typesafe wrapper around DefaultWriter.
void WriteUnionIndex(int value)
virtual bool Matches(Schema sc, object obj)
delegate void Writer< T >(T t)
void Write(T value, Encoder encoder)
Serializes the given object using this writer's schema.
virtual int ResolveUnion(UnionSchema us, object obj)
Finds the branch within the given UnionSchema that matches the given object.
int Count
Count of schemas in the union
Definition: UnionSchema.cs:39
GenericWriter(DefaultWriter writer)
void WriteString(string value)
Schema ItemSchema
Schema for the array 'type' attribute
Definition: ArraySchema.cs:32
virtual long GetArrayLength(object value)
Returns the length of an array.
Type Tag
Schema type property
Definition: Schema.cs:56
GenericWriter(Schema schema)
The default type used by GenericReader and GenericWriter for objects for FixedSchema
Definition: GenericFixed.cs:28
virtual void WriteMap(MapSchema schema, object value, Encoder encoder)
Serialized a map.