Пример #1
0
 protected String GetAttrTypeID(AttributeType attrtype)
 {
     return((attrtype.OwnerType.IsNodeType ? "NAT_" : "EAT_")
            + attrtype.OwnerType.Name + "_" + attrtype.Name);
 }
        public static object ParseImpl(TextReader reader, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
        {
            char lookahead = (char)reader.Peek();

            if (lookahead == 'o')
            {
                reader.Read(); // eat 'o'
                return(new Own());
            }
            else if (lookahead == 'p')
            {
                reader.Read();                                       // eat 'p'
                StringBuilder sb = new StringBuilder();
                while (reader.Peek() != ',' && reader.Peek() != ')') // attributes are separated by , a node/edge terminated by ) in .grs
                {
                    sb.Append((char)reader.Read());                  // eat non ',', ')'
                }
                OwnPown op = new OwnPown();
                op.ehe = sb.ToString();
                return(op);
            }
            else if (lookahead == 'h')
            {
                reader.Read(); // eat 'h'
                StringBuilder sb = new StringBuilder();
                while (reader.Peek() != ';')
                {
                    sb.Append((char)reader.Read()); // eat non ';'
                }
                string ehe = sb.ToString();
                sb.Length = 0;
                reader.Read();                                       // eat ';'
                while (reader.Peek() != ',' && reader.Peek() != ')') // attributes are separated by , a node/edge terminated by ) in .grs
                {
                    sb.Append((char)reader.Read());                  // eat non ',',')'
                }
                OwnPownHome oph = new OwnPownHome();
                oph.ehe = ehe;
                oph.aha = sb.ToString();
                return(oph);
            }
            else
            {
                if (reader.Peek() == 'n')
                {
                    reader.Read();
                    if (reader.Peek() == 'u')
                    {
                        reader.Read();
                        if (reader.Peek() == 'l')
                        {
                            reader.Read();
                            if (reader.Peek() == 'l')
                            {
                                reader.Read();
                                return(null);
                            }
                        }
                    }
                }
                throw new Exception("parsing failure");
            }
        }
Пример #3
0
 // convenience helper function for firing the changing node/edge/object attribute event (contains type dispatching and fixes the change type to assignment)
 public static void ChangingAttributeAssign(IGraph graph, IAttributeBearer owner, AttributeType attrType, object value)
 {
     if (owner is INode)
     {
         graph.ChangingNodeAttribute((INode)owner, attrType, AttributeChangeType.Assign, value, null);
     }
     else if (owner is IEdge)
     {
         graph.ChangingEdgeAttribute((IEdge)owner, attrType, AttributeChangeType.Assign, value, null);
     }
     else
     {
         graph.ChangingObjectAttribute((IObject)owner, attrType, AttributeChangeType.Assign, value, null);
     }
 }
Пример #4
0
 protected String GetDomainID(AttributeType attrType)
 {
     return(GetDomainID(attrType.Kind, attrType.EnumType));
 }
Пример #5
0
 public string Emit(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     return(attribute != null?attribute.ToString() : "null");
 }
Пример #6
0
 public object Parse(TextReader reader, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     reader.Read(); reader.Read(); reader.Read(); reader.Read();             // eat 'n' 'u' 'l' 'l'
     return(null);
 }
Пример #7
0
        /// <summary>
        /// Type needed for enum, otherwise null ok.
        /// Graph needed for node/edge, otherwise null ok.
        /// Main graph context needed to get access to the graph -> env dictionary for subgraph.
        /// </summary>
        public static void EmitAttributeValue(MainGraphExportContext mainGraphContext,
                                              object value, AttributeType type, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits)
        {
            switch (type.Kind)
            {
            case AttributeKind.ByteAttr:
                sw.Write(((sbyte)value).ToString() + "Y");
                return;

            case AttributeKind.ShortAttr:
                sw.Write(((short)value).ToString() + "S");
                return;

            case AttributeKind.IntegerAttr:
                sw.Write(((int)value).ToString());
                return;

            case AttributeKind.LongAttr:
                sw.Write(((long)value).ToString() + "L");
                return;

            case AttributeKind.BooleanAttr:
                sw.Write(((bool)value).ToString());
                return;

            case AttributeKind.StringAttr:
                if (value == null)
                {
                    sw.Write("\"\"");
                }
                else
                {
                    sw.Write("\"" + ((string)value).Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"");
                }
                return;

            case AttributeKind.FloatAttr:
                sw.Write(((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture) + "f");
                return;

            case AttributeKind.DoubleAttr:
                sw.Write(((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture));
                return;

            case AttributeKind.ObjectAttr:
                sw.Write(graph.Model.Serialize(value, type, graph));
                return;

            case AttributeKind.GraphAttr:
                if (value != null && mainGraphContext != null && mainGraphContext.graphToContext != null)
                {
                    sw.Write("\"" + mainGraphContext.graphToContext[(INamedGraph)value].name + "\"");
                }
                else
                {
                    sw.Write("null");
                }
                return;

            case AttributeKind.EnumAttr:
                sw.Write(type.EnumType.PackagePrefixedName + "::" + type.EnumType[(int)value].Name);
                return;

            case AttributeKind.NodeAttr:
            case AttributeKind.EdgeAttr:
                if (value != null)
                {
                    sw.Write("@(\"" + graph.GetElementName((IGraphElement)value) + "\")");
                }
                else
                {
                    sw.Write("null");
                }
                return;

            case AttributeKind.InternalClassObjectAttr:
                if (value != null)
                {
                    IObject obj = (IObject)value;
                    EmitObjectFetchingOrCreation(mainGraphContext, obj.Type, obj, graph, sw, deferredInits);
                }
                else
                {
                    sw.Write("null");
                }
                return;

            default:
                throw new Exception("Unsupported attribute kind in export");
            }
        }
 // Called during debugging or emit writing, the implementation must return a string representation for the attribute.
 // For attribute type object or a user defined type, which is treated as object.
 // The attribute type may be null.
 // The string is meant for consumption by humans, it does not need to be parseable.
 public static string Emit(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     return(EmitImpl(attribute, attrType, graph));
     //return "null"; // default implementation
 }
Пример #9
0
 /// <summary>
 /// Emits the node/edge attribute initialization code in graph exporting
 /// for an attribute of the given type with the given value into the stream writer.
 /// </summary>
 private static void EmitAttributeInitialization(MainGraphExportContext mainGraphContext,
                                                 AttributeType attrType, object value, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits)
 {
     sw.Write(", {0} = ", attrType.Name);
     EmitAttribute(mainGraphContext, attrType, value, graph, sw, deferredInits);
 }
Пример #10
0
 /// <summary>
 /// Emits the attribute value as code
 /// for an attribute of the given type with the given value into the stream writer
 /// Main graph context is needed to get access to the graph -> env dictionary.
 /// </summary>
 public static void EmitAttribute(MainGraphExportContext mainGraphContext,
                                  AttributeType attrType, object value, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits)
 {
     if (attrType.Kind == AttributeKind.SetAttr)
     {
         IDictionary set = (IDictionary)value;
         sw.Write("{0}{{", attrType.GetKindName());
         bool first = true;
         foreach (DictionaryEntry entry in set)
         {
             if (first)
             {
                 EmitAttributeValue(mainGraphContext, entry.Key, attrType.ValueType, graph, sw, deferredInits);
                 first = false;
             }
             else
             {
                 sw.Write(",");
                 EmitAttributeValue(mainGraphContext, entry.Key, attrType.ValueType, graph, sw, deferredInits);
             }
         }
         sw.Write("}");
     }
     else if (attrType.Kind == AttributeKind.MapAttr)
     {
         IDictionary map = (IDictionary)value;
         sw.Write("{0}{{", attrType.GetKindName());
         bool first = true;
         foreach (DictionaryEntry entry in map)
         {
             if (first)
             {
                 EmitAttributeValue(mainGraphContext, entry.Key, attrType.KeyType, graph, sw, deferredInits);
                 sw.Write("->");
                 EmitAttributeValue(mainGraphContext, entry.Value, attrType.ValueType, graph, sw, deferredInits);
                 first = false;
             }
             else
             {
                 sw.Write(",");
                 EmitAttributeValue(mainGraphContext, entry.Key, attrType.KeyType, graph, sw, deferredInits);
                 sw.Write("->");
                 EmitAttributeValue(mainGraphContext, entry.Value, attrType.ValueType, graph, sw, deferredInits);
             }
         }
         sw.Write("}");
     }
     else if (attrType.Kind == AttributeKind.ArrayAttr)
     {
         IList array = (IList)value;
         sw.Write("{0}[", attrType.GetKindName());
         bool first = true;
         foreach (object entry in array)
         {
             if (first)
             {
                 EmitAttributeValue(mainGraphContext, entry, attrType.ValueType, graph, sw, deferredInits);
                 first = false;
             }
             else
             {
                 sw.Write(",");
                 EmitAttributeValue(mainGraphContext, entry, attrType.ValueType, graph, sw, deferredInits);
             }
         }
         sw.Write("]");
     }
     else if (attrType.Kind == AttributeKind.DequeAttr)
     {
         IDeque deque = (IDeque)value;
         sw.Write("{0}[", attrType.GetKindName());
         bool first = true;
         foreach (object entry in deque)
         {
             if (first)
             {
                 EmitAttributeValue(mainGraphContext, entry, attrType.ValueType, graph, sw, deferredInits);
                 first = false;
             }
             else
             {
                 sw.Write(",");
                 EmitAttributeValue(mainGraphContext, entry, attrType.ValueType, graph, sw, deferredInits);
             }
         }
         sw.Write("]");
     }
     else
     {
         EmitAttributeValue(mainGraphContext, value, attrType, graph, sw, deferredInits);
     }
 }
Пример #11
0
        private static bool AddSubgraphAsNeeded(MainGraphExportContext mainGraphContext,
                                                IGraphElement elem, AttributeType attrType)
        {
            if (attrType.Kind == AttributeKind.GraphAttr)
            {
                return(AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)elem.GetAttribute(attrType.Name)));
            }

            bool graphAdded = false;

            if (attrType.Kind == AttributeKind.SetAttr ||
                attrType.Kind == AttributeKind.MapAttr ||
                attrType.Kind == AttributeKind.ArrayAttr ||
                attrType.Kind == AttributeKind.DequeAttr)
            {
                if (attrType.ValueType.Kind == AttributeKind.GraphAttr)
                {
                    if (attrType.Kind == AttributeKind.SetAttr)
                    {
                        IDictionary set = (IDictionary)elem.GetAttribute(attrType.Name);
                        foreach (DictionaryEntry entry in set)
                        {
                            graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key);
                        }
                    }
                    else if (attrType.Kind == AttributeKind.MapAttr)
                    {
                        IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name);
                        foreach (DictionaryEntry entry in map)
                        {
                            graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Value);
                        }
                    }
                    else if (attrType.Kind == AttributeKind.ArrayAttr)
                    {
                        IList array = (IList)elem.GetAttribute(attrType.Name);
                        foreach (object entry in array)
                        {
                            graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry);
                        }
                    }
                    else if (attrType.Kind == AttributeKind.DequeAttr)
                    {
                        IDeque deque = (IDeque)elem.GetAttribute(attrType.Name);
                        foreach (object entry in deque)
                        {
                            graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry);
                        }
                    }
                }
            }

            if (attrType.Kind == AttributeKind.MapAttr)
            {
                if (attrType.KeyType.Kind == AttributeKind.GraphAttr)
                {
                    IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name);
                    foreach (DictionaryEntry entry in map)
                    {
                        graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key);
                    }
                }
            }

            return(graphAdded);
        }
