protected virtual object ResolveRecord(RecordSchema writerSchema, RecordSchema readerSchema, IReader dec, Type type) { object result = FormatterServices.GetUninitializedObject(type); foreach (Field wf in writerSchema) { if (readerSchema.Contains(wf.Name)) { Field rf = readerSchema.GetField(wf.Name); string name = rf.aliases?[0] ?? wf.Name; PropertyInfo propertyInfo = type.GetProperty(name); if (propertyInfo != null) { object value = Resolve(wf.Schema, rf.Schema, dec, propertyInfo.PropertyType) ?? wf.DefaultValue?.ToObject(typeof(object)); propertyInfo.SetValue(result, value, null); } FieldInfo fieldInfo = type.GetField(name); if (fieldInfo != null) { object value = Resolve(wf.Schema, rf.Schema, dec, fieldInfo.FieldType) ?? wf.DefaultValue?.ToObject(typeof(object)); fieldInfo.SetValue(result, value); } } else { _skipper.Skip(wf.Schema, dec); } } return(result); }
protected virtual object ResolveRecord(RecordSchema writerSchema, RecordSchema readerSchema, IReader dec, Type type) { object result = FormatterServices.GetUninitializedObject(type); var typeHash = type.GetHashCode(); var typeMembers = new Dictionary <string, MemberInfo>(StringComparer.InvariantCultureIgnoreCase); if (!cachedRecordMembers.ContainsKey(typeHash)) { foreach (var propertyInfo in type.GetProperties()) { typeMembers.Add(propertyInfo.Name, propertyInfo); } foreach (var fieldInfo in type.GetFields()) { typeMembers.Add(fieldInfo.Name, fieldInfo); } cachedRecordMembers.Add(typeHash, typeMembers); } else { typeMembers = cachedRecordMembers[typeHash]; } foreach (Field wf in writerSchema) { if (readerSchema.Contains(wf.Name)) { Field rf = readerSchema.GetField(wf.Name); string name = rf.aliases?[0] ?? wf.Name; var memberInfo = typeMembers[name]; object value; switch (memberInfo) { case FieldInfo fieldInfo: value = Resolve(wf.Schema, rf.Schema, dec, fieldInfo.FieldType) ?? wf.DefaultValue?.ToObject(typeof(object)); fieldInfo.SetValue(result, value); break; case PropertyInfo propertyInfo: value = Resolve(wf.Schema, rf.Schema, dec, propertyInfo.PropertyType) ?? wf.DefaultValue?.ToObject(typeof(object)); propertyInfo.SetValue(result, value, null); break; } } else { _skipper.Skip(wf.Schema, dec); } } return(result); }
/// <summary> /// Deserializes a record from the stream. /// </summary> /// <param name="reuse">If not null, a record object that could be reused for returning the result</param> /// <param name="writerSchema">The writer's RecordSchema</param> /// <param name="readerSchema">The reader's schema, must be RecordSchema too.</param> /// <param name="dec">The decoder for deserialization</param> /// <returns>The record object just read</returns> protected override object ReadRecord(object reuse, RecordSchema writerSchema, Schema readerSchema, Decoder dec) { RecordSchema rs = (RecordSchema)readerSchema; if (rs.Name == null) { return(base.ReadRecord(reuse, writerSchema, readerSchema, dec)); } ISpecificRecord rec = (reuse != null ? reuse : ObjectCreator.Instance.New(rs.Fullname, Schema.Type.Record)) as ISpecificRecord; object obj; foreach (Field wf in writerSchema) { try { Field rf; if (rs.TryGetField(wf.Name, out rf)) { obj = rec.Get(rf.Pos); rec.Put(rf.Pos, Read(obj, wf.Schema, rf.Schema, dec)); } else { Skip(wf.Schema, dec); } } catch (Exception ex) { throw new AvroException(ex.Message + " in field " + wf.Name, ex); } } var defaultStream = new MemoryStream(); var defaultEncoder = new BinaryEncoder(defaultStream); var defaultDecoder = new BinaryDecoder(defaultStream); foreach (Field rf in rs) { if (writerSchema.Contains(rf.Name)) { continue; } defaultStream.Position = 0; // reset for writing Resolver.EncodeDefaultValue(defaultEncoder, rf.Schema, rf.DefaultValue); defaultStream.Flush(); defaultStream.Position = 0; // reset for reading obj = rec.Get(rf.Pos); rec.Put(rf.Pos, Read(obj, rf.Schema, rf.Schema, defaultDecoder)); } return(rec); }
protected virtual IDictionary <string, object> ReadRecord(RecordSchema writerSchema, Schema readerSchema, IDecoder dec) { RecordSchema rs = (RecordSchema)readerSchema; GenericRecord result = CreateRecord(rs); foreach (Field wf in writerSchema) { try { Field rf; if (rs.TryGetFieldAlias(wf.Name, out rf)) { object obj = null; TryGetField(result, wf.Name, rf.Pos, out obj); AddField(result, wf.Name, rf.Pos, Read(wf.Schema, rf.Schema, dec)); } else { Skip(wf.Schema, dec); } } catch (Exception ex) { throw new AvroException(ex.Message + " in field " + wf.Name); } } var defaultStream = new MemoryStream(); var defaultEncoder = new BinaryEncoder(defaultStream); var defaultDecoder = new BinaryDecoder(defaultStream); foreach (Field rf in rs) { if (writerSchema.Contains(rf.Name)) { continue; } defaultStream.Position = 0; // reset for writing Resolver.EncodeDefaultValue(defaultEncoder, rf.Schema, rf.DefaultValue); defaultStream.Flush(); defaultStream.Position = 0; // reset for reading object obj = null; TryGetField(result, rf.Name, rf.Pos, out obj); AddField(result, rf.Name, rf.Pos, Read(rf.Schema, rf.Schema, defaultDecoder)); } return(result.contents); }
protected virtual IDictionary <string, object> ResolveRecord(RecordSchema writerSchema, RecordSchema readerSchema, IReader dec) { Record result = new Record(readerSchema); foreach (Field wf in writerSchema) { if (readerSchema.Contains(wf.Name)) { Field rf = readerSchema.GetField(wf.Name); object value = Resolve(wf.Schema, rf.Schema, dec) ?? wf.DefaultValue?.ToObject(typeof(object)); AddField(result, rf.aliases?[0] ?? wf.Name, rf.Pos, value); } else { _skipper.Skip(wf.Schema, dec); } } return(result.Contents); }
private ReadItem ResolveRecord(RecordSchema writerSchema, RecordSchema readerSchema) { var schemaPair = new SchemaPair(writerSchema, readerSchema); ReadItem recordReader; if (_recordReaders.TryGetValue(schemaPair, out recordReader)) { return(recordReader); } FieldReader[] fieldReaderArray = null; var recordAccess = GetRecordAccess(readerSchema); recordReader = (r, d) => ReadRecord(r, d, recordAccess, fieldReaderArray); _recordReaders.Add(schemaPair, recordReader); var readSteps = new List <FieldReader>(); foreach (Field wf in writerSchema) { Field rf; if (readerSchema.TryGetFieldAlias(wf.Name, out rf)) { var readItem = ResolveReader(wf.Schema, rf.Schema); if (IsReusable(rf.Schema.Tag)) { readSteps.Add((rec, d) => recordAccess.AddField(rec, rf.Name, rf.Pos, readItem(recordAccess.GetField(rec, rf.Name, rf.Pos), d))); } else { readSteps.Add((rec, d) => recordAccess.AddField(rec, rf.Name, rf.Pos, readItem(null, d))); } } else { var skip = GetSkip(wf.Schema); readSteps.Add((rec, d) => skip(d)); } } // fill in defaults for any reader fields not in the writer schema foreach (Field rf in readerSchema) { if (writerSchema.Contains(rf.Name)) { continue; } var defaultStream = new MemoryStream(); var defaultEncoder = new BinaryEncoder(defaultStream); defaultStream.Position = 0; // reset for writing Resolver.EncodeDefaultValue(defaultEncoder, rf.Schema, rf.DefaultValue); defaultStream.Flush(); var defaultBytes = defaultStream.ToArray(); var readItem = ResolveReader(rf.Schema, rf.Schema); var rfInstance = rf; if (IsReusable(rf.Schema.Tag)) { readSteps.Add((rec, d) => recordAccess.AddField(rec, rfInstance.Name, rfInstance.Pos, readItem(recordAccess.GetField(rec, rfInstance.Name, rfInstance.Pos), new BinaryDecoder(new MemoryStream(defaultBytes))))); } else { readSteps.Add((rec, d) => recordAccess.AddField(rec, rfInstance.Name, rfInstance.Pos, readItem(null, new BinaryDecoder(new MemoryStream(defaultBytes))))); } } fieldReaderArray = readSteps.ToArray(); return(recordReader); }