Note: I'm not sure how best to title and tag this question so helpful edits welcome!
I am reverse engineering an ASP.NET Webforms website (for which I don't have the correct version of the source code) to ASP.NET MVC using database first entity framework, and am having difficulty understanding how a particular view/set of data works.
A record has an "Options" field which contains a series of numbers which, when read, identify which of 48 options are true. I'm trying to figure out how to read/write this result.
So, the options table is structured like so:
As you can see there is a BitValue column (Which continues up to 281474976710656); I believe this is what I need to use to identify the options when presented with a number like so: 5120 or 17592186044480
If that number only identified a single option I'd probably be able to figure this out easier but unfortunately there can be several options identified.
So for example, a record has this in it's options field: 17592186044480 The options this identifies (when I refer to the existing website) are: Procedure (BitValue: 64) Shore Crew Error (BitValue: 17592186044416)
But I can't for the life of me figure out how both of those numbers translate to the one in the options field!
Any hints?
Ok, so 64 + 17592186044416 = 17592186044480 That helps understand how the number is generated, but how to I reverse this to identify the options that make up the number?
CONCLUSION I have accepted an answer as, in combination with some comments, it helped me find the solution.
In the end, I wrote out the "options" as an enum like so...
[Flags] public enum options : long
{
Master_Pilot_Exchange = 2,
Bridge_Team_Issues = 4,
Language_Difficulty = 8,
Briefing = 16,
Crew_Competency = 32,
Procedure = 64,
Personal_Performance = 128,
Fatigue = 256,
....
}
and created a function to check each option to see if it is included in the bitValue:
private bool checkBits(long maskIn, int optionId)
{
options mask = (options)maskIn;
var toCheck = db.InitialReportOptions.Single(i => i.InitialReportOptionID == optionId);
options chk = (options)toCheck.BitValue;
bool test = false;
if ((mask & chk) == chk)
{
test = true;
}
//
return test;
}
And when I need to add a new bitValue to a record, I use the following:
options newMask = (options)0;
long bitResult = 0;
foreach(var option in model.ReportOptions)
{
if (option.IsTrue)
{
var bitv = (options)option.BitValue;
bitResult = bitResult | ( (long)newMask | (long)bitv);
}
}
model.InitialReportRecord.Options = bitResult;
I daresay it could be more efficient but it works so I'm happy!