Mercurial > repos > RelicTools > RelicTools
view ChunkyValidator.cs @ 0:82db9430c2e4 default tip
Initial commit under GPLv3
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 06 Oct 2018 19:49:25 +0100 |
parents | |
children |
line wrap: on
line source
// This file is a part of the Relic Tools and is copyright 2006-2018 IBBoard. // // The file and the library/program it is in are licensed under the GNU GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. using System; using System.IO; using System.Collections; namespace IBBoard.Relic.RelicTools { /// <summary> /// Summary description for ChunkyValidator. /// </summary> public class ChunkyValidator { private class ValidatorToken { string tkn; int min, max; ValidatorToken[] children; public ValidatorToken(string token, int minOccurances, int maxOccurances, ValidatorToken[] childTokens) { tkn = token; min = minOccurances; max = maxOccurances; children = childTokens; } public ValidatorToken(string token, int minOccurances, int maxOccurances) :this(token, minOccurances, maxOccurances, new ValidatorToken[0]){} public ValidatorToken(string token, ValidatorToken[] childTokens):this(token, 1, 1, childTokens){} public ValidatorToken(string token):this(token, 1, 1){} public string Token { get{ return tkn; } } public int MinOccurances { get{ return min; } } public int MaxOccurances { get{ return max; } } public ValidatorToken[] SubTokens { get{ return children; } set{ children = value; } } } string type; ValidatorToken[] tokens; int part; public ChunkyValidator(FileInfo file) { type = file.Name.Substring(0, file.Name.IndexOf('.')).ToUpper(); StreamReader sr = file.OpenText(); //char[] chars = new char[file.Length]; char prev = ' '; string chars = sr.ReadLine(); while (chars!=null && chars.StartsWith("#")) { chars = sr.ReadLine(); } sr.Close(); if (chars == null) { throw new InvalidOperationException("Could not find validator string in file"); } chars = chars.Trim(); if (chars == "") { throw new InvalidOperationException("Could not find validator string in file"); } string temp = ""; int val = 0, min = -1, max = -1; ArrayList currTokens = new ArrayList(); Stack items = new Stack(); for (int i = 0; i<chars.Length; i++) { if (chars[i]==' ') { if (temp!="") { currTokens.Add(new ValidatorToken(temp, (min>-1?min:1), (max>-1?max:1))); } temp = ""; min = -1; max = -1; val = 0; } else if (chars[i]=='[') { currTokens.Add(new ValidatorToken(temp, (min>-1?min:1), (max>-1?max:1)));//create a token for a FOLD items.Push(currTokens);//store our current tokens currTokens = new ArrayList();//and clear the list temp = ""; } else if (chars[i]==']') { ValidatorToken[] childTokens = (ValidatorToken[])currTokens.ToArray(typeof(ValidatorToken)); currTokens = (ArrayList)items.Pop(); ((ValidatorToken)currTokens[currTokens.Count-1]).SubTokens = childTokens; temp = ""; } //else if (chars[i]=='(') //{ //min = 1; max = 1; //} else if (chars[i]==')') { if (min>-1) { max = (val > min ? val : min); } else { min = val; max = val; } } else if (Char.IsDigit(chars[i])) { if (prev=='(') { val = int.Parse(chars[i].ToString()); } else if (prev=='-') { min = val; val = int.Parse(chars[i].ToString()); } else if (Char.IsDigit(prev)) { val*=10; val+= int.Parse(chars[i].ToString()); } //else it's something it shouldn't be } else if (Char.IsLetter(chars[i])) { temp+=chars[i]; } prev = chars[i]; } if (prev!=']') { /* ValidatorToken[] childTokens = (ValidatorToken[])currTokens.ToArray(typeof(ValidatorToken)); currTokens = (ArrayList)items.Pop(); ((ValidatorToken)currTokens[currTokens.Count-1]).SubTokens = childTokens; } else {*/ currTokens.Add(new ValidatorToken(temp, (min>-1?min:1), (max>-1?max:1))); } tokens = (ValidatorToken[])currTokens.ToArray(typeof(ValidatorToken)); } public string FileType { get{ return type; } } public bool Validate(string validationString) { lock(this) { string[] parts = validationString.Split(' '); part = 0; int pos = 0; Stack layers = new Stack(); Stack layerPositions = new Stack(); try { while (pos < tokens.Length) { if (!validate(parts, tokens[pos])) { return false; } pos++; } } catch (IndexOutOfRangeException) { return false; } return true; } } private bool validate(string[] parts, ValidatorToken token) { int diff = 0; if (token.SubTokens.Length>0) { for (int j = 0; j<token.MinOccurances; j++) { if (parts[part]!=token.Token+"[") { return false; } part++; for (int k = 0; k<token.SubTokens.Length; k++) { if (!validate(parts, token.SubTokens[k])) { return false; } } if (parts[part]!="]") { return false; } part++; } diff = token.MaxOccurances - token.MinOccurances; for (int j = 0; j < diff; j++) { if (parts[part]!=token.Token+"[") { break; } part++; for (int k = 0; k<token.SubTokens.Length; k++) { if (!validate(parts, token.SubTokens[k])) { return false; } } if (parts[part]!="]") { return false; } part++; } if (part<parts.Length && parts[part]==token.Token) { return false; } } else { for (int j = 0; j<token.MinOccurances; j++) { if (parts[part]!=token.Token) { return false; } part++; } diff = token.MaxOccurances - token.MinOccurances; for (int j = 0; j < diff; j++) { if (parts[part]!=token.Token) { break; } else { part++; } } if (part<parts.Length && parts[part]==token.Token) { return false; } } return true; } } }