示例#1
0
 private static void Parse(Tokenizer tokenizer, object current, IniTypeDescription type)
 {
     Tokenizer.Token token;
     string name;
     TypeHash subType;
     IniTypeDescription childType = null;
     IniTypeAndAlias[] typeAndAliases;
     IniTypeAndAlias typeAndAlias;
     Match match;
     object subObject;
     CommonParser.GoToValue(tokenizer);
     Dictionary<string, int> attributeSetCheck = new Dictionary<string, int>(type.Items.Length);
     for (int idx = 0; idx < type.Items.Length; ++idx)
     {
         attributeSetCheck.Add(type.Items[idx].Name, 0);
     }
     while ((token = tokenizer.Current()).Type != EXPRESSION_OBJECTEND)
     {
         if (token.Type != EXPRESSION_ATTRIBUTE)
         {
             throw new OpenSAGEException(ErrorCode.IniParser, "Token '$TOKEN$' was not recognized", "token", token);
         }
         name = _attributeId.Match(token.Value).Groups["name"].Value;
         IIniDescription itemDescription = null;
         for (int idx = 0; idx < type.Items.Length; ++idx)
         {
             if (type.Items[idx].Name == name)
             {
                 itemDescription = type.Items[idx];
                 break;
             }
         }
         if (itemDescription == null)
         {
             throw new OpenSAGEException(ErrorCode.IniParser, "No property named $NAME$ can be found.", "name", name);
         }
         token = tokenizer.Next();
         if (itemDescription is IniPropertyDescription)
         {
             object result;
             if (!(itemDescription as IniPropertyDescription).TheParseHandler(tokenizer, (itemDescription as IniPropertyDescription).ItemType, out result))
             {
                 throw new OpenSAGEException(ErrorCode.IniParser, "Could not parse property named $NAME$.", "name", name);
             }
             if (itemDescription.MaxOccurrences == 1)
             {
                 itemDescription.Property.SetValue(current, result);
             }
             else
             {
                 if (itemDescription.Property.PropertyType.IsArray)
                 {
                     Array testArray = itemDescription.Property.GetValue(current) as Array;
                     if (attributeSetCheck[name] == testArray.Length)
                     {
                         throw new OpenSAGEException(ErrorCode.IniParser, "Attribute $NAME$ was set more times than its array length ($LENGTH$).",
                             "name", itemDescription.Name, "length", testArray.Length);
                     }
                     (itemDescription.Property.GetValue(current) as Array).SetValue(result, attributeSetCheck[name]);
                 }
                 else
                 {
                     itemDescription.Property.PropertyType.GetMethod("Add").Invoke(itemDescription.Property.GetValue(current), new[] { result });
                 }
             }
         }
         else
         {
             if (token.Type != EXPRESSION_OBJECTSTART)
             {
                 throw new OpenSAGEException(ErrorCode.IniParser, "Token '$TOKEN$' was not recognized", "token", token);
             }
             match = _objectTypeAndId.Match(token.Value);
             subType = match.Groups["type"].Value;
             typeAndAliases = (itemDescription as IniTypePropertyDescription).TypeOptions;
             typeAndAlias = null;
             for (int idx = 0; idx < typeAndAliases.Length; ++idx)
             {
                 if (typeAndAliases[idx].Alias == subType)
                 {
                     typeAndAlias = typeAndAliases[idx];
                 }
             }
             if (typeAndAlias == null)
             {
                 throw new OpenSAGEException(ErrorCode.IniParser, "No object of type $TYPE$ can be instanciated.", "type", subType.TheString);
             }
             childType = _descriptions.Find(x => x.Name == subType);
             if (typeAndAlias == null)
             {
                 throw new OpenSAGEException(ErrorCode.IniParser, "No object of type $TYPE$ can be instanciated.", "type", subType.TheString);
             }
             subObject = Activator.CreateInstance(typeAndAlias.Type, match.Groups["id"].Value);
             tokenizer.Next();
             Parse(tokenizer, subObject, childType);
             if (itemDescription.MaxOccurrences == 1)
             {
                 itemDescription.Property.SetValue(current, subObject);
             }
             else
             {
                 if (itemDescription.Property.PropertyType.IsArray)
                 {
                     Array testArray = itemDescription.Property.GetValue(current) as Array;
                     if (attributeSetCheck[name] == testArray.Length)
                     {
                         throw new OpenSAGEException(ErrorCode.IniParser, "Attribute $NAME$ was set more times than its array length ($LENGTH$).",
                             "name", itemDescription.Name, "length", testArray.Length);
                     }
                     (itemDescription.Property.GetValue(current) as Array).SetValue(subObject, attributeSetCheck[name]);
                 }
                 else
                 {
                     itemDescription.Property.PropertyType.GetMethod("Add").Invoke(itemDescription.Property.GetValue(current), new[] { subObject });
                 }
             }
         }
         ++attributeSetCheck[name];
         tokenizer.Next();
         CommonParser.GoToValue(tokenizer);
     }
     IIniDescription item;
     for (int idx = 0; idx < type.Items.Length; ++idx)
     {
         if ((item = type.Items[idx]).MinOccurrences != 0 && attributeSetCheck[item.Name] < item.MinOccurrences)
         {
             throw new OpenSAGEException(ErrorCode.IniParser, "Attribute $NAME$ was only set $OCCURRENCIES$ times but needs to be set at least $MIN$ times.",
                 "name", item.Name, "occurrencies", attributeSetCheck[item.Name], "min", item.MinOccurrences);
         }
         if (item.MaxOccurrences != 0 && attributeSetCheck[item.Name] > item.MaxOccurrences)
         {
             throw new OpenSAGEException(ErrorCode.IniParser, "Attribute $NAME$ was set $OCCURRENCIES$ times but needs to be set at most $MAX$ times.",
                 "name", item.Name, "occurrencies", attributeSetCheck[item.Name], "max", item.MaxOccurrences);
         }
     }
     tokenizer.Next();
 }
示例#2
0
 public static void RegisterType(IniTypeDescription description)
 {
     _descriptions.Add(description);
 }