Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 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);
 }
Example #4
0
 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);
 }
Example #5
0
        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);
        }
Example #6
0
        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);
        }