Пример #12
0
 // convenience helper function for firing the changing node/edge/object attribute event (for an attribute of map type, contains type dispatching and fixes the change type to element removal)
 public static void ChangingMapAttributeRemoveElement(IGraph graph, IAttributeBearer owner, AttributeType attrType, object keyToRemove)
 {
     if (owner is INode)
     {
         graph.ChangingNodeAttribute((INode)owner, attrType, AttributeChangeType.RemoveElement, null, keyToRemove);
     }
     else if (owner is IEdge)
     {
         graph.ChangingEdgeAttribute((IEdge)owner, attrType, AttributeChangeType.RemoveElement, null, keyToRemove);
     }
     else
     {
         graph.ChangingObjectAttribute((IObject)owner, attrType, AttributeChangeType.RemoveElement, null, keyToRemove);
     }
 }
Пример #13
0
 // convenience helper function for firing the changing node/edge/object attribute event (for an attribute of map type, contains type dispatching and fixes the change type to element addition)
 public static void ChangingMapAttributePutElement(IGraph graph, IAttributeBearer owner, AttributeType attrType, object key, object value)
 {
     if (owner is INode)
     {
         graph.ChangingNodeAttribute((INode)owner, attrType, AttributeChangeType.PutElement, value, key);
     }
     else if (owner is IEdge)
     {
         graph.ChangingEdgeAttribute((IEdge)owner, attrType, AttributeChangeType.PutElement, value, key);
     }
     else
     {
         graph.ChangingObjectAttribute((IObject)owner, attrType, AttributeChangeType.PutElement, value, key);
     }
 }
        // You must implement this class in the same partial class in ./ExternalAttributeEvaluationModelExternalFunctionsImpl.cs:
        // You must implement the functions called by the following functions inside that class (same name plus suffix Impl):

        // Called during .grs import, at exactly the position in the text reader where the attribute begins.
        // For attribute type object or a user defined type, which is treated as object.
        // The implementation must parse from there on the attribute type requested.
        // It must not parse beyond the serialized representation of the attribute,
        // i.e. Peek() must return the first character not belonging to the attribute type any more.
        // Returns the parsed object.
        public static object Parse(TextReader reader, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
        {
            return(ParseImpl(reader, attrType, graph));
            //reader.Read(); reader.Read(); reader.Read(); reader.Read(); // eat 'n' 'u' 'l' 'l' // default implementation
            //return null; // default implementation
        }
Пример #15
0
        private static bool IsAttributeToBeSkipped(MainGraphExportContext mainGraphContext, AttributeType attrType)
        {
            if (mainGraphContext.typesToAttributesToSkip != null &&
                mainGraphContext.typesToAttributesToSkip.ContainsKey(attrType.OwnerType.PackagePrefixedName) &&
                mainGraphContext.typesToAttributesToSkip[attrType.OwnerType.PackagePrefixedName].ContainsKey(attrType.Name))
            {
                return(true);
            }

            return(false);
        }
 // Called during .grs export, the implementation must return a string representation for the attribute.
 // For attribute type object or a user defined type, which is treated as object.
 // The serialized string must be parseable by Parse.
 public static string Serialize(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     return(SerializeImpl(attribute, attrType, graph));
     //Console.WriteLine("Warning: Exporting attribute of object type to null"); // default implementation
     //return "null"; // default implementation
 }
Пример #17
0
        /// <summary>
        /// Returns a string representation of the given non-container value
        /// </summary>
        /// <param name="value">The scalar of which to get the string representation</param>
        /// <param name="attrType">The attribute type (may be null)</param>
        /// <param name="graph">The graph with the model and the element names</param>
        /// <returns>String representation of the scalar.</returns>
        /// <param name="firstLevelObjectEmitted">Prevents emitting of further objects and thus infinite regressions</param>
        /// <param name="nameToObject">If not null, the names of visited objects are added</param>
        /// <param name="procEnv">If not null, the processing environment is used for transient object unique id emitting and fetching</param>
        private static string ToString(object value, AttributeType attrType, IGraph graph,
                                       bool firstLevelObjectEmitted, IDictionary <string, IObject> nameToObject, IGraphProcessingEnvironment procEnv)
        {
            if (value is IMatch)
            {
                return(ToString((IMatch)value, graph, firstLevelObjectEmitted, nameToObject, procEnv));
            }
            if (value is IObject)
            {
                return(ToString((IObject)value, graph, firstLevelObjectEmitted, nameToObject, procEnv));
            }
            if (value is ITransientObject)
            {
                return(ToString((ITransientObject)value, graph, firstLevelObjectEmitted, nameToObject, procEnv));
            }

            // enums are bitches, sometimes ToString gives the symbolic name, sometimes only the integer value
            // we always want the symbolic name, enforce this here
            if (attrType != null && attrType.Kind == AttributeKind.EnumAttr)
            {
                Debug.Assert(attrType.Kind != AttributeKind.SetAttr && attrType.Kind != AttributeKind.MapAttr);
                EnumAttributeType enumAttrType = attrType.EnumType;
                EnumMember        member       = enumAttrType[(int)value];
                if (member != null)
                {
                    return(member.Name);
                }
            }
            if (graph != null && value is Enum)
            {
                Debug.Assert(value.GetType().Name != "Dictionary`2" &&
                             value.GetType().Name != "List`1" && value.GetType().Name != "Deque`1");
                foreach (EnumAttributeType enumAttrType in graph.Model.EnumAttributeTypes)
                {
                    if (value.GetType() == enumAttrType.EnumType)
                    {
                        EnumMember member = enumAttrType[(int)value];
                        if (member != null)
                        {
                            return(member.Name);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            // for set/map entries of node/edge type return the persistent name
            if (attrType != null && (attrType.Kind == AttributeKind.NodeAttr || attrType.Kind == AttributeKind.EdgeAttr))
            {
                if (graph != null && value != null)
                {
                    return(((INamedGraph)graph).GetElementName((IGraphElement)value));
                }
            }
            if (value is IGraphElement)
            {
                if (graph != null)
                {
                    return(((INamedGraph)graph).GetElementName((IGraphElement)value));
                }
            }

            // we return "" for null as null is a valid string denoting the empty string in GrGen (dubious performance optimization)
            if (value == null)
            {
                return("");
            }
            else
            {
                if (value is double)
                {
                    return(((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture));
                }
                else if (value is float)
                {
                    return(((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture) + "f");
                }
                else
                {
                    return(value.ToString());
                }
            }
        }
 // Called during debugging on user request, the implementation must return a named graph representation for the attribute.
 // For attribute type object or a user defined type, which is treated as object.
 // The attribute type may be null. The return graph must be of the same model as the graph handed in.
 // The named graph is meant for display in the debugger, to visualize the internal structure of some attribute type.
 // This way you can graphically inspect your own data types which are opaque to GrGen with its debugger.
 public static GRGEN_LIBGR.INamedGraph AsGraph(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     return(AsGraphImpl(attribute, attrType, graph));
     //return null; // default implementation
 }
Пример #19
0
        public static String AttributeTypeToXgrsType(AttributeType attributeType)
        {
            switch (attributeType.Kind)
            {
            case AttributeKind.ByteAttr:
                return("byte");

            case AttributeKind.ShortAttr:
                return("short");

            case AttributeKind.IntegerAttr:
                return("int");

            case AttributeKind.LongAttr:
                return("long");

            case AttributeKind.BooleanAttr:
                return("boolean");

            case AttributeKind.StringAttr:
                return("string");

            case AttributeKind.FloatAttr:
                return("float");

            case AttributeKind.DoubleAttr:
                return("double");

            case AttributeKind.ObjectAttr:
                return("object");

            case AttributeKind.EnumAttr:
                return(attributeType.EnumType.PackagePrefixedName);

            case AttributeKind.SetAttr:
                return("set<" + AttributeTypeToXgrsType(attributeType.ValueType) + ">");

            case AttributeKind.MapAttr:
                return("map<" + AttributeTypeToXgrsType(attributeType.KeyType) + "," + AttributeTypeToXgrsType(attributeType.ValueType) + ">");

            case AttributeKind.ArrayAttr:
                return("array<" + AttributeTypeToXgrsType(attributeType.ValueType) + ">");

            case AttributeKind.DequeAttr:
                return("deque<" + AttributeTypeToXgrsType(attributeType.ValueType) + ">");

            case AttributeKind.NodeAttr:
                return(attributeType.PackagePrefixedTypeName);

            case AttributeKind.EdgeAttr:
                return(attributeType.PackagePrefixedTypeName);

            case AttributeKind.InternalClassObjectAttr:
                return(attributeType.PackagePrefixedTypeName);

            case AttributeKind.InternalClassTransientObjectAttr:
                return(attributeType.PackagePrefixedTypeName);

            case AttributeKind.GraphAttr:
                return("graph");

            default:
                return(null);
            }
        }
Пример #20
0
 public GRGEN_LIBGR.INamedGraph AsGraph(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     return(null);
 }
Пример #21
0
 /// <summary>
 /// Initializes an info tag.
 /// </summary>
 /// <param name="attrType">The attribute to be shown.</param>
 /// <param name="shortInfoTag">Whether this is a short info tag (no attribute name is shown).</param>
 public InfoTag(AttributeType attrType, bool shortInfoTag)
 {
     AttributeType = attrType;
     ShortInfoTag  = shortInfoTag;
 }
Пример #22
0
 public string Serialize(object attribute, GRGEN_LIBGR.AttributeType attrType, GRGEN_LIBGR.IGraph graph)
 {
     Console.WriteLine("Warning: Exporting attribute of object type to null");
     return("null");
 }
Пример #23
0
        private static void ReadAttributes(IGraphElement elem, XmlElement xmlelem)
        {
            GraphElementType type = elem.Type;

            foreach (XmlElement attrelem in xmlelem.GetElementsByTagName("attr"))
            {
                String        attrname = attrelem.GetAttribute("name");
                String        attrval  = attrelem.InnerText;
                AttributeType attrType = type.GetAttributeType(attrname);

                object value = null;
                switch (attrType.Kind)
                {
                case AttributeKind.BooleanAttr:
                    if (attrval.Equals("true", StringComparison.OrdinalIgnoreCase))
                    {
                        value = true;
                    }
                    else if (attrval.Equals("false", StringComparison.OrdinalIgnoreCase))
                    {
                        value = false;
                    }
                    else
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be either \"true\" or \"false\"!");
                    }
                    break;

                case AttributeKind.EnumAttr:
                {
                    int val;
                    if (Int32.TryParse(attrval, out val))
                    {
                        value = val;
                    }
                    else
                    {
                        foreach (EnumMember member in attrType.EnumType.Members)
                        {
                            if (attrval == member.Name)
                            {
                                value = member.Value;
                                break;
                            }
                        }
                        if (value == null)
                        {
                            String errorText = "Attribute \"" + attrname + "\" must be one of the following values:";
                            foreach (EnumMember member in attrType.EnumType.Members)
                            {
                                errorText += " - " + member.Name + " = " + member.Value;
                            }
                            throw new Exception(errorText);
                        }
                    }
                    break;
                }

                case AttributeKind.ByteAttr:
                {
                    sbyte val;
                    if (!SByte.TryParse(attrval, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be a byte (signed)!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.ShortAttr:
                {
                    short val;
                    if (!Int16.TryParse(attrval, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be a short!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.IntegerAttr:
                {
                    int val;
                    if (!Int32.TryParse(attrval, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be an integer!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.LongAttr:
                {
                    long val;
                    if (!Int64.TryParse(attrval, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be a long!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.StringAttr:
                    value = attrval;
                    break;

                case AttributeKind.FloatAttr:
                {
                    float val;
                    if (!Single.TryParse(attrval, System.Globalization.NumberStyles.Float,
                                         System.Globalization.CultureInfo.InvariantCulture, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be a floating point number!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.DoubleAttr:
                {
                    double val;
                    if (!Double.TryParse(attrval, System.Globalization.NumberStyles.Float,
                                         System.Globalization.CultureInfo.InvariantCulture, out val))
                    {
                        throw new Exception("Attribute \"" + attrname + "\" must be a floating point number!");
                    }
                    value = val;
                    break;
                }

                case AttributeKind.ObjectAttr:
                {
                    throw new Exception("Attribute \"" + attrname + "\" is an object type attribute!\n"
                                        + "It is not possible to assign a value to an object type attribute!");
                }

                case AttributeKind.SetAttr:
                case AttributeKind.MapAttr:
                case AttributeKind.ArrayAttr:
                case AttributeKind.DequeAttr:
                default:
                    throw new Exception("Unsupported attribute value type: \"" + attrType.Kind + "\"");     // TODO: support set=SetAttr and seq=ArrayAttr, here and in export
                }

                elem.SetAttribute(attrname, value);
            }
        }