I have a little helper class that generates a script, used later in my code, namely :
public class ScriptBuilder
{
public string Script { get; set; }
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
Script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
Script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
Script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder setLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
// + other set functions with different parameters/numbers of parameters
}
// ScriptBuilder is used like this :
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = {scriptType}")
.WriteLine($"/! NAME = {name}")
.WriteLine($"/! DESCRIPTION = {description}")
.WriteLine($"/!HEADEND")
/* the header is done now */
.NewLine(2);
It is pretty basic method chaining. I would like to implement IF and IF ELSE IF ELSE in this scripting language, but I don't see a really neat way for doing it.
For the IF I came up with the member function :
public ScriptBuilder IF(bool condition, ScriptBuilder res)
{
if (condition)
{
return res;
}
else
{
return this;
}
}
that can be used as :
ScriptBuilder.IF(condition,
scriptStringBuilder
.setThis(...)
.setThat(...)
;
)
but I am not satisfied because
scriptStringBuilder.setThis(...).setThat(...); would alread have taken effect
I have to write scriptStringBuilder to use it. No pertinent idea of the IF ELSE IF ELSE though.
I could use delegates perhaps, like :
public delegate ScriptBuilder ScriptBuilderFunction(params object[] Parameters);
public ScriptBuilder IF(bool condition, ScriptBuilderFunction func)
{
// ...
}
but I don't even see how to implement that ...
Ideally, I would like to write :
scriptStringBuilder.
.setThis(...)
.setThat(...)
.IF(condition)
.THEN()
.setThis(...)
.doThat(...)
.ELSEIF(othercondition)
.makeThis(...)
.doThat(...)
.ENDIF()
.setThatNow(...)
;
This is a very rough sketch of how you could implement this:
class Program
{
static void Main(string[] args)
{
var number = 999;
ScriptBuilder scriptStringBuilder = new ScriptBuilder();
var text = scriptStringBuilder
.WriteLine($"/!HEADSTART")
.WriteLine($"/! TYPE = abc")
.WriteLine($"/! NAME = name")
.WriteLine($"/!HEADEND")
.NewLine(2)
.IfCondition(number != 999, ifCondition => {
ifCondition.NewLine(1);
ifCondition.WriteLine("SUCCESS");
}, elseCondition => {
elseCondition.NewLine(1);
elseCondition.WriteLine("FAIL");
},
elseIf1 => elseIf1.ElseIfCondition(number > 1, h1 => h1.WriteLine("NUMBER IS BIGGER THAN 1")),
elseIf2 => elseIf2.ElseIfCondition(number > 2, h2 => h2.WriteLine("NUMBER IS BIGGER THAN 2")))
.Build();
Console.WriteLine(text);
Console.ReadKey();
}
}
public class ScriptBuilder : IElseIfConditionable
{
private string _script;
public ScriptBuilder NewLine(uint numberOfLines = 1)
{
if (numberOfLines == 0)
{
return this;
}
else
{
for (int i = 1; i <= numberOfLines; ++i)
{
_script += Environment.NewLine;
}
return this;
}
}
public ScriptBuilder WriteLine(string str = "")
{
if (str != "")
{
_script += str;
NewLine();
}
return this;
}
public ScriptBuilder(string line = "")
{
_script = line;
if (line != "")
{
NewLine();
}
}
public ScriptBuilder SetLong(string longName, long x)
{
WriteLine("int " + longName + " " + x.ToString(System.Globalization.CultureInfo.InvariantCulture));
return this;
}
public string Build()
{
return _script;
}
public ScriptBuilder IfCondition(bool condition, Action<ScriptBuilder> trueCondition, Action<ScriptBuilder> falseCondition, params Func<IElseIfConditionable, Tuple<ScriptBuilder, bool>>[] elseIfs)
{
if (condition)
{
trueCondition(this);
return this;
}
foreach (var elseIf in elseIfs)
{
if (elseIf(this).Item2)
{
return this;
}
}
if (!condition)
{
falseCondition(this);
}
return this;
}
public Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition)
{
if (condition)
{
trueCondition(this);
}
return Tuple.Create(this, condition);
}
}
public interface IElseIfConditionable
{
Tuple<ScriptBuilder, bool> ElseIfCondition(bool condition, Action<ScriptBuilder> trueCondition);
}
This is equivalent of:
var s = new ScriptBuilder();
if (number != 999)
{
s.NewLine(1);
s.WriteLine("SUCCESS");
}
else if (number > 1)
{
s.WriteLine("NUMBER IS BIGGER THAN 1");
}
else if (number > 2)
{
s.WriteLine("NUMBER IS BIGGER THAN 2");
}
else
{
s.NewLine(1);
s.WriteLine("FAIL");
}
Related
I have a problem with Xamarin.Forms whereby the View is not refreshing as I would expect it to.
I have bound a View to a ViewModel, and I have a series of methods to perform various functions.
On the successful completion of a function, I want it to execute my LoadResults() method.
The LoadResults() method works fine when I load the view initially. However, when I execute any other method (DeleteScan(id) method shown below) it should re-fire the LoadResults() method and reload the page.
I know it is entering the LoadResults() method as I've put a break point in there and stepped through it. But by the end of it, it doesn't reload the view.
I also know the view can refresh, as I have other simple methods which are simply updating properties in the VM and those changes are reflecting in the UI.
So for whatever reason, LoadResults() is not reloading the page.
Any ideas what I've done wrong here?
View Model Constructor and Properties
public class ResultsProcessViewModel : INotifyPropertyChanged
{
public ICommand AddTimingCommand { get; set; }
public ICommand AddScanCommand { get; set; }
public ICommand InsertTimingCommand { get; set; }
public ICommand InsertScanCommand { get; set; }
public ICommand DeleteTimingCommand { get; set; }
public ICommand DeleteScanCommand { get; set; }
public ICommand PublishCommand { get; set; }
public ICommand LoadResultsCommand { get; set; }
public ICommand CancelMissingFinisherCommand { get; set; }
public ICommand CancelMissingTimingCommand { get; set; }
public int RaceId { get; set; }
public DateTime RaceDate { get; set; }
//public ResultsViewModel(Race race)
public ResultsProcessViewModel(Race race)
{
AddTimingCommand = new Command<string>(AddTiming);
InsertTimingCommand = new Command(InsertTiming);
AddScanCommand = new Command<string>(AddScan);
InsertScanCommand = new Command(InsertScan);
DeleteTimingCommand = new Command<int>(DeleteTiming);
DeleteScanCommand = new Command<int>(DeleteScan);
PublishCommand = new Command(Publish);
LoadResultsCommand = new Command<int>(LoadResults);
CancelMissingFinisherCommand = new Command(CancelMissingFinisher);
CancelMissingTimingCommand = new Command(CancelMissingTiming);
Invalid = false;
PublishStatus = race.ResultStatus;
Published = false;
PublishVisibility = false;
AddTimingVisibility = false;
AddScanVisibility = false;
AddVisibility = true;
IsBusy = false;
RaceId = race.Id;
RaceDate = race.RaceDate;
RaceStartTime = Convert.ToDateTime(race.RaceStartTime);
Scans = ScansAPI.GetScans(RaceId);
Timings = TimingsAPI.GetTimings(RaceId);
Entries = EntriesAPI.GetEntries(RaceId);
LoadResults(RaceId);
}
ObservableCollection<GroupedResultModel> _grouped;
public ObservableCollection<GroupedResultModel> grouped
{
get { return _grouped; }
set
{
if (_grouped == value)
return;
_grouped = value;
OnPropertyChanged("Grouped");
}
}
DateTime _raceStartTime;
public DateTime RaceStartTime
{
get { return _raceStartTime; }
set
{
if (_raceStartTime == value)
return;
_raceStartTime = value;
OnPropertyChanged("RaceStartTime");
}
}
int _timingPosition;
public int TimingPosition
{
get { return _timingPosition; }
set
{
if (_timingPosition == value)
return;
_timingPosition = value;
OnPropertyChanged("TimingPosition");
}
}
int _addScanTimingId;
public int AddScanTimingId
{
get { return _addScanTimingId; }
set
{
if (_addScanTimingId == value)
return;
_addScanTimingId = value;
OnPropertyChanged("AddScanTimingId");
}
}
int _addTimingScanId;
public int AddTimingScanId
{
get { return _addTimingScanId; }
set
{
if (_addTimingScanId == value)
return;
_addTimingScanId = value;
OnPropertyChanged("AddTimingScanId");
}
}
int _scanPosition;
public int ScanPosition
{
get { return _scanPosition; }
set
{
if (_scanPosition == value)
return;
_scanPosition = value;
OnPropertyChanged("ScanPosition");
}
}
bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
if (_isBusy == value)
return;
_isBusy = value;
OnPropertyChanged("IsBusy");
}
}
bool _published;
public bool Published
{
get { return _published; }
set
{
if (_published == value)
return;
_published = value;
OnPropertyChanged("Published");
}
}
bool _publishVisibility;
public bool PublishVisibility
{
get { return _publishVisibility; }
set
{
if (_publishVisibility == value)
return;
_publishVisibility = value;
OnPropertyChanged("PublishVisibility");
}
}
bool _error;
public bool Error
{
get { return _error; }
set
{
if (_error == value)
return;
_error = value;
OnPropertyChanged("Error");
}
}
bool _addVisibility;
public bool AddVisibility
{
get { return _addVisibility; }
set
{
if (_addVisibility == value)
return;
_addVisibility = value;
OnPropertyChanged("AddVisibility");
}
}
bool _addTimingVisibility;
public bool AddTimingVisibility
{
get { return _addTimingVisibility; }
set
{
if (_addTimingVisibility == value)
return;
_addTimingVisibility = value;
OnPropertyChanged("AddTimingVisibility");
}
}
bool _addScanVisibility;
public bool AddScanVisibility
{
get { return _addScanVisibility; }
set
{
if (_addScanVisibility == value)
return;
_addScanVisibility = value;
OnPropertyChanged("AddScanVisibility");
}
}
ObservableCollection<Result> _results;
public ObservableCollection<Result> Results
{
get
{
return _results;
}
set
{
if (_results != value)
{
_results = value;
OnPropertyChanged("Results");
}
}
}
ObservableCollection<Scan> _scans;
public ObservableCollection<Scan> Scans
{
get
{
return _scans;
}
set
{
if (_scans != value)
{
_scans = value;
OnPropertyChanged("Scans");
}
}
}
ObservableCollection<Timing> _timings;
public ObservableCollection<Timing> Timings
{
get
{
return _timings;
}
set
{
if (_timings != value)
{
_timings = value;
OnPropertyChanged("Timings");
}
}
}
ObservableCollection<RaceEntry> _entries;
public ObservableCollection<RaceEntry> Entries
{
get
{
return _entries;
}
set
{
if (_entries != value)
{
_entries = value;
OnPropertyChanged("Entries");
}
}
}
bool _invalid;
public bool Invalid
{
get { return _invalid; }
set
{
if (_invalid == value)
return;
_invalid = value;
OnPropertyChanged("Invalid");
}
}
bool _resultsInvalid;
public bool ResultsInvalid
{
get { return _resultsInvalid; }
set
{
if (_resultsInvalid == value)
return;
_resultsInvalid = value;
OnPropertyChanged("ResultsInvalid");
}
}
bool _insertScanVisibility;
public bool InsertScanVisibility
{
get { return _insertScanVisibility; }
set
{
if (_insertScanVisibility == value)
return;
_insertScanVisibility = value;
OnPropertyChanged("InsertScanVisibility");
}
}
string _validationError;
public string ValidationError
{
get { return _validationError; }
set
{
if (_validationError == value)
return;
_validationError = value;
OnPropertyChanged("ValidationError");
}
}
string _resultsValidationError;
public string ResultsValidationError
{
get { return _resultsValidationError; }
set
{
if (_resultsValidationError == value)
return;
_resultsValidationError = value;
OnPropertyChanged("ResultsValidationError");
}
}
string _missingBib;
public string MissingBib
{
get { return _missingBib; }
set
{
if (_missingBib == value)
return;
_missingBib = value;
OnPropertyChanged("MissingBib");
}
}
string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set
{
if (_errorMessage == value)
return;
_errorMessage = value;
OnPropertyChanged("ErrorMessage");
}
}
public Race SelectedRace { get; set; }
private bool _raceCountZero;
public bool RaceCountZero
{
get { return _raceCountZero; }
set
{
if (_raceCountZero == value)
return;
_raceCountZero = value;
OnPropertyChanged("RaceCountZero");
}
}
string _aboveBelow;
public string AboveBelow
{
get { return _aboveBelow; }
set
{
if (_aboveBelow == value)
return;
_aboveBelow = value;
OnPropertyChanged("AboveBelow");
}
}
string _aboveBelowPosition;
public string AboveBelowPosition
{
get { return _aboveBelowPosition; }
set
{
if (_aboveBelowPosition == value)
return;
_aboveBelowPosition = value;
OnPropertyChanged("AboveBelowPosition");
}
}
string _publishStatus;
public string PublishStatus
{
get { return _publishStatus; }
set
{
if (_publishStatus == value)
return;
_publishStatus = value;
OnPropertyChanged("PublishStatus");
}
}
string _newBatchCode;
public string NewBatchCode
{
get { return _newBatchCode; }
set
{
if (_newBatchCode == value)
return;
_newBatchCode = value;
OnPropertyChanged("NewBatchCode");
}
}
string _addHH;
public string AddHH
{
get { return _addHH; }
set
{
if (_addHH == value)
return;
_addHH = value;
OnPropertyChanged("AddHH");
}
}
string _addMM;
public string AddMM
{
get { return _addMM; }
set
{
if (_addMM == value)
return;
_addMM = value;
OnPropertyChanged("AddMM");
}
}
string _addSS;
public string AddSS
{
get { return _addSS; }
set
{
if (_addSS == value)
return;
_addSS = value;
OnPropertyChanged("AddSS");
}
}
string _scanBatchCode;
public string ScanBatchCode
{
get { return _scanBatchCode; }
set
{
if (_scanBatchCode == value)
return;
_scanBatchCode = value;
OnPropertyChanged("ScanBatchCode");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
DeleteScan method
void DeleteScan(int scanid)
{
//Do stuff when deleting a scan. It needs to do all this in the observable collection. Then when we submit, we'll update all scans, timings etc with whats in the collection
Task.Run(() =>
{
try
{
Device.BeginInvokeOnMainThread(() => IsBusy = true);
var IsThereConnection = GlobalFunctions.CheckForInternetConnection();
if (IsThereConnection == false)
throw new Exception("You cannot delete a scan whilst you are offline");
//We are good to go
else
{
var deletescan = ScansAPI.DeleteScan(scanid);
if (deletescan.Code != "NoContent")
throw new Exception("Error deleting scan");
}
}
catch (Exception ex)
{
Device.BeginInvokeOnMainThread(() =>
{
ValidationError = ex.Message;
Invalid = true;
});
return;
}
finally
{
var newscans = ScansAPI.GetScans(RaceId);
var sortednewscans = new ObservableCollection<Scan>(newscans.OrderBy(c => c.Position));
Scans = sortednewscans;
Device.BeginInvokeOnMainThread(() => Published = false);
Device.BeginInvokeOnMainThread(() => LoadResults(RaceId));
Device.BeginInvokeOnMainThread(() => AddScanVisibility = false);
Device.BeginInvokeOnMainThread(() => IsBusy = false);
}
});
}
LoadResults Method
void LoadResults(int raceid)
{
var results = new ObservableCollection<Result>();
//Start with the timings
foreach (Timing timing in Timings)
{
var result = new Result();
//Basic details
result.RaceId = RaceId;
result.RaceDate = RaceDate;
result.Status = "Processing";
result.BackgroundColour = "White";
result.ScanTrashVisibility = true;
result.TimingTrashVisibility = true;
//Timing Data
result.TimingId = timing.Id;
result.TimingPosition = timing.Position;
result.TimingStatus = timing.Status;
result.StartTime = timing.StartTime;
result.EndTime = timing.EndTime;
result.TimingBatchCode = timing.BatchCode;
result.TimingBatchPosition = timing.BatchCode + timing.Position.ToString();
var elapsed = result.EndTime - result.StartTime;
string elapsedhours = elapsed.Hours.ToString();
string elapsedminutes = elapsed.Minutes.ToString();
string elapsedseconds = elapsed.Seconds.ToString();
string elapsedmillis;
if (elapsed.Milliseconds.ToString().Length > 2)
{
elapsedmillis = elapsed.Milliseconds.ToString().Substring(0, 2);
}
else
{
elapsedmillis = elapsed.Milliseconds.ToString();
}
if (elapsedhours.Length == 1) { elapsedhours = "0" + elapsedhours; }
if (elapsedminutes.Length == 1) { elapsedminutes = "0" + elapsedminutes; }
if (elapsedseconds.Length == 1) { elapsedseconds = "0" + elapsedseconds; }
if (elapsedmillis.Length == 1) { elapsedmillis = "0" + elapsedmillis; }
if((elapsedhours == "00"))
{
result.Elapsed = elapsedminutes + ":" + elapsedseconds + "." + elapsedmillis;
}
else
{
result.Elapsed = elapsedhours + ":" + elapsedminutes + ":" + elapsedseconds + "." + elapsedmillis;
}
results.Add(result);
}
//Add in the scans
foreach (Result result1 in results)
{
var scan = Scans.Where(p => p.BatchCode == result1.TimingBatchCode)
.FirstOrDefault(p => p.Position == result1.TimingPosition);
if (scan != null)
{
result1.ScanId = scan.Id;
result1.ScanPosition = scan.Position;
result1.ScanStatus = scan.Status;
result1.ScanBibNumber = scan.BibNumber;
result1.ScanBatchCode = scan.BatchCode;
result1.ScanBatchPosition = scan.BatchCode + scan.Position.ToString();
}
else
{
result1.ScanId = 0;
result1.ScanPosition = 0;
result1.ScanStatus = 99;
result1.ScanBibNumber = "UNKNOWN";
result1.AddScanButtonVisibility = true;
result1.ScanBatchCode = result1.TimingBatchCode;
}
}
//Add any scans which there are no times for
var notimescans = new ObservableCollection<Scan>();
foreach (Scan scan in Scans)
{
var checkscan = results.FirstOrDefault(s => s.ScanId == scan.Id);
if (checkscan == null)
{
var newresult = new Result();
newresult.RaceId = RaceId;
newresult.RaceDate = RaceDate;
newresult.Status = "Processing";
newresult.ScanId = scan.Id;
newresult.ScanPosition = scan.Position;
newresult.ScanStatus = scan.Status;
newresult.ScanBibNumber = scan.BibNumber;
newresult.ScanBatchCode = scan.BatchCode;
newresult.ScanBatchPosition = scan.BatchCode + scan.Position.ToString();
newresult.ScanTrashVisibility = true;
newresult.AddTimingButtonVisibility = true;
newresult.TimingId = 0;
newresult.TimingPosition = 99999;
newresult.TimingStatus = 99;
newresult.Elapsed = "N/A";
results.Add(newresult);
}
}
//Then add in the entries
foreach (Result result2 in results)
{
var entry = Entries.FirstOrDefault(p => p.BibNumber == result2.ScanBibNumber);
if (entry != null)
{
result2.EntryId = entry.Id;
result2.FirstName = entry.FirstName;
result2.LastName = entry.LastName;
result2.FormattedName = entry.FirstName + " " + entry.LastName.ToUpper();
result2.Gender = entry.Gender;
result2.DateOfBirth = entry.DateOfBirth;
result2.Club = entry.Club;
result2.Team = entry.Team;
result2.EntryBibNumber = entry.BibNumber;
if (result2.Club == null)
{
result2.FormattedClub = "";
}
else
{
result2.FormattedClub = entry.Club.ToUpper();
}
}
else
{
result2.EntryId = 0;
result2.FirstName = "Unknown";
result2.LastName = "ATHLETE";
result2.FormattedName = entry.FirstName + " " + entry.LastName.ToUpper();
result2.Gender = "Unknown";
result2.DateOfBirth = DateTime.Now;
result2.Club = "";
result2.Team = "";
result2.EntryBibNumber = result2.ScanBibNumber + " (Unrecognised)";
}
if(result2.ScanBatchCode == "NULLBATCH")
{
result2.ScanBatchCode = "Default";
}
if (result2.TimingBatchCode == "NULLBATCH")
{
result2.TimingBatchCode = "Default";
}
}
if(Scans.Count() != Timings.Count())
{
ResultsInvalid = true;
ResultsValidationError = "Your scan count and timing count's don't match. Please continue processing your results until these match and you will then be able to publish.";
}
else
{
Invalid = false;
PublishVisibility = true;
}
var sortedresults = new ObservableCollection<Result>(results.OrderBy(c => c.Elapsed));
int newposition = 1;
foreach (Result sortedresult in sortedresults)
{
sortedresult.OverallPosition = newposition;
newposition = newposition + 1;
}
//Create batches
grouped = new ObservableCollection<GroupedResultModel>();
foreach (Result result in results)
{
GroupedResultModel resultGroup = new GroupedResultModel();
var groupcheck = grouped.FirstOrDefault(b => b.BatchCode == result.ScanBatchCode);
if (groupcheck == null)
{
resultGroup.BatchCode = result.ScanBatchCode;
var BatchOfResults = results.Where(r => r.ScanBatchCode == resultGroup.BatchCode).OrderBy(r => r.Elapsed);
int batchposition = 1;
foreach (Result batchedresult in BatchOfResults)
{
batchedresult.OverallPosition = batchposition;
resultGroup.Add(batchedresult);
batchposition = batchposition + 1;
}
grouped.Add(resultGroup);
}
}
Results = sortedresults;
OnPropertyChanged("Invalid");
}
I wrote a piece of code to run from the first IP address to the last and retrieve the MAC and Hostname of devices in my network.
But, i do not know how to get the hierachy of then. Information like what router is the device conected (via Cable of WiFi also). And some routers are not managed (they don't have IP - they are just "switchs").
First, i didn't think it was possible, since a "tracert" on the CMD does not show then, but when i call the "Network Complete Map" on Windows Control Panel, they get all the information i need - so there is a way. See the image below:
The "switchs" circled in red have no IP, the "TL-xxxx" are routers with DHCP turned of. The "gateway" is a server that has the DHCP and provides connection to the internet.
Thus far, i wrote the following code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Net;
using System.Runtime.InteropServices;
namespace Network
{
[Serializable] public sealed class Map
{
private bool mMARKED = true;
private long mDB = 0L;
private string mIP = string.Empty;
private string mMAC = string.Empty;
private string mBRAND = string.Empty;
private string mNAME = string.Empty;
public bool Save { get { return this.mMARKED; } set { this.mMARKED = value; } }
public long DBId { get { return this.mDB; } set { this.mDB = value; } }
public string IP { get { return this.mIP; } set { this.mIP = value; } }
public string MAC { get { return this.mMAC; } set { this.mMAC = value; } }
public string BRAND { get { return this.mBRAND; } set { this.mBRAND = value; } }
public string NAME { get { return this.mNAME; } set { this.mNAME = value; } }
}
[Serializable] public sealed class Scanner
{
public const string WebOUIFile = "http://standards-oui.ieee.org/oui.txt";
public const string LocalOUIFileName = "oui.txt";
private const long MaxOUIAge = (TimeSpan.TicksPerDay * 90L);
internal Dictionary<string, string> OUIList;
private List<Map> mDevices = new List<Map>(50);
public List<Map> Devices { get { return this.mDevices; } }
public static Scanner Scan;
public Thread Worker;
public bool AutoSave { get; set; }
private string Node;
private byte mInitial;
public static string UploadPath { get; set; }
public byte Initial { get { return this.mInitial; } set { this.mInitial = value; } }
public byte Current { get; private set; }
public byte Limit { get; set; }
public bool Working { get; private set; }
public string Errors;
public string Message { get; private set; }
public bool UpdatingOUI { get; private set; }
public void Interrupt()
{
this.Working = false;
if (this.Worker != null)
{
this.Worker.Abort();
this.Worker = null;
}
this.Node = string.Empty;
this.Initial = 0;
this.Current = 0;
this.Limit = 0;
this.Working = false;
}
public void ToDestroy()
{
this.Interrupt();
this.Errors = string.Empty;
this.Message = string.Empty;
}
public void Stop(bool immediate) { if (immediate) { this.Interrupt(); } }
[DllImport("iphlpapi.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int SendARP(int DestIP, int SrcIP, out long pMacAddr, ref int PhyAddrLen);
public void ToBegin() { }
public void Stop() { this.Stop(true); }
private static int IPToInt(string Expression)
{
try
{
byte[] IPAddress = System.Net.IPAddress.Parse(Expression).GetAddressBytes();
return (Convert.ToInt32(IPAddress[3]) << 24) | (Convert.ToInt32(IPAddress[2]) << 16) | (Convert.ToInt32(IPAddress[1]) << 8) | Convert.ToInt32(IPAddress[0]);
} catch { return 0; }
}
private Map GetBasics(string IPString)
{
int res = Scanner.IPToInt(IPString);
if (res > 0)
{
long mem = 0L;
int PhyAddrLen = 6;
if (Scanner.SendARP(res, 0, out mem, ref PhyAddrLen) == 0)
{
Map dev = new Map();
byte[] macbytes = BitConverter.GetBytes(mem);
dev.IP = IPString;
string Tmp = BitConverter.ToString(macbytes, 0, 3);
if (this.OUIList != null && this.OUIList.ContainsKey(Tmp)) { dev.BRAND = this.OUIList[Tmp]; }
dev.MAC = Tmp + "-" + BitConverter.ToString(macbytes, 3, 3);
try { dev.NAME = Dns.GetHostEntry(IPString).HostName.ToLower(); } catch { dev.NAME = "unknow"; }
return dev;
}
}
return null;
}
private static void GetNode(ref string IP, ref string Node, ref byte Device)
{
string[] NodeComp = IP.Split('.');
Node = NodeComp[0] + "." + NodeComp[1] + "." + NodeComp[2] + ".";
Device = Convert.ToByte(NodeComp[3]);
}
public static Dictionary<string, string> DonwloadOUTFile(bool ForceUpdate = true)
{
Dictionary<string, string> List = null;
try
{
string Aux = Scanner.UploadPath;
if (Aux == null) { Aux = string.Empty; }
else if (Aux != string.Empty)
{
string Tmp = Aux + "~" + Scanner.LocalOUIFileName;
Aux += Scanner.LocalOUIFileName;
bool FileExists = File.Exists(Aux);
if (FileExists && ((DateTime.UtcNow.Ticks - (new FileInfo(Aux)).CreationTimeUtc.Ticks) > Scanner.MaxOUIAge))
{
File.Delete(Aux);
ForceUpdate = true;
}
string Aux2 = string.Empty;
if (ForceUpdate)
{
List = new Dictionary<string, string>(25000);
using (WebClient Downloader = new WebClient()) { Downloader.DownloadFile(Scanner.WebOUIFile, Tmp); }
using (StreamReader Reader = new StreamReader(Tmp))
using (StreamWriter Writer = new StreamWriter(Aux))
{
do
{
Aux = Reader.ReadLine();
if (Aux.ToLower().Contains("(hex)"))
{
Aux2 = Aux.Substring(0, 8).ToUpper();
Aux = Aux.Substring(Aux.LastIndexOf('\t') + 1);
if (!List.ContainsKey(Aux2))
{
List.Add(Aux2, Aux);
Writer.WriteLine(Aux2 + "\t" + Aux);
}
}
} while (Reader.Peek() >= 0);
Reader.Close();
Writer.Close();
}
try { File.Delete(Tmp); } catch { /* NOTHING */ }
}
else if (FileExists)
{
List = new Dictionary<string, string>(25000);
using (StreamReader Reader = new StreamReader(Aux))
{
do
{
Aux = Reader.ReadLine();
if (Aux != null && Aux.Length > 9)
{
Aux2 = Aux.Substring(0, 8);
if (!List.ContainsKey(Aux2)) { List.Add(Aux2, Aux.Substring(9)); }
}
} while (Reader.Peek() >= 0);
Reader.Close();
}
}
}
}
catch
{
if (List != null) { List.Clear(); }
List = null;
}
return List;
}
private void ReadScaner()
{
this.UpdatingOUI = true;
try { this.OUIList = Scanner.DonwloadOUTFile(ForceUpdate: false); } catch { /* NOTHING */ }
this.UpdatingOUI = false;
if (this.OUIList == null || this.OUIList.Count == 0) { this.Errors += "\nErrorOUIFileDownload"; }
Map Dev = null;
this.Current = this.Initial;
if (this.Limit < this.Initial)
{
Dev = this.GetBasics(this.Node + this.Initial.ToString());
if (Dev != null) { this.Devices.Add(Dev); }
}
else
{
bool ToAdd = true;
while (this.Current <= this.Limit)
{
Dev = this.GetBasics(this.Node + this.Current.ToString());
this.Current += 1;
if (Dev != null)
{
ToAdd = true;
foreach (Map iDev in this.Devices)
{
if (iDev.MAC == Dev.MAC)
{
ToAdd = false;
break;
}
}
if (ToAdd) { this.Devices.Add(Dev); }
}
}
}
this.Message = "Finished!";
this.Interrupt();
}
public void GetRange(string IPInitial, byte Limit, bool AutoSave = true)
{
if (!this.Working)
{
this.AutoSave = AutoSave;
this.Working = true;
Scanner.GetNode(ref IPInitial, ref this.Node, ref this.mInitial);
this.Limit = Limit;
this.Worker = new Thread(this.ReadScaner);
this.Worker.IsBackground = true;
this.ToBegin();
this.Worker.Start();
}
}
public static void GetRange(bool AutoSave, string IPInitial, byte Limit)
{
if (Scanner.Scan == null)
{
Scanner.Scan = new Scanner();
Scanner.Scan.GetRange(IPInitial, Limit, AutoSave: AutoSave);
}
}
~Scanner()
{
if (this.OUIList != null)
{
this.OUIList.Clear();
this.OUIList = null;
}
}
}
}
How do i make that code able to get the hierarchy like windows does?
I am using https://courses.cs.washington.edu/courses/cse326/07su/prj2/kruskal.html psuedocode as reference when writing my code.
Code is in C#, and my code can only generate mazes up to 11x11, anything more than than it will run, seemingly, forever (e.g. 12x11 or 12x12 won't work)
Grid Properties are just storing the dimension of the size of the maze
public class GridProperties
{
private int xLength;
private int yLength;
public GridProperties(int xlength, int ylength)
{
xLength = xlength;
yLength = ylength;
}
public int getXLength()
{
return this.xLength;
}
public int getYLength()
{
return this.yLength;
}
}
Cell Properties generates the grid
public class CellProperties
{
private GridProperties Grid;
private bool topWall, bottomWall, rightWall, leftWall;
private int? xCoord, yCoord;
private CellProperties topCell, bottomCell, rightCell, leftCell;
private CellProperties topParentCell, bottomParentCell, rightParentCell, leftParentCell;
private HashSet<String> passageID = new HashSet<String>();
public CellProperties(GridProperties grid = null, int? targetXCoord = null, int? targetYCoord = null,
CellProperties tpCell = null, CellProperties bpCell = null,
CellProperties rpCell = null, CellProperties lpCell = null)
{
this.Grid = grid;
this.xCoord = targetXCoord;
this.yCoord = targetYCoord;
this.updatePassageID(this.xCoord.ToString() + this.yCoord.ToString());
this.topWall = true;
this.bottomWall = true;
this.rightWall = true;
this.leftWall = true;
this.topParentCell = tpCell;
this.bottomParentCell = bpCell;
this.rightParentCell = rpCell;
this.leftParentCell = lpCell;
this.topCell = this.setTopCell();
this.bottomCell = this.setBottomCell();
if (this.yCoord == 0)
{
this.rightCell = this.setRightCell();
}
this.leftCell = this.setLeftCell();
}
public CellProperties setTopCell()
{
if (this.Grid == null)
{
return null;
}
if (this.yCoord == this.Grid.getYLength() - 1)
{
return new CellProperties();
}
else
{
return new CellProperties(this.Grid, this.xCoord, this.yCoord + 1, null, this, null, null);
}
}
public CellProperties setBottomCell()
{
if (this.yCoord == 0)
{
return new CellProperties();
}
else
{
return this.bottomParentCell;
}
}
public CellProperties setRightCell()
{
if (this.Grid == null)
{
return null;
}
if (this.xCoord == this.Grid.getXLength() - 1)
{
return new CellProperties();
}
else
{
return new CellProperties(this.Grid, this.xCoord + 1, this.yCoord, null, null, null, this);
}
}
public CellProperties setLeftCell( )
{
if (this.xCoord == 0)
{
return new CellProperties();
}
else
{
if (this.Grid == null)
{
return null;
}
if (this.yCoord == 0)
{
return this.leftParentCell;
}
else
{
CellProperties buffer = this.bottomCell;
for (int depth = 0; depth < this.yCoord - 1; depth++)
{
buffer = buffer.bottomParentCell;
}
buffer = buffer.leftParentCell.topCell;
for (int depth = 0; depth < this.yCoord - 1; depth++)
{
buffer = buffer.topCell;
}
buffer.rightCell = this;
return buffer;
}
}
}
public GridProperties getGrid()
{
return this.Grid;
}
public CellProperties getBottomCell()
{
return this.bottomCell;
}
public CellProperties getTopCell()
{
return this.topCell;
}
public CellProperties getLeftCell()
{
return this.leftCell;
}
public CellProperties getRightCell()
{
return this.rightCell;
}
public void setBottomWall(Boolean newBottomWall)
{
this.bottomWall = newBottomWall;
}
public void setTopWall(Boolean newTopWall)
{
this.topWall = newTopWall;
}
public void setLeftWall(Boolean newLeftWall)
{
this.leftWall = newLeftWall;
}
public void setRightWall(Boolean newRightWall)
{
this.rightWall = newRightWall;
}
public Boolean getBottomWall()
{
return this.bottomWall;
}
public Boolean getTopWall()
{
return this.topWall;
}
public Boolean getLeftWall()
{
return this.leftWall;
}
public Boolean getRightWall()
{
return this.rightWall;
}
public void updatePassageID(String newPassageID)
{
this.passageID.Add(newPassageID);
}
public void setPassageID(HashSet<String> newPassageID)
{
this.passageID = new HashSet<string>(newPassageID);
}
public HashSet<String> getPassageID()
{
return this.passageID;
}
}
This class is where the magic happens ... or suppose to happen.
public class KruskalMazeGenerator
{
private CellProperties Cell0x0;
private CellProperties CurrentCell;
private CellProperties NeighbourCell;
private int WallsDown;
private int TotalNumberOfCells;
private Random rnd = new Random();
private int rndXCoord, rndYCoord;
private String rndSide;
public KruskalMazeGenerator(CellProperties cell0x0)
{
Cell0x0 = cell0x0;
WallsDown = 0;
TotalNumberOfCells = Cell0x0.getGrid().getXLength() * Cell0x0.getGrid().getYLength();
}
public void selectRandomCellCoords()
{
this.rndXCoord = rnd.Next(0, this.Cell0x0.getGrid().getXLength());
this.rndYCoord = rnd.Next(0, this.Cell0x0.getGrid().getYLength());
}
public void selectRandomSide(String[] possibleSides)
{
if (possibleSides.Length != 0)
{
this.rndSide = possibleSides[rnd.Next(0, possibleSides.Length)];
}
}
public void selectRandomCurrentCell()
{
this.selectRandomCellCoords();
this.CurrentCell = this.Cell0x0;
for (int xWalk = 0; xWalk < this.rndXCoord; xWalk++)
{
this.CurrentCell = this.CurrentCell.getRightCell();
}
for (int xWalk = 0; xWalk < this.rndYCoord; xWalk++)
{
this.CurrentCell = this.CurrentCell.getTopCell();
}
}
public CellProperties checkWallBetweenCurrentAndNeighbour(List<String> possibleSides)
{
if (this.rndSide == "top")
{
if (this.CurrentCell.getTopCell() == null || this.CurrentCell.getTopCell().getGrid() == null)
{
possibleSides.Remove("top");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getTopCell();
}
else if (this.rndSide == "bottom")
{
if (this.CurrentCell.getBottomCell() == null || this.CurrentCell.getBottomCell().getGrid() == null)
{
possibleSides.Remove("bottom");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getBottomCell();
}
else if (this.rndSide == "left")
{
if (this.CurrentCell.getLeftCell() == null || this.CurrentCell.getLeftCell().getGrid() == null)
{
possibleSides.Remove("left");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getLeftCell();
}
else if (this.rndSide == "right")
{
if (this.CurrentCell.getRightCell() == null || this.CurrentCell.getRightCell().getGrid() == null)
{
possibleSides.Remove("right");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getRightCell();
}
return null;
}
public void selectRandomNeigbhourCell()
{
this.selectRandomSide(new String[4] { "top", "bottom", "left", "right" });
this.NeighbourCell = this.checkWallBetweenCurrentAndNeighbour(new List<String>(new String[4] { "top", "bottom", "left", "right" }));
}
public void checkForDifferentPassageID()
{
if (!this.CurrentCell.getPassageID().SetEquals(this.NeighbourCell.getPassageID()))
{
if (this.rndSide == "top")
{
this.CurrentCell.setTopWall(false);
this.NeighbourCell.setBottomWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "bottom")
{
this.CurrentCell.setBottomWall(false);
this.NeighbourCell.setTopWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "left")
{
this.CurrentCell.setLeftWall(false);
this.NeighbourCell.setRightWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "right")
{
this.CurrentCell.setRightWall(false);
this.NeighbourCell.setLeftWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
}
}
public void unionAndResetPassageID()
{
HashSet<String> oldCurrentPassageID = new HashSet<String>(this.CurrentCell.getPassageID());
HashSet<String> oldNeighbourPassageID = new HashSet<String>(this.NeighbourCell.getPassageID());
HashSet <String> newPassageID = new HashSet<String>();
newPassageID = this.CurrentCell.getPassageID();
newPassageID.UnionWith(this.NeighbourCell.getPassageID());
CellProperties xwalkCell = new CellProperties();
CellProperties ywalkCell = new CellProperties();
for (int xWalk = 0; xWalk < this.Cell0x0.getGrid().getXLength(); xWalk++)
{
xwalkCell = xWalk == 0 ? this.Cell0x0 : xwalkCell.getRightCell();
for (int yWalk = 0; yWalk < this.Cell0x0.getGrid().getYLength(); yWalk++)
{
xwalkCell.setBottomWall(xWalk == 0 && yWalk == 0 ? false : xwalkCell.getBottomWall());
xwalkCell.setBottomWall(xWalk == this.Cell0x0.getGrid().getXLength() - 1 && yWalk == this.Cell0x0.getGrid().getYLength() - 1 ? false : xwalkCell.getBottomWall());
ywalkCell = yWalk == 0 ? xwalkCell : ywalkCell.getTopCell();
if (ywalkCell.getPassageID().SetEquals(oldCurrentPassageID) ||
ywalkCell.getPassageID().SetEquals(oldNeighbourPassageID))
{
ywalkCell.setPassageID(newPassageID);
}
}
}
}
public CellProperties createMaze()
{
while (this.WallsDown < this.TotalNumberOfCells - 1)
{
this.selectRandomCurrentCell();
this.selectRandomNeigbhourCell();
if (this.NeighbourCell != null)
{
this.checkForDifferentPassageID();
}
}
return this.Cell0x0;
}
}
then this is my visual representation class
public class drawGrid : CellProperties
{
private CellProperties Cell0x0 = new CellProperties();
private CellProperties yWalkBuffer = new CellProperties();
private CellProperties xWalkBuffer = new CellProperties();
private String bottomWall = "";
private String topWall = "";
private String leftAndrightWalls = "";
public drawGrid(CellProperties cell0x0)
{
Cell0x0 = cell0x0;
}
private void WallDrawingReset()
{
this.bottomWall = "\n";
this.topWall = "\n";
this.leftAndrightWalls = "\n";
}
private void Draw()
{
// draw bottom wall
{
if (this.bottomWall == "\n")
{
Console.Write("");
}
else
{
Console.Write(this.bottomWall);
}
}
Console.Write(this.leftAndrightWalls);
// draw top wall
{
if (topWall == "\n")
{
Console.Write("");
}
else
{
Console.Write(this.topWall);
}
}
}
public void yWalk()
{
for (int yWalk = 0; yWalk < this.Cell0x0.getGrid().getYLength(); yWalk++)
{
this.yWalkBuffer = yWalk == 0 ? this.Cell0x0 : this.yWalkBuffer.getTopCell();
this.WallDrawingReset();
this.xWalk(yWalk);
this.Draw();
}
}
private void xWalk(int yWalk)
{
for (int xWalk = 0; xWalk < this.Cell0x0.getGrid().getXLength(); xWalk++)
{
this.xWalkBuffer = xWalk == 0 ? this.yWalkBuffer : this.xWalkBuffer.getRightCell();
if (yWalk == 0)
{
this.bottomWall = xWalkBuffer.getBottomWall() ? this.bottomWall + "----" : this.bottomWall + " ";
this.topWall = xWalkBuffer.getTopWall() ? this.topWall + "----" : this.topWall + " ";
}
else
{
this.topWall = this.xWalkBuffer.getTopWall() ? this.topWall + "----" : this.topWall + " ";
}
if (xWalk == 0)
{
leftAndrightWalls = this.xWalkBuffer.getLeftWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
leftAndrightWalls = this.xWalkBuffer.getRightWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
}
else
{
leftAndrightWalls = this.xWalkBuffer.getRightWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
}
}
}
}
this is how i call them
class Program
{
static void Main(string[] args)
{
{
CellProperties cell = new CellProperties(new GridProperties(12, 11), 0, 0, null, null, null, null);
drawGrid draw = new drawGrid(cell);
draw.yWalk();
KruskalMazeGenerator kmaze = new KruskalMazeGenerator(cell);
cell = kmaze.createMaze();
Console.WriteLine("Final");
draw = new drawGrid(cell);
draw.yWalk();
}
Console.ReadKey();
}
}
Since I got you guys here, please don't mind pitching in what I can improve on as in coding style and other things that you are displeased with.
Thanks in advance.
Error seems to be here:
this.updatePassageID(this.xCoord.ToString() + this.yCoord.ToString());
Image those two scenarios:
xCoord = 1 and yCoord = 11.
xCoord = 11 and yCoord = 1.
both those result in newPassageID of 111.
So simply change the line to
this.updatePassageID(this.xCoord.ToString() + "|" + this.yCoord.ToString());
or written more sexy:
this.updatePassageID($"{xCoord}|{yCoord}");
With this you will receive
1|11 for the first scenario and 11|1 for the second which differs.
Edit based on comments:
I saw that your code is looping endlessly in the method createMaze. This method calls a method called checkForDifferentPassageID in there you check if two collections are equal or not. Once I saw that those collections are of type HashSet<string>, I thought that maybe your strings you put into the HashSet arent as unique as you think they are and there we go. So overall it took me like 10 minutes.
UPDATE
I don´t want you to do my Work and write code for me I just wanted a nurge in the right Direction!
So I have to be more specific with my Problem, give me a chance to do some work on this and I will update my question with the results ;-)
UPDATE 2
I´ve solved my Problem with Roslyn maybe not very elegant but it work for my needs, here is the code ;-)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
namespace ParserTest
{
public class MyParser
{
private int _currentLevel = 1;
public void TestMethod()
{
string testString =
#" if(#ISEMPTY(temp.tis_filterstatus2))
{
tis_datasheet_selection.is_selected = 'Y'
}
else
{
if(#ISEMPTY(temp.tis_programmtyp_filter)) { }
else
{
AND tis_programme_v.type = '#SUB(temp.tis_programmtyp_filter)'
}
if(#ISEMPTY(temp.tis_programmfilter)) { }
else
{
AND tis_programme_v.programm LIKE '#SUB(temp.tis_programmfilter)%'
}";
var result = this.Parse(testString);
var finalResult = this.GenerateDsl(result);
}
public List<IfStatement> Parse(string strToParse)
{
var result = new List<IfStatement>();
var syntaxTree = SyntaxTree.ParseText(#"using System;class C{static void M(){" + strToParse + "}}");
var rootNodes = syntaxTree.GetRoot().DescendantNodes().Where(getRootNodes);
result = rootNodes.Select(n => ToIfStatement(n, null)).ToList();
ApplyNestingLevel(result);
return result;
}
private string GenerateDsl(List<IfStatement> list)
{
var sb = new StringBuilder();
foreach(var ifStmt in list)
{
IfStatementToDsl(ifStmt, sb);
}
return sb.ToString();
}
private string IfStatementToDsl(IfStatement ifStmt, StringBuilder sb)
{
string sqr = "";
for (int i = 0; i < ifStmt.Level; i++)
{
sqr += "'";
}
sb.Append("#IF(");
sb.Append(ifStmt.Condition.ApplyLevel(ifStmt.Level) + "," + sqr);
sb.Append(ifStmt.Statement.ApplyLevel(ifStmt.Level));
if(ifStmt.Childs.Count > 0)
{
foreach(var c in ifStmt.Childs)
{
IfStatementToDsl(c, sb);
}
}
sb.Append(sqr + "," + sqr);
if(ifStmt.Else != null)
{
sb.Append(ifStmt.Else.Statement.ApplyLevel(ifStmt.Level));
foreach(var c in ifStmt.Else.Childs)
{
IfStatementToDsl(c, sb);
}
}
sb.Append(sqr + ")");
return sb.ToString();
}
#region Parsing-Methods
private IfStatement ToIfStatement(SyntaxNode node, SyntaxNode parent)
{
var ifNode = (IfStatementSyntax)node;
var ifStmt = new IfStatement
{
Condition = ifNode.Condition.ToString(),
Statement = GetIfStatement(ifNode),
Childs = GetIfChilds(ifNode)
};
if (ifNode.Else != null)
{
ifStmt.Else = new ElseStatement
{
Statement = GetElseStatement(ifNode.Else),
Childs = GetElseChilds(ifNode.Else)
};
}
return ifStmt;
}
private List<IfStatement> GetIfChilds(IfStatementSyntax node)
{
var childs = node.Statement.DescendantNodes().Where(n => WhereIfNodes(n, node));
return childs.Select(n => ToIfStatement(n, node)).ToList();
}
private List<IfStatement> GetElseChilds(ElseClauseSyntax node)
{
var childs = node.Statement.DescendantNodes().Where(n => WhereElseNodes(n, node));
return childs.Select(n => ToIfStatement(n, node)).ToList();
}
private string GetIfStatement(IfStatementSyntax node)
{
var result = node.Statement.DescendantNodes().Where(n => WhereIfStatement(n, node));
string returnValue = "";
foreach (var n in result)
{
returnValue += n.ToString();
}
return returnValue.CleanString();
}
private string GetElseStatement(ElseClauseSyntax node)
{
var result = node.Statement.DescendantNodes().Where(n => WhereElseStatement(n, node));
string returnValue = "";
foreach (var n in result)
{
returnValue += n.ToString() + " ";
}
return returnValue.CleanString();
}
private void ApplyNestingLevel(List<IfStatement> list)
{
foreach (var item in list)
{
item.Level = _currentLevel;
if (item.Childs.Count > 0 || (item.Else != null && item.Else.Childs.Count > 0))
{
_currentLevel++;
}
ApplyNestingLevel(item.Childs);
if (item.Else != null)
{
ApplyNestingLevel(item.Else.Childs);
}
}
}
#endregion
#region Linq Where-Conditions
private bool WhereIfNodes(SyntaxNode node, IfStatementSyntax parent)
{
if(node.Kind == SyntaxKind.IfStatement && (node.Parent.Parent == parent))
{
return true;
}
return false;
}
private bool WhereElseNodes(SyntaxNode node, ElseClauseSyntax parent)
{
if (node.Kind == SyntaxKind.IfStatement && (node.Parent.Parent == parent))
{
return true;
}
return false;
}
private bool WhereIfStatement(SyntaxNode node, IfStatementSyntax parent)
{
if ((node.Kind == SyntaxKind.ExpressionStatement || node.Kind == SyntaxKind.LocalDeclarationStatement)
&& (node.Parent.Parent == parent))
{
return true;
}
return false;
}
private bool WhereElseStatement(SyntaxNode node, ElseClauseSyntax parent)
{
if ((node.Kind == SyntaxKind.ExpressionStatement || node.Kind == SyntaxKind.LocalDeclarationStatement)
&& (node.Parent.Parent == parent))
{
return true;
}
return false;
}
private Func<SyntaxNode, bool> getRootNodes =
n => n.Kind == SyntaxKind.IfStatement &&
(n.Parent.Parent.Kind != SyntaxKind.ElseClause && n.Parent.Parent.Kind != SyntaxKind.IfStatement);
#endregion
}
public class IfStatement
{
public int Level { get; set; }
public string Condition { get; set; }
public string Statement { get; set; }
public ElseStatement Else { get; set; }
public List<IfStatement> Childs { get; set; }
}
public class ElseStatement
{
public string Statement { get; set; }
public List<IfStatement> Childs { get; set; }
}
public static class Ext
{
public static string CleanString(this string value)
{
return value.Replace("\t", "").Replace("\n", "").Replace("\r", "");
}
public static string ApplyLevel(this string value, int level)
{
int multiplier = level * 2;
if (level == 0)
multiplier = 1;
var sb = new StringBuilder(multiplier);
for (int i = 0; i < multiplier; i++)
{
sb.Append("'");
}
return value.Replace("'", sb.ToString());
}
}
}
I have to write if-else Statements in a Domain-Specific-Language which is really a pain in the ass!
(The DSL is from a Third-Party-Tool which I have to use to generate WHERE-Statements for SQL-Queries)
Syntax:
#IF(#ISEMPTY(#SUB(temp.last_name))),'if true','else')
#SUB() reads a textboxvalue
Sample:
#IF(#ISEMPTY(#SUB(temp.last_name))),'','account_contact.last_name = ''DOE'' ')
you have to double your single-quotes in the else statement and if you want to nest different "if-else" every time you go a level deeper you have to double the doubled single-quotes!
You see it´s not very simple to write if you have complicated contitions...
So I thought I write a parser that transforms a normal if-else statement to this DSL-Syntax!
The Parser should create objects of this class:
public class IfCondition
{
public int ID { get; set; }
public int ParentID { get; set; }
public int Level { get; set; }
public string Condition { get; set; }
public string Content { get; set; }
public string ElseContent { get; set; }
}
based on a Collection of this Objects I could generate the DSL-Statements!
So my Problem is I really don´t have a clue, how to parse a String like this:
IF(#ISEMPTY(#SUB(temp.last_name))) { }
ELSE
{
IF(#SUB(temp.test) = 'Y')
{
account_contact.last_name = 'DOE'
}
ELSE
{
account_contat.first_name = "JOHN"
}
}
can somebody give me a nudge in the right direction?
If you use Roslyn for syntax rewritting. Not to just write about what you can do, here is an easy example.
Basically how it works. You create a syntax tree for your code and then use predefined visitors to visit those nodes you want to rewrite, you replace them by valid C# code and then you can compile this tree and make it work.
EDIT:
Another, more reliable source with an example
I have recently decided to use protobuf-net to serialize large plain text data files my application uses to see if there is any performance gain over parsing the plain text data.
Data Class:
[ProtoContract]
public class ClimateFile : BaseModel
{
#region Properties
[ProtoMember(1)]
public double Latitude { get { return GetValue(() => Latitude); } private set { SetValue(() => Latitude, value); } }
[ProtoMember(2)]
public double Longitude { get { return GetValue(() => Longitude); } private set { SetValue(() => Longitude, value); } }
[ProtoMember(3)]
public string Notes { get { return GetValue(() => Notes); } set { SetValue(() => Notes, value); } }
[ProtoMember(4)]
public DateTime MinDate { get { return GetValue(() => MinDate); } private set { SetValue(() => MinDate, value); } }
[ProtoMember(5)]
public DateTime MaxDate { get { return GetValue(() => MaxDate); } private set { SetValue(() => MaxDate, value); } }
[ProtoMember(6)]
public List<ClimateDailyData> DailyData { get { return GetValue(() => DailyData); } private set { SetValue(() => DailyData, value); } }
#endregion
#region Method
public static ClimateFile Load(string filePath)
{
try
{
var ext = Path.GetExtension(filePath).ToUpper();
if (ext == ".P51")
return new ClimateFile(filePath);
else if (ext == ".P51X")
{
ClimateFile climateFile;
using (var file = File.OpenRead(filePath))
{
climateFile = Serializer.Deserialize<ClimateFile>(file);
}
return climateFile;
}
}
catch (Exception e)
{
throw new InvalidDataException(String.Format("The file \"{0}\" could not be opened, {1}", filePath, ExceptionUtilities.JoinExceptionMessages(e)));
}
throw new ArgumentException("filePath was not a .P51 or .P51X file.");
}
public void LoadP51File(string filePath)
{
List<string[]> lines = GetFileLines(filePath);
Latitude = double.Parse(lines[0][0]);
Longitude = double.Parse(lines[0][1]);
for (int i = 2; i < lines[0].Length; ++i)
Notes += String.Format("{0} ", lines[0][i]);
MinDate = GetDate(lines[2][0]);
MaxDate = GetDate(lines[lines.Count - 1][0]);
// Parse daily data
lines.RemoveRange(0, 2);
var dailyData = lines.Select(row => new ClimateDailyData()
{
DataDate = GetDate(row[0]),
MaxTemperature = double.Parse(row[2]),
MinTemperature = double.Parse(row[3]),
Rainfall = double.Parse(row[4]),
Evaporation = double.Parse(row[5]),
SolarRadiation = double.Parse(row[6])
}).ToList();
DailyData = dailyData;
}
public void SaveP51XFile(string filePath)
{
using (var file = File.Create(filePath))
{
Serializer.Serialize<ClimateFile>(file, this);
}
}
public List<string[]> GetFileLines(string filePath)
{
var rows = new List<string[]>();
var cells = new List<string>();
var cell = new StringBuilder();
using (var fs = new BufferedStream(File.OpenRead(filePath)))
{
int buffer;
while ((buffer = fs.ReadByte()) != -1)
{
char nextChar = (char)buffer;
if (nextChar >= '!') // If the character is a non-whitespace printable character
{
cell.Append(nextChar);
continue;
}
if (nextChar == ' ' || nextChar == '\t')
{
if (cell.Length > 0)
{
cells.Add(cell.ToString());
cell.Clear();
}
continue;
}
if (nextChar == '\r' || nextChar == '\n')
{
if (cell.Length > 0)
{
cells.Add(cell.ToString());
cell.Clear();
}
if (cells.Count > 0)
{
rows.Add(cells.ToArray());
cells.Clear();
}
continue;
}
throw new InvalidDataException("The climate file contains unknown characters.");
}
if (cell.Length > 0)
cells.Add(cell.ToString());
if (cells.Count > 0)
rows.Add(cells.ToArray());
}
return rows;
}
public DateTime GetDate(string date)
{
return DateTime.ParseExact(date, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
}
public override void Dispose()
{
if (Disposed)
return;
if (DailyData != null)
foreach (ClimateDailyData dailyData in DailyData)
dailyData.Dispose();
base.Dispose();
}
#endregion
#region Initialization
public ClimateFile()
{
}
public ClimateFile(string filePath)
{
LoadP51File(filePath);
}
#endregion
}
Collection Data Class:
[ProtoContract]
public class ClimateDailyData : BaseModel
{
[ProtoMember(1)]
public DateTime DataDate { get { return GetValue(() => DataDate); } set { SetValue(() => DataDate, value); } }
[ProtoMember(2)]
public int JulianDay { get { return DataDate.DayOfYear; } }
[ProtoMember(3)]
public double MaxTemperature { get { return GetValue(() => MaxTemperature); } set { SetValue(() => MaxTemperature, value); } }
[ProtoMember(4)]
public double MinTemperature { get { return GetValue(() => MinTemperature); } set { SetValue(() => MinTemperature, value); } }
[ProtoMember(5)]
public double Rainfall { get { return GetValue(() => Rainfall); } set { SetValue(() => Rainfall, value); } }
[ProtoMember(6)]
public double Evaporation { get { return GetValue(() => Evaporation); } set { SetValue(() => Evaporation, value); } }
[ProtoMember(7)]
public double SolarRadiation { get { return GetValue(() => SolarRadiation); } set { SetValue(() => SolarRadiation, value); } }
}
Serialization Command:
public ICommand ImportP51
{
get
{
return new RelayCommand(delegate
{
OpenFileDialog openDialogue = new OpenFileDialog()
{
AddExtension = true,
CheckPathExists = true,
CheckFileExists = true,
DefaultExt = ".p51",
Filter = "Climate Files|*.p51",
InitialDirectory = DataPath,
Multiselect = false,
Title = "Select a File to Open"
};
if ((bool)openDialogue.ShowDialog())
{
string filePath = String.Empty;
try
{
filePath = openDialogue.FileName;
var climate = new Climate();
climate.FilePath = filePath;
var savePath = String.Format("{0}\\{1}.p51x", ClimateDataPath, Path.GetFileNameWithoutExtension(filePath));
climate.FileData.SaveP51XFile(savePath);
}
catch (Exception e)
{
MessageBox.Show(String.Format("The file \"{0}\" could not be opened, {1}", filePath, ExceptionUtilities.JoinExceptionMessages(e)), "Invalid File");
}
}
});
}
}
When executing ImportP51, I get the exception "Specified method is not supported", I am using protobuf-net V2 r594 which was released on the 12/10/2012 and am thinking of trying to use one of the previous versions if I cannot get it to work with this version. Can someone please tell me what I am doing wrong?
I've tried to reconstruct a working version of the code (since I don't have your BaseModel) which I've done by using automatically implemented properties and adding an initializer for the list (DailyData), and explicitly referencing r594 from google-code. The only error I get is:
Cannot apply changes to property ClimateDailyData.JulianDay
which makes sense, because it can't rightly deserialize data into a read-only property, so I removed the serialization marker from that one:
// [ProtoMember(2)] removed - serialized implicitly via DataData
public int JulianDay { get { return DataDate.DayOfYear; } }
After that it worked fine. Since I don't have your command framework, I have:
static class Program
{
static void Main()
{
var climateFile = new ClimateFile();
climateFile.InitSomeDataForSerialization();
climateFile.SaveP51XFile("foo.P51X");
var clone = ClimateFile.Load("foo.P51X");
}
}
where InitSomeDataForSerialization just sets some of the values (since they have private setters, I can't do that in Main):
public void InitSomeDataForSerialization()
{
Longitude = 10; Latitude = 4; Notes = "Test";
DailyData.Add(
new ClimateDailyData { DataDate = DateTime.Today, MinTemperature = 12, MaxTemperature = 35}
);
}
And... it works.
On a hunch, I checked what happens if you reference "CoreOnly" instead of "Full", but that then refuses to compile because Serializer.Serialize<T> and Serializer.Deserialize<T> don't exist.
I'm happy to help, but as far as I can tell, nothing is wrong.
Things I would suggest next:
show the full stack-trace of what happens in this exception, including any inner-exceptions (see the fix below)
please check exactly which file you referenced in the 594 zip (look at "What Files Do I Need.txt", but I'd guess the correct one for you is "Full/net30/..."; the nuget package configures the most appropriate files automatically)
please show a fully reproducible example, i.e. where I can press F5 and see the exact exception (I had to change the code in the example for it to compile, which means I am no longer testing the same thing)
Fix for correct exception wrapping:
catch (Exception e)
{
throw new InvalidDataException(String.Format("The file \"{0}\" could not be opened", filePath), e);
}