private void InputStructure(IDictionary cs, ref string file, ref string data, ref int pos, ref int line)
{
string key = "";
// Go through all of the data until
// the end or until the struct closes
// or when an arror occurred
while ((pos < data.Length) && !cpErrorResult)
{
// Get current character
char c = data[pos++];
// Check what character this is
switch(c)
{
case '{': // Begin of new struct
// Validate key
if(ValidateKey(cs, key.Trim(), file, line))
{
// Parse this struct and add it
IDictionary cs2;
if(cs is ListDictionary) cs2 = new ListDictionary(); else cs2 = new Hashtable();
InputStructure(cs2, ref file, ref data, ref pos, ref line);
if(cs.Contains(key.Trim()) && (cs[key.Trim()] is IDictionary))
cs[key.Trim()] = Combine((IDictionary)cs[key.Trim()], cs2, (cs is ListDictionary));
else
cs[key.Trim()] = cs2;
key = "";
}
break;
case '}': // End of this struct
// Stop parsing in this struct
return;
case '(': // Function
ParseFunction(cs, ref file, ref data, ref pos, ref line, ref key);
key = "";
break;
case '=': // Assignment
// Validate key
if(ValidateKey(cs, key.Trim(), file, line))
{
// Now parsing assignment
object val = ParseAssignment(ref file, ref data, ref pos, ref line);
if(!cpErrorResult)
{
cs[key.Trim()] = val;
key = "";
}
}
break;
case ';': // Terminator
// Validate key
if(!string.IsNullOrEmpty(key))
{
if(ValidateKey(cs, key.Trim(), file, line))
{
// Add the key with null as value
cs[key.Trim()] = null;
key = "";
}
}
break;
case '\n': // New line
// Count the line
line++;
// Add this to the key as a space.
// Spaces are not allowed, but it will be trimmed
// when its the first or last character.
key += " ";
break;
case '\\': // Possible comment
case '/':
// Backtrack to use previous character also
pos--;
// Check for the line comment //
if(data.Substring(pos, 2) == "//")
{
// Find the next line
int np = data.IndexOf("\n", pos);
// Next line found?
if(np > -1)
{
// Count the line
line++;
// Skip everything on this line
pos = np + 1;
}
else
{
// No end of line
// Skip everything else
pos = data.Length + 1;
}
}
// Check for the block comment /* */
else if(data.Substring(pos, 2) == "/*")
{
// Find the next closing block comment
int np = data.IndexOf("*/", pos);
// Closing block comment found?
if(np > -1)
{
// Count the lines in the block comment
string blockdata = data.Substring(pos, np - pos + 2);
line += (blockdata.Split("\n".ToCharArray()).Length - 1);
// Skip everything in this block
pos = np + 2;
}
else
{
// No end of line
// Skip everything else
pos = data.Length + 1;
}
}
else
{
// No whitespace
pos++;
}
break;
default: // Everything else
// Add character to key
key += c.ToString(CultureInfo.InvariantCulture);
break;
}
}
}