Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }