示例#1
0
 private void InsertIntoData(int index, string value)
 {
     while (_parsedData.Count <= index)
     {
         _parsedData.Add(new ConfigValue(string.Empty, final: true));
     }
     _parsedData[index] = new ConfigValue(value, final: true);
 }
示例#2
0
        private static ConfigValue CvDataFromCustom <T>(T value)
        {
            var str     = value.ToString();
            var escaped = ConfigValue.EscapeString(str);

            if (str.Count(char.IsWhiteSpace) != 0 ||
                escaped != str ||
                string.IsNullOrEmpty(escaped))
            {
                escaped = $"\"{escaped}\"";
            }

            return(new ConfigValue(escaped));
        }
        private static T LoadToCollectionWrap <T>(ConfigValue config)
            where T : class, new()
        {
            var keys = config.GetKeys();

            if (keys.Length > 1)
            {
                throw new FormatException("Array can only contains values with the same identifier");
            }
            else if (keys.Length == 0)
            {
                return(new T());
            }

            var elementsType            = typeof(T).GetGenericArguments().Single();
            var genericLoadToCollection = MethodLoadToCollection.MakeGenericMethod(typeof(T), elementsType);

            return((T)genericLoadToCollection.Invoke(null, new object[] { config.GetAll(keys[0]) }));
        }
        private static void ParseLevel(State state, string baseIndentation)
        {
            ConfigValue lastConfigValue = null;

            while (state.Line < state.Data.Length)
            {
                var line = state.Data[state.Line].TrimEnd();
                if (string.IsNullOrWhiteSpace(line))
                {
                    state.Line += 1;
                    continue;
                }

                var lineIndentation = GetIndentation(line);
                ValidateIndentationLevel(state, lineIndentation, baseIndentation);

                if (lineIndentation.Length > baseIndentation.Length)
                {
                    state.Context.Push(lastConfigValue);
                    ParseLevel(state, lineIndentation);
                    continue;
                }

                if (lineIndentation.Length < baseIndentation.Length)
                {
                    state.Context.Pop();
                    break;
                }

                var data = line.Substring(lineIndentation.Length);
                var len  = data.IndexOfAny(new[] { ' ', '\t' });

                var name  = len < 0 ? data : data.Substring(0, len);
                var value = len < 0 ? "" : data.Substring(len).Trim();
                lastConfigValue = new ConfigValue(value);
                state.Context.Peek().Set(
                    name,
                    lastConfigValue
                    );
                state.Line += 1;
            }
        }
示例#5
0
 public static string SaveToString(ConfigValue config)
 {
     return(GenerateString(config, string.Empty));
 }
示例#6
0
 public static void SaveToStream(ConfigValue config, TextWriter writer)
 {
     writer.Write(GenerateString(config, ""));
 }
        /// <summary>
        /// Loads configuration to given Class type
        /// </summary>
        /// <typeparam name="T">Target class</typeparam>
        /// <param name="config">Configuration</param>
        /// <returns>Class, filled with configuration values oe null</returns>
        public static T LoadToClass <T>(ConfigValue config)
            where T : class, new()
        {
            if (config == null)
            {
                return(null);
            }

            if (typeof(T).GetInterfaces().Contains(typeof(ICollection)))
            {
                return(LoadToCollectionWrap <T>(config));
            }

            var instance = new T();

            foreach (var field in typeof(T).GetFields())
            {
                var dataSourceAttribute = field.GetCustomAttribute <ConfigDataSourceAttribute>();
                var path = dataSourceAttribute?.DataPath
                           ?? field.Name.ToLowerInvariant();

                if (!config.ContainsPath(path))
                {
                    // Skipping not relevant fields
                    continue;
                }

                if (field.FieldType.GetTypeInfo().IsPrimitive ||
                    field.FieldType.GetConstructor(Type.EmptyTypes) == null)
                {
                    var configValue     = config.GetByPath(path);
                    var genericAsCustom =
                        configValue.AsConfigList().Count == 1
                            ? MethodAsCustom.MakeGenericMethod(field.FieldType)
                            : MethodAsCustomFromRaw.MakeGenericMethod(field.FieldType);

                    var value = genericAsCustom.Invoke(configValue, null);

                    field.SetValue(instance, value);
                }
                else
                {
                    var fieldType = field.FieldType;

                    var typeSource = field.GetCustomAttribute <ConfigDataTypeSourceAttribute>();
                    var typeName   =
                        config.GetByPath(typeSource?.DataPath)
                        ?.AsString()
                        ?.ToLowerInvariant();
                    if (typeName != null)
                    {
                        var mapping = field.GetCustomAttributes <ConfigDataTypeMappingAttribute>();
                        fieldType = mapping
                                    ?.FirstOrDefault(attr => attr.TypeName == typeName)
                                    ?.FieldType
                                    ?? Assembly
                                    .GetEntryAssembly()
                                    .GetTypes()
                                    .Where(t => field.FieldType.IsAssignableFrom(t))
                                    .FirstOrDefault(t => t.Name.ToLowerInvariant() == typeName)
                                    ?? throw new TypeLoadException(
                                              $"Can not find type with name '{typeName}'"
                                              );
                    }

                    var genericLoadToClass = MethodLoadToClass.MakeGenericMethod(fieldType);
                    var innerInstance      = genericLoadToClass.Invoke(null, new object[] { config.GetByPath(path) });
                    field.SetValue(instance, innerInstance);
                }
            }

            return(instance);
        }
示例#8
0
        private static void SetByPathNamed
            (string path, ConfigValue root, ConfigValue value)
        {
            if (path == null || value == null)
            {
                return;
            }

            var pathLower    = path.ToLowerInvariant().Trim().TrimStart('.');
            var targetParent = root;
            var target       = root;
            var name         = ":";

            while (!string.IsNullOrEmpty(pathLower))
            {
                if (char.IsDigit(pathLower.FirstOrDefault()))
                {
                    var indexStr = new string(
                        pathLower.TakeWhile(char.IsDigit).ToArray()
                        );

                    var sindex = int.Parse(indexStr, NumberStyles.Integer, CultureInfo.InvariantCulture);

                    while (targetParent.GetAll(name).Count <= sindex)
                    {
                        targetParent.Set(name, "");
                    }

                    pathLower = pathLower.Substring(indexStr.Length).Trim().TrimStart('.');
                    target    = targetParent.GetAll(name)[sindex];
                }
                else if (char.IsLetter(pathLower.First()))
                {
                    var key = new string(
                        pathLower.TakeWhile(char.IsLetter).ToArray()
                        );

                    pathLower    = pathLower.Substring(key.Length).Trim().TrimStart('.');
                    targetParent = target;
                    if (!target.Contains(key))
                    {
                        target.Set(key, Config.Create());
                    }
                    target = target.Get(key);
                    name   = key;
                }
                else if (pathLower.First() == '$' && char.IsDigit(pathLower.ElementAtOrDefault(1)))
                {
                    var indexStr = new string(
                        pathLower.Skip(1).TakeWhile(char.IsDigit).ToArray()
                        );
                    var sindex = int.Parse(indexStr, NumberStyles.Integer, CultureInfo.InvariantCulture);
                    target.InsertIntoData(sindex, value._parsedData.First()._data);
                    target._data = target.ParsedDataToRawString();

                    pathLower = pathLower.Substring(indexStr.Length + 1).Trim().TrimStart('.');
                    if (!string.IsNullOrEmpty(pathLower))
                    {
                        throw new FormatException(
                                  $"Data arguments indexation must be the last operation. Rest: '{pathLower}'"
                                  );
                    }
                    return;
                }
                else
                {
                    throw new FormatException($"Unexpected symbol '{pathLower[0]}'({(byte)pathLower[0]})");
                }
            }


            if (value._data != null)
            {
                target._data       = value._data;
                target._parsedData = value._parsedData;
            }

            foreach (var val in value._values)
            {
                target._values.Add(val.Key, val.Value);
            }
        }
示例#9
0
 /// <summary>
 /// Saves new values with given name
 /// </summary>
 /// <param name="path">Path to the value</param>
 /// <param name="value"></param>
 /// <returns></returns>
 public ConfigValue SetByPath(string path, ConfigValue value)
 {
     SetByPathNamed(path, this, value);
     return(this);
 }