private FieldDef AddFieldCreate(string name, FlatBuffersType type) { var fieldOffset = FieldIndexToOffset((ushort)Fields.Count); var fieldDef = new FieldDef { Name = name, Value = new Value { offset = fieldOffset, type = type }, TypeBuilder = TypeBuilder, }; if (Fixed) { var size = fieldDef.Value.type.InlineSize; var alignment = fieldDef.Value.type.InlineAlignment; // structs_ need to have a predictable format, so we need to align to // the largest scalar MinAlign = Math.Max(MinAlign, alignment); if (Fields.Count > 0) { PadLastField(alignment); } fieldDef.Value.offset = (ushort)ByteSize; ByteSize += size; } if (Fields.Add(fieldDef.Name, fieldDef)) { throw new Exception("field already exists!"); } return(fieldDef); }
public int ParseEnumDecl(int offset, string schemaStr, bool isUnion) { offset = SkipWhitespace(offset, schemaStr); string name; offset = ParseIdentifier(offset, schemaStr, out name); var underlyingType = isUnion ? BaseType.UType : BaseType.Int; // by default offset = SkipWhitespace(offset, schemaStr); if (!isUnion && schemaStr[offset] == ':') { offset++; offset = SkipWhitespace(offset, schemaStr); var tempType = new FlatBuffersType { BaseType = BaseType.None }; offset = ParseTypeIdentifier(offset, schemaStr, tempType); underlyingType = tempType.BaseType; } if (!underlyingType.IsScalar()) { throw new Exception("Enum must be a scalar type"); } var enumDef = TypeBuilder.AddEnum(name, underlyingType); if (isUnion) { enumDef.UnderlyingType.EnumDef = enumDef; } //TODO metadata, again, but as "attributes" on the enumDef offset = SkipWhitespace(offset, schemaStr); offset = Consume("{", offset, schemaStr); offset = ParseEnumValDeclStar(offset, schemaStr, enumDef, isUnion); return(offset); }
public int ParseVectorType(int offset, string schemaStr, out FlatBuffersType type) { type = new FlatBuffersType(); type.BaseType = BaseType.Vector; offset = SkipWhitespace(offset, schemaStr); offset = Consume("[", offset, schemaStr); offset = ParseTypeIdentifier(offset, schemaStr, type); offset = SkipWhitespace(offset, schemaStr); offset = Consume("]", offset, schemaStr); return(offset); }
public int ParseType(int offset, string schemaStr, out FlatBuffersType type) { type = new FlatBuffersType(); offset = SkipWhitespace(offset, schemaStr); if (schemaStr[offset] == '[') { return(ParseVectorType(offset, schemaStr, out type)); } else { type.BaseType = BaseType.None; offset = ParseTypeIdentifier(offset, schemaStr, type); } return(offset); }
public FieldDef AddField(string name, FlatBuffersType type, string defaultValue = null, SymbolTable <Value> attributes = null) { if (Fixed && !type.BaseType.IsScalar() && !type.IsStruct) { throw new Exception("structs may contain only scalar or struct fields"); } FieldDef typeField = null; if (type.BaseType == BaseType.Union) { // For union fields, add a second auto-generated field to hold the type typeField = AddField(name + "_type", type.EnumDef.UnderlyingType); } var field = AddFieldCreate(name, type); field.Attributes = attributes ?? field.Attributes; if (defaultValue != null) { if (!type.BaseType.IsScalar()) { throw new Exception("default values currently only suppoerted for scalars"); } field.Value.constant = defaultValue; } if (type.EnumDef != null && type.BaseType.IsScalar() && !Fixed && !type.EnumDef.BitFlags && field.Value.constant != null && type.EnumDef.ReverseLookup(Int32.Parse(field.Value.constant)) != null) { throw new Exception("enum " + type.EnumDef.Name + " does not have a declaration for this field's default of " + field.Value.constant); } field.Deprecated = field.Attributes.Lookup("deprecated") != null; if (field.Deprecated && (Fixed || field.Value.type.BaseType.IsScalar())) { throw new Exception("can't deprecate fields in a struct"); } var nested = field.Attributes.Lookup("nested_flatbuffer"); if (nested != null) { if (nested.type.BaseType != BaseType.String) { throw new Exception("nested_flatbuffer attribute must be a string (the root type)"); } if (field.Value.type.BaseType != BaseType.Vector || field.Value.type.ElementType != BaseType.UByte) { throw new Exception("nested_flatbuffer attribute may only apply to a vector of ubyte"); } TypeBuilder.LookupOrCreateStruct(nested.constant); } // If this field is a union, and it has a manually assigned id, the automatically added type field should have an id as well (of N - 1). if (typeField != null) { var attr = field.Id; if (attr != null) { var id = int.Parse(attr.constant); var value = new Value(); value.type = field.Id.type; value.constant = (id - 1).ToString(); typeField.Attributes.Add("id", value); } } return(field); }
public int ParseTypeIdentifier(int offset, string schemaStr, FlatBuffersType type) { offset = SkipWhitespace(offset, schemaStr); string identifier; offset = ParseIdentifier(offset, schemaStr, out identifier); var baseType = BaseType.None; if (identifier == "bool") { baseType = BaseType.Bool; } else if (identifier == "byte") { baseType = BaseType.Byte; } else if (identifier == "ubyte") { baseType = BaseType.UByte; } else if (identifier == "short") { baseType = BaseType.Short; } else if (identifier == "ushort") { baseType = BaseType.UShort; } else if (identifier == "int") { baseType = BaseType.Int; } else if (identifier == "uint") { baseType = BaseType.UInt; } else if (identifier == "long") { baseType = BaseType.Long; } else if (identifier == "ulong") { baseType = BaseType.ULong; } else if (identifier == "float") { baseType = BaseType.Float; } else if (identifier == "double") { baseType = BaseType.Double; } else if (identifier == "string") { baseType = BaseType.String; } Definition def = null; if (baseType == BaseType.None) { // must be a type defined earlier! def = TypeBuilder.Enums.Lookup(identifier); if (def == null) { def = TypeBuilder.LookupOrCreateStruct(identifier); } } if (type.BaseType == BaseType.Vector) { if (def != null && def is EnumDef) { var enumDef = def as EnumDef; type.ElementType = enumDef.UnderlyingType.BaseType; type.EnumDef = enumDef; } else if (def != null && def is StructDef) { type.ElementType = BaseType.Struct; type.StructDef = def as StructDef; } else if (baseType != BaseType.None) { type.ElementType = baseType; } else { throw new Exception("Unexpected type input"); } } else if (def != null) { if (def is EnumDef) { var enumDef = def as EnumDef; type.BaseType = enumDef.UnderlyingType.BaseType; type.EnumDef = enumDef; } else if (def is StructDef) { type.BaseType = BaseType.Struct; type.StructDef = def as StructDef; } else { throw new Exception("Unexpected type input"); } } else { type.BaseType = baseType; } return(offset); }