private object DeserializeVector(int structBase, int offset, FieldTypeDefinition field) { var typeModel = field.TypeModel; object result = null; var vectorStart = GetVectorStart(structBase, offset); if (_offsetToObject.TryGetValue(vectorStart, out result)) { return(result); } var vectorLength = GetVectorLength(structBase, offset); if (typeModel.Type.BaseType == typeof(Array)) { result = DeserializeArray(typeModel, vectorLength, vectorStart); } else if (typeModel.Type.IsGenericType && typeof(IList).IsAssignableFrom(typeModel.Type)) { result = DeserializeList(typeModel, vectorLength, vectorStart); } _offsetToObject.Add(vectorStart, result); return(result); }
private void SerializeFieldValue(object obj, StructTypeDefinition structDef, FieldTypeDefinition field) { if (structDef.IsFixed) { SerializeInlineValue(obj, field.TypeModel); } else { SerializePropertyValue(obj, field); } }
private string BuildMetadata(FieldTypeDefinition field) { var sb = new StringBuilder(); if (field.DefaultValueProvider.IsDefaultValueSetExplicity) { sb.AppendFormat(" = {0}", field.DefaultValueProvider.GetDefaultValue(field.TypeModel.Type)); } BuildMetadata(sb, field); return(sb.ToString()); }
private void AddReferenceFieldOffset(object obj, FieldTypeDefinition field) { var fieldBufferOffset = 0; var dict = field.HasNestedFlatBufferType ? _nestedOffsets : _objectOffsets; if (!dict.TryGetValue(obj, out fieldBufferOffset)) { throw new FlatBuffersSerializationException("Offset for object not found in map"); } _builder.AddOffset(field.Index, fieldBufferOffset, 0); }
private object DeserializeInlineValue(int structBase, FieldTypeDefinition field) { var typeModel = field.TypeModel; var offset = structBase + field.Offset; if (typeModel.BaseType.IsScalar()) { return(DeserializeScalarValue(typeModel.BaseType, offset)); } if (typeModel.BaseType == BaseType.Struct) { return(DeserializeStruct(offset, 0, typeModel)); } throw new NotImplementedException(); }
private void WriteField(FieldTypeDefinition field) { var fieldTypeName = GetFlatBufferTypeName(field.TypeModel); if (field.HasNestedFlatBufferType) { fieldTypeName = "[ubyte]"; } var meta = BuildMetadata(field); WriteAllComments(field, false); var fieldName = ApplyNameStyle(_options.FieldNamingStyle, field.Name); _writer.WriteLine("{0}{1}:{2}{3};", _indent, fieldName, fieldTypeName, meta); }
private object DeserializeUnion(int structBase, int offset, FieldTypeDefinition field) { var unionDef = field.TypeModel.UnionDef; var unionTypeOffset = GetFieldOffset(structBase, field.UnionTypeField.Offset); if (unionTypeOffset == 0) { return(null); } // Get the value of the union type var unionType = _buffer.Get(unionTypeOffset + structBase); var typeToDeserialize = unionDef.Fields.FirstOrDefault(i => i.Index == unionType); if (typeToDeserialize == null || typeToDeserialize.MemberType == null) { return(null); } return(DeserializeStruct(structBase, offset, typeToDeserialize.MemberType)); }
/// <summary> /// Adds a field to the struct, recalculating the valious sizing, alignment and padding values. /// </summary> /// <param name="field"></param> /// <exception cref="FlatBuffersStructFieldReflectionException"></exception> public void AddField(FieldTypeDefinition field) { field.OriginalIndex = _fields.Count; var typeModel = field.TypeModel; if (IsFixed) { var size = typeModel.InlineSize; var alignment = typeModel.InlineAlignment; if (typeModel.IsStruct) { // We're adding an inline struct var structDef = typeModel.StructDef; size = structDef.ByteSize; } // align MinAlign = Math.Max(MinAlign, alignment); PadLastField(alignment); field.Offset = ByteSize; ByteSize += size; } else { field.Offset = FieldIndexToOffset(field.Index); } if (field.Key && HasKey) { throw new FlatBuffersStructFieldReflectionException("Cannot add '{0}' as a key field, key already exists", field.Name); } if (field.Key) { HasKey = true; } _fields.Add(field); }
private object DeserializeReferenceType(int structBase, int offset, FieldTypeDefinition field) { var typeModel = field.TypeModel; if (field.HasNestedFlatBufferType) { var nestedStart = GetVectorStart(structBase, offset); return(DeserializeStruct(nestedStart, 0, field.NestedFlatBufferType)); } switch (typeModel.BaseType) { case BaseType.Vector: { return(DeserializeVector(structBase, offset, field)); } case BaseType.Struct: { return(DeserializeStruct(structBase, offset, typeModel)); } case BaseType.String: { return(DeserializeString(structBase, offset)); } case BaseType.Union: { return(DeserializeUnion(structBase, offset, field)); } default: { throw new ArgumentException("Field is not a reference type"); } } }
private void DeserializeStructField(object obj, StructTypeDefinition structDef, FieldTypeDefinition field, int structBase) { if (field.Deprecated) { return; } object value = null; if (structDef.IsFixed) { value = DeserializeInlineValue(structBase, field); } else { value = DeserializePropertyValue(structBase, field); } field.ValueProvider.SetValue(obj, value); }
private object DeserializePropertyValue(int structBase, FieldTypeDefinition field) { var typeModel = field.TypeModel; var offset = GetFieldOffset(structBase, field.Offset); if (offset == 0) { // Nothing in buffer, use default value return(field.DefaultValueProvider.GetDefaultValue(field.TypeModel.Type)); } switch (typeModel.BaseType) { case BaseType.Bool: { return(_buffer.Get(offset + structBase) == 1); } case BaseType.Char: { return(_buffer.GetSbyte(offset + structBase)); } case BaseType.UType: case BaseType.UChar: { return(_buffer.Get(offset + structBase)); } case BaseType.Short: { return(_buffer.GetShort(offset + structBase)); } case BaseType.UShort: { return(_buffer.GetUshort(offset + structBase)); } case BaseType.Int: { return(_buffer.GetInt(offset + structBase)); } case BaseType.UInt: { return(_buffer.GetUint(offset + structBase)); } case BaseType.Long: { return(_buffer.GetLong(offset + structBase)); } case BaseType.ULong: { return(_buffer.GetUlong(offset + structBase)); } case BaseType.Float: { return(_buffer.GetFloat(offset + structBase)); } case BaseType.Double: { return(_buffer.GetDouble(offset + structBase)); } case BaseType.String: case BaseType.Struct: case BaseType.Vector: case BaseType.Union: { return(DeserializeReferenceType(structBase, offset, field)); } default: { throw new InvalidOperationException(); } } }
private void SerializeStructField(object obj, StructTypeDefinition structDef, FieldTypeDefinition field) { if (field.Deprecated) { return; } if (field.Padding > 0) { _builder.Pad(field.Padding); } var val = field.ValueProvider.GetValue(obj); SerializeFieldValue(val, structDef, field); }
private int SerializePropertyValue(object obj, FieldTypeDefinition field) { var typeModel = field.TypeModel; if (typeModel.IsReferenceType && obj == null) { if (field.Required) { throw new FlatBuffersSerializationException("Required field '{0}' is not set", field.Name); } } if (field.DefaultValueProvider.IsDefaultValue(obj)) { return(_builder.Offset); } switch (typeModel.BaseType) { case BaseType.Bool: { _builder.AddBool(field.Index, (bool)obj, false); break; } case BaseType.Char: { _builder.AddSbyte(field.Index, (sbyte)obj, 0); break; } case BaseType.UType: case BaseType.UChar: { _builder.AddByte(field.Index, (byte)obj, 0); break; } case BaseType.Short: { _builder.AddShort(field.Index, (short)obj, 0); break; } case BaseType.UShort: { _builder.AddUshort(field.Index, (ushort)obj, 0); break; } case BaseType.Int: { _builder.AddInt(field.Index, (int)obj, 0); break; } case BaseType.UInt: { _builder.AddUint(field.Index, (uint)obj, 0); break; } case BaseType.Long: { _builder.AddLong(field.Index, (long)obj, 0); break; } case BaseType.ULong: { _builder.AddUlong(field.Index, (ulong)obj, 0); break; } case BaseType.Float: { _builder.AddFloat(field.Index, (float)obj, 0); break; } case BaseType.Double: { _builder.AddDouble(field.Index, (double)obj, 0); break; } case BaseType.Struct: { if (typeModel.IsStruct) { // Structs are serialized inline var structOffset = SerializeStruct(obj, typeModel); _builder.AddStruct(field.Index, structOffset, 0); } else { // Is a table, so grab the offset AddReferenceFieldOffset(obj, field); } break; } case BaseType.String: case BaseType.Vector: case BaseType.Union: { AddReferenceFieldOffset(obj, field); break; } default: { throw new InvalidOperationException(); } } return(_builder.Offset); }
private void ReflectStructFieldDef(StructTypeDefinition structDef, MemberInfo member) { var valueProvider = CreateValueProvider(member); var defaultValueProvider = CreateDefaultValueProvider(member); var attr = member.Attribute <FlatBuffersFieldAttribute>(); var valueType = valueProvider.ValueType; TypeModel memberTypeModel = null; TypeModel nestedTypeModel = null; if (valueType == typeof(object)) { if (attr == null || (!attr.IsUnionField && !attr.HasNestedFlatBufferType)) { throw new FlatBuffersStructFieldReflectionException("Field with 'object' member must have a UnionType or NestedFlatBufferType declared"); } if (attr.HasNestedFlatBufferType) { memberTypeModel = nestedTypeModel = GetTypeModel(attr.NestedFlatBufferType); } if (attr.IsUnionField) { memberTypeModel = GetTypeModel(attr.UnionType); } } else { if (attr != null && attr.HasNestedFlatBufferType) { throw new FlatBuffersStructFieldReflectionException("HasNestedFlatBufferType can only be used on fields with 'object' member"); } memberTypeModel = GetTypeModel(valueType); } FieldTypeDefinition unionTypeField = null; if (memberTypeModel.IsUnion) { var unionTypeFieldValueProvider = new UnionTypeValueProvider(valueProvider, memberTypeModel); var unionTypeFieldDefaultValueProvider = TypeDefaultValueProvider.Instance; unionTypeField = new FieldTypeDefinition(unionTypeFieldValueProvider, unionTypeFieldDefaultValueProvider) { Name = string.Format("{0}_type", member.Name), TypeModel = GetTypeModel <UnionFieldType>() }; } var field = new FieldTypeDefinition(valueProvider, defaultValueProvider) { Name = member.Name, // TODO: allow attribute override TypeModel = memberTypeModel, }; if (nestedTypeModel != null) { field.NestedFlatBufferType = nestedTypeModel; } ReflectUserMetadata(member, field); if (attr != null) { if (!string.IsNullOrEmpty(attr.Name)) { field.Name = attr.Name; } if (attr.IsIdSetExplicitly) { field.UserIndex = attr.Id; if (unionTypeField != null) { unionTypeField.UserIndex = attr.Id - 1; } } field.Required = attr.Required; field.Deprecated = attr.Deprecated; if (attr.Key) { if (!ValidKeyType(valueType)) { throw new FlatBuffersStructFieldReflectionException("Cannot add '{0}' as a key field. Type must be string or scalar", member.Name); } field.Key = attr.Key; } if (attr.Hash != FlatBuffersHash.None) { if (!ValidHashType(valueType)) { throw new FlatBuffersStructFieldReflectionException("Cannot use Hash setting on '{0}'. Type must be int/uint/long/ulong", member.Name); } field.Hash = attr.Hash; } } if (unionTypeField != null) { structDef.AddField(unionTypeField); field.UnionTypeField = unionTypeField; } structDef.AddField(field); }