Skip to content

Instantly share code, notes, and snippets.

@blam23
Created August 26, 2012 18:58
Show Gist options
  • Save blam23/3482605 to your computer and use it in GitHub Desktop.
Save blam23/3482605 to your computer and use it in GitHub Desktop.
AxConfig Parser
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace AxRun
{
public class AxConfigEntry
{
public string Name;
public Dictionary<String, Object> Data;
public AxConfigEntry(string name)
{
Name = name;
Data = new Dictionary<string, object>();
}
public void Insert(string name, object data)
{
Data.Add(name, data);
}
public bool TryGetValue<T>(string k, out T value)
{
object v;
var d = Data.TryGetValue(k, out v);
if (d)
{
if (v is object[])
{
throw new Exception("TryGetValue does not support arrays, use TryGetArray instead.");
}
value = (T) Convert.ChangeType(v, typeof (T));
return true;
}
value = default(T);
return false;
}
public bool TryGetArray<T>(string k, out T[] value)
{
object v;
var d = Data.TryGetValue(k, out v);
if (d)
{
var c = (object[])v;
value = new T[c.Length];
for (var i = 0; i < c.Length; i++)
{
value[i] = (T)Convert.ChangeType(c[i], typeof(T));
}
return true;
}
value = default(T[]);
return false;
}
public bool IsArray(string k)
{
object v;
var d = Data.TryGetValue(k, out v);
if (d)
{
return v is object[];
}
return false;
}
}
public class AxConfig
{
public string Path;
public Dictionary<String, AxConfigEntry> Entries = new Dictionary<string, AxConfigEntry>();
public const string INDENTS = " \t-";
private int _line = 0;
public AxConfigEntry this[string key]
{
get { return Entries[key]; }
}
public void Load(String path)
{
Path = path;
AxConfigEntry current = null;
var lines = File.ReadAllLines(path);
for (var i = 0; i < lines.Length; i++)
{
_line = i + 1;
var tl = lines[i].Trim();
if (tl.Length == 0)
{
continue;
}
if (tl[0] == '#')
{
continue;
}
var line = lines[i].Trim();
if (INDENTS.IndexOf(lines[i][0]) != -1)
{
if(current == null)
{
throw Error("indentation found on upper level object");
}
var indx = line.IndexOf('=');
if(indx == -1)
{
throw Error("missing assignment");
}
var var = line.Substring(0, indx).Trim();
var value = GetValue(line.Substring(indx+1).Trim());
current.Insert(var, value);
}
else
{
current = new AxConfigEntry(line);
Entries.Add(line, current);
}
}
}
public object GetValue(string p)
{
if (p == "true") return true;
if (p == "false") return false;
if (p[0] == '"')
{
return p.Substring(1, p.Length - 2);
}
if (Char.IsNumber(p[0]) || p[0] == '-' || p[0] == '.')
{
var hex = p.StartsWith("0x");
if (p.EndsWith("f"))
{
return float.Parse(p.Substring(0, p.Length - 1), hex ? NumberStyles.HexNumber : NumberStyles.Float);
}
if (p.EndsWith("l"))
{
return long.Parse(p.Substring(0, p.Length - 1), hex ? NumberStyles.HexNumber : NumberStyles.Integer);
}
if (p.EndsWith("b"))
{
return byte.Parse(p.Substring(0, p.Length - 1), hex ? NumberStyles.None : NumberStyles.Integer);
}
return p.Contains(".") ? double.Parse(p.Substring(0, p.Length), hex ? NumberStyles.HexNumber : NumberStyles.Float) : int.Parse(p.Substring(0, p.Length - 1), hex ? NumberStyles.HexNumber : NumberStyles.Integer);
}
if (p[0] == '[')
{
var arr = new List<object>();
var i = 1;
var j = 1;
while (i < p.Length-1)
{
var instr = false;
while ((p[j] != ']' && p[j] != ',') || instr)
{
if (p[j] == '"' && p[j - 1] != '\\')
instr = !instr;
j++;
}
var var = p.Substring(i, j-i).Trim();
arr.Add(GetValue(var));
i = ++j;
}
return arr.ToArray();
}
throw Error("invalid data");
}
private Exception Error(string p)
{
return new Exception(String.Format("Invalid AxFile, {0} on line {1}", p, _line));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment