How to Get Rssi Value of WlanGetNetworkBssList Function Return Value - wlanapi

Windows's WlanAPi has a function which is WlanGetNetworkBssList.This function return a variable which type is PWLAN_AVAILABLE_NETWORK.
How to get rssi value of PWLAN_AVAILABLE_NETWORK rssi value using windows wlan api ?

These structure definitions and constructors work in my code works from WlanGetAvailableNetworkList it is incomplete and does not completely parse the structure, but it does get RSSI.
[StructLayout(LayoutKind.Sequential)]
public struct WLAN_AVAILABLE_NETWORKS_LIST
{
public UInt32 NumberOfNetworks;
//Current Not used by Native System, can be used to indicate desired network
public UInt32 CurrentNetwork;
//one per network found
public WLAN_AVAILABLE_NETWORK[] Available_Network;
//input for constructor
private IntPtr p;
public WLAN_AVAILABLE_NETWORKS_LIST(IntPtr _p)
{
IntPtr pn = new IntPtr();
// TODO: Complete member initialization
this.p = _p;
this.NumberOfNetworks = (UInt32)Marshal.ReadInt32(p);
this.CurrentNetwork = (UInt32)Marshal.ReadInt32(p, 4);
this.Available_Network = new WLAN_AVAILABLE_NETWORK[NumberOfNetworks];
for (int i = 0; i < NumberOfNetworks; i++)
{
pn = (IntPtr)(p.ToInt32() + 8 + (628 * i));
//Available_Network[i] = (WLAN_AVAILABLE_NETWORK)Marshal.PtrToStructure(pn, typeof(WLAN_AVAILABLE_NETWORK));
Available_Network[i].strProfileName = Marshal.PtrToStringUni(pn);
Available_Network[i].SSID = new dot11_SSID(new IntPtr(pn.ToInt32() + 512));
Available_Network[i].dot11BssType = (DOT11_BSS_TYPE)Marshal.ReadInt32(pn, 512 + 36);
Available_Network[i].uNumberOfBssids = (UInt32)Marshal.ReadInt32(pn, 512+36+4);
Available_Network[i].wlanSignalQuality = (UInt32)Marshal.ReadInt32(pn, 512 + 36 + 5*4+32+4);
}
}
}
Structure for WLAN_AVAILABLE_NETWORK
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WLAN_AVAILABLE_NETWORK //size = 628
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strProfileName;//size 512
public dot11_SSID SSID;//size 36
public DOT11_BSS_TYPE dot11BssType; // size 4
public UInt32 uNumberOfBssids; // 4
//public bool bNetworkConnectable; // 4
//public UInt32 wlanNotConnectableReason; // 4
//public UInt32 uNumberOfPhyTypes; // 4
////public DOT11_PHY_TYPE[] dot11PhyTypes; // max is 8, size is 8*4 = 32
//public UInt32[] dot11PhyTypes; // max is 8, size is 8*4 = 32
//public bool bMorePhyTypes;// 4
public UInt32 wlanSignalQuality; // size 4
//A percentage value that represents the signal quality of the network. WLAN_SIGNAL_QUALITY is of type ULONG. This member contains a value between 0 and 100. A value of 0 implies an actual RSSI signal strength of -100 dbm. A value of 100 implies an actual RSSI signal strength of -50 dbm. You can calculate the RSSI signal strength value for wlanSignalQuality values between 1 and 99 using linear interpolation.
//public bool bSecurityEnabled;// 4
////public DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;// 4
////public DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;// 4
//public UInt32 dot11DefaultAuthAlgorithm;// 4
//public UInt32 dot11DefaultCipherAlgorithm;// 4
//public UInt32 dwFlags;// 4
//public UInt32 dwReserved;// 4
}
I could not make the Marshal.PtrToStructure work.
Here is the function that calls the WlanGetAvailableNetworkList
public static WLAN_AVAILABLE_NETWORKS_LIST GetAvailNetworkList()
{
UInt32 _dwflags = 3;
IntPtr handle = GetClientHandle();
IntPtr pGuid = GetCurrentInterfaceGuidPointer();
IntPtr _ppAvailNetworkList = new IntPtr();
uint error = WlanGetAvailableNetworkList(handle, pGuid, _dwflags, IntPtr.Zero, out _ppAvailNetworkList);
if (error != 0)
{
Console.WriteLine("WlanEnumerated function in GetAvailNetworkPointer() failed... inspect error number" + error);
}
else
{
// It worked
}
WLAN_AVAILABLE_NETWORKS_LIST TempNetworkList = new WLAN_AVAILABLE_NETWORKS_LIST(_ppAvailNetworkList);
WlanFreeMemory(pGuid);
CloseClientHandle(handle);
return TempNetworkList;
}
and the NUINT test that confirms there are RSSI values.
[Test]
public void GetAvailNetworkReturnsRSSI()
{
WiFiApi.WLAN_AVAILABLE_NETWORKS_LIST networklist = WiFiApi.GetAvailNetworkList();
for (int i = 0; i < networklist.NumberOfNetworks; i++)
{
string SSIDstr = new string(networklist.Available_Network[i].SSID.SSID);
Console.Write("Network " + i + " ");
Console.Write(SSIDstr);
Console.Write(" RSSI = " + networklist.Available_Network[i].wlanSignalQuality);
Console.Write(" dbM = " + ((int)(networklist.Available_Network[i].wlanSignalQuality/2)-100));
Console.WriteLine(" ");
if (0 != networklist.Available_Network[i].SSID.SSID_Length)
{
Assert.LessOrEqual((int)networklist.Available_Network[i].wlanSignalQuality, 100);
Assert.Greater((int)networklist.Available_Network[i].wlanSignalQuality, 0);
}
}
}

Related

Finding the two largest element of an array

For Problem:
Finding and printing unique team of two students (otherwise printing "?") from each region out of n regions based on greater scores (from 0 to 800)
I thought that we can keep track of the largest and second largest element, initialized with scores of -1 and -1. There are only a few possibilities:
If score is more than the largest, then largest must be the current and shift largest to second largest, but if largest is same as second largest, the team can be formed in two ways, hence undefined.
Else if score is more than second then directly replace him.
Else if score is same as second then also undefined
But it seems this is wrong, but I don't know why?
Code:
import java.util.Arrays;
import java.util.Scanner;
public class B659 {
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
int n = num();
int m = num();
String[] rgn1 = new String[m]; // students with highest score in their region
String[] rgn2 = new String[m]; // students with second-highest score in their region
int[] rgn1s = new int[m]; // highest score in the regions
int[] rgn2s = new int[m]; // second-highest score in the regions
Arrays.fill(rgn1s, -1);
Arrays.fill(rgn2s, -1);
boolean[] und = new boolean[m];
for (int i = 0; i < n; i++) {
String sn = str();
int r = num() - 1;
int sc = num();
if (sc > rgn1s[r]) {
if (rgn2s[r] == rgn1s[r] && rgn1s[r] != -1) {
und[r] = true;
continue;
} else {
rgn2s[r] = rgn1s[r];
rgn2[r] = rgn1[r];
}
rgn1s[r] = sc;
rgn1[r] = sn;
} else if (sc > rgn2s[r]) {
rgn2s[r] = sc;
rgn2[r] = sn;
} else if (sc == rgn2s[r]) {
und[r] = true;
}
}
for (int i = 0; i < m; i++) {
print((!und[i]) ? (rgn1[i] + " " + rgn2[i]) : "?");
}
}
private static int num() {
return sc.nextInt();
}
private static String str() {
return sc.next();
}
private static void print(Object x) {
System.out.println(x);
}
}
Your code doesn't handle the situation when once the duplicate values has been encountered and the und[r] field has been set true, two higher values are encountered.
For eg:
6 2
Ram 1 200
Shyam 1 200
Raju 2 200
Rita 1 300
Hera 2 500
Sita 1 500
You need to redefine the if and add another else if part for the duplicate entries if they happens to be the last pair.
else if (sc == rgn1s[r]) {
und[r] = true;
}
For eg:
6 2
Ram 1 200
Shyam 1 300
Raju 2 200
Rita 1 500
Hera 2 500
Sita 1 500

Generating an array of partially random boolean values based on certain criteria [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am trying to generate random data based on some criteria. I am stuck on how to start so I don't have any code.
I just want some guide on how I can achieve that. You need not provide complete code.
So, coming to the problem, lets say we have this existing data:
Total - 10
Won - 7
Lost - 3
Longest Winning Streak - 5
Longest Losing Streak - 2
Now I need to generate an array of random boolean values (true representing a win and false representing a loss) which fulfills the above criteria.
So, in this case the output can be any of the following:
0011011111
1111101100
1010011111
..........
Its the streak part that bothers me. If it weren't for the streak, I could have generated seven 1(s) and three 0(s) and then randomly shuffled them.
Note: I would prefer solutions in C#, VB.NET, JavaScript, or Python but any language is welcome.
I'd suggest a genetic algorithm.
class Program
{
static int len = 10;
static int win = 7;
static int lws = 5;
static int lls = 2;
static Random rnd = new Random();
static void Main(string[] args)
{
int genSz = 15;
var generation = new List<Chromosome>();
Helper.Repeat(() => generation.Add(new Chromosome()), genSz);
int gen = 1;
while (generation.First().Fitness != 0)
{
//procreation
Helper.Repeat(() => {
int x1 = rnd.Next(genSz / 2);
int x2 = rnd.Next(genSz);
generation.Add(new Chromosome(generation[x1], generation[x2]));
}, genSz);
//selection
generation = generation.OrderBy(x => x.Fitness).Take(genSz).ToList();
Console.WriteLine("GENERATION " + gen++);
foreach (var x in generation)
{
Console.WriteLine(x);
}
Console.ReadLine();
}
Console.ReadLine();
}
class Chromosome
{
bool[] genes = new bool[len];
public Chromosome() { }
public Chromosome(Chromosome p1, Chromosome p2)
{
//crossingover
rnd.Shuffle(ref p1, ref p2); //may reorder parents or not
var x = rnd.Next(len);
Array.Copy(p1.genes, 0, genes, 0, x);
Array.Copy(p2.genes, x, genes, x, len - x);
//mutation
if (rnd.Flip())
{
x = rnd.Next(len);
genes[x] = !genes[x];
}
}
public int Fitness
{
get
{
int w = genes.Count(g => g);
int l = len - w;
int ws = genes.LongestStreak(g => g);
int ls = genes.LongestStreak(g => !g);
return Math.Abs(w - win) + Math.Abs(lws - ws) + Math.Abs(lls - ls);
}
}
public override string ToString()
{
return "[" + new string(genes.Select(g => g ? '*' : '.').ToArray()) + "] " + Fitness.ToString();
}
}
}
public static class Helper
{
public static bool Flip(this Random rnd) => rnd.Next(2) == 0;
public static void Shuffle<T>(this Random rnd, ref T a, ref T b, bool allowNoChange = true)
{
if (allowNoChange && rnd.Flip()) return; //no reordering
T tmp = a; a = b; b = tmp;
}
public static int LongestStreak<T>(this IEnumerable<T> sequence, Predicate<T> selector)
{
int current = 0;
int longest = 0;
foreach (T x in sequence)
{
if (selector(x))
{
current++;
if (current > longest) longest = current;
}
else
{
current = 0;
}
}
return longest;
}
public static void Repeat(this Action action, int N)
{
for (int n = 0; n < N; n++) action();
}
}
Second variant - brute force. Can be used if the sequence is short. Also you can get all possible variants with it.
class Program
{
static void Main(string[] args)
{
var res = new[] { true, false }.Words(10).Where(w => {
return
w.Count(g => g) == 7 &&
w.LongestStreak(g => g) == 5 &&
w.LongestStreak(g => !g) == 2;
});
foreach (var v in res)
{
foreach (var b in v)
{
Console.Write(b ? "*" : ".");
}
Console.WriteLine();
}
Console.WriteLine(res.Count());
Console.ReadLine();
}
}
public static class Helper
{
public static IEnumerable<IEnumerable<T>> Words<T>(this IEnumerable<T> alphabet, int len)
{
foreach (var l in alphabet)
{
if (len == 1)
{
yield return l.Yield();
}
else
{
foreach (var w in alphabet.Words(len - 1))
{
yield return w.Prepend(l);
}
}
}
}
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
static IEnumerable<T> Prepend<T>(this IEnumerable<T> rest, T first)
{
yield return first;
foreach (var item in rest)
yield return item;
}
public static int LongestStreak<T>(this IEnumerable<T> sequence, Predicate<T> selector)
{
int current = 0;
int longest = 0;
foreach (T x in sequence)
{
if (selector(x))
{
current++;
if (current > longest) longest = current;
}
else
{
current = 0;
}
}
return longest;
}
}
My suggestion would be to use an algorithm to select k bits (your won number) from a length-n (your total number) string. Here, I use the kbits(n, k) function written by #foglebird. You can then filter out the undesired permutations using a list comprehension.
import itertools
def kbits(n, k):
result = []
for bits in itertools.combinations(range(n), k):
s = ['0'] * n
for bit in bits:
s[bit] = '1'
result.append(''.join(s))
return result
total = 10
won = 7
lost = 3
max_win = 5
max_lose = 2
answer = [x for x in kbits(total, won) if '1'*(max_win+1) not in x and '0'*(max_lose+1) not in x]
I had an answer posted, then noticed I was missed some key requirements. I added and changed some stuff to address those missing elements.
The core method fails most of the time, but it does so quickly enough that you can do it in a loop until you get a good answer. Depending on the actual values, in cases where there are very few legal results, it seems like you need to luck out.
The steps used:
Pick a random spot for the longest streak (Win in the example)
Bracket the streak with losses to prevent extending it when setting leftovers
Find the indices with enough consecutive slots to hold the loss streak
Pick a random one and set the loss streak (returns if there are none)
Set all the Leftovers as Not the value at n-1 to avoid extending or creating a new streak
So, it becomes hit or miss whether then WinCount and LossCount are correct. That seems easier to stumble upon than streaks of the right size. A wrapper method tests the result to reject and rerun. With the given values, it usually find a winner in the first 10 or so times.
The core method to construct a string representation, and a helper:
' ToDo change to return Bool() = string is easier to read
Private Function FarhamStreaks(winStrk As Int32, loseStrk As Int32, total As Int32) As String
' -1 == not set
Dim result = Enumerable.Repeat(-1, total).ToArray
' set longest streak first
Dim wNDX = RNG.Next(0, total + 1 - winStrk)
For n As Int32 = 0 To winStrk - 1
result(wNDX + n) = 1
Next
' bracket with losers so the w streak cant extend
If wNDX > 0 Then result(wNDX - 1) = 0
If wNDX + winStrk < result.Length - 1 Then result(wNDX + winStrk) = 0
' look for eligible consecutive starting slots
' might be none
Dim lossNdx As New List(Of Int32)
For n As Int32 = 0 To result.Count - 1
Dim count = CountConsecutiveLooserSlotsFrom(n, result)
If (n + 1) < result.Count AndAlso count >= loseStrk Then
lossNdx.Add(n)
End If
Next
If lossNdx.Count = 0 Then
' do over
' the code has never gotten here
' but depends on the mix of values
Return ""
End If
' set losses
Dim lNdx = lossNdx(RNG.Next(0, lossNdx.Count))
For n As Int32 = 0 To loseStrk - 1
result(lNdx + n) = 0
Next
' set the leftovers based on next value to avoid
' extending streaks
For n As Int32 = 0 To result.Length - 1
If result(n) = -1 Then
If n > 0 Then
result(n) = If(result(n - 1) = 0, 1, 0)
Else
result(n) = If(result(n + 1) = 0, 1, 0)
End If
End If
Next
Dim resultString = String.Join(",", result)
' convert to boolean
Dim realResult(total) As Boolean
For n As Int32 = 0 To total - 1
realResult(n) = Convert.ToBoolean(result(n))
Next
Return resultString
End Function
' find candidate slots for the shorter streak:
Private Function CountConsecutiveLooserSlotsFrom(ndx As Integer, theArray As Int32()) As Int32
Dim count As Int32 = 1 ' including ndx
For n As Int32 = ndx To theArray.Length - 2
If theArray(n) <> 1 AndAlso theArray(n + 1) <> 1 Then
count += 1
Else
Exit For
End If
Next
Return count
End Function
The method to validate a result candidate (and performance metrics):
Private Function MakeFarhamStreak(wins As Int32, winStreak As Int32,
lossStreak As Int32,
total As Int32) As String
Const MaxTries As Int32 = 999
Dim losses = (total - wins)
Dim reverse As Boolean = (lossStreak > winStreak)
Dim candidate As String
Dim sw As New Stopwatch
Dim pass, fail As Int32
Dim count As Int32
sw.Start()
For n As Int32 = 0 To MaxTries
If reverse Then
candidate = FarhamStreaks(lossStreak, winStreak, total)
' to do: un-reverse (Not) the results -
Else
candidate = FarhamStreaks(winStreak, lossStreak, total)
End If
Dim result = candidate.Split(","c)
' test win count
count = candidate.Where(Function(f) f = "1").Count
If count <> wins Then
fail += 1
Continue For
End If
' test loss count
count = candidate.Where(Function(f) f = "0").Count
If count <> losses Then
fail += 1
Continue For
End If
Dim tmp = candidate.Replace(","c, "")
' test win streak size
Dim wstreaks = tmp.Select(Function(c, i) tmp.Substring(i).
TakeWhile(Function(q) q = c AndAlso q = "1").
Count()).
Max
If wstreaks <> winStreak Then
fail += 1
Continue For
End If
Dim lstreaks = tmp.Select(Function(c, i) tmp.Substring(i).
TakeWhile(Function(q) q = c AndAlso q = "0").
Count()).
Max
If lstreaks <> lossStreak Then
fail += 1
Continue For
End If
pass += 1
If pass = 1 Then
Console.WriteLine("First Pass in {0}ms (try # {1} = {2})",
sw.ElapsedMilliseconds, n, candidate)
' normally, return at this point
End If
Next
End Function
It is easier to fit the shorter streak around the longer one, so it reverses the parm order as needed. There isnt code to flip/Not the results.
results:
First Pass in 18ms (try # 4 = 1,1,1,1,1,0,0,1,0,1)
Total FAILURES 753 75.38%
Total Pass 247 24.72%
Total time for 999 candidates 29ms
It found the first passing value on try #4 - with the 10, 7w, 5ws, 2ls values it usually finds one in the first 10.

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0

I'm not really sure why I keep getting this error message. I'm trying to add int three to result. I don't understand why it doesn't let me do this, it seems result would be empty when I try to put three into index size1-1.
Error message: (Lines 452, 423, 11 are marked)
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at BigInt.singleDigitMultiply(BigInt.java:452)
at BigInt.multiply(BigInt.java:423)
at Dem.main(Dem.java:11)
Portion of BigInt class:
public BigInt multiply(BigInt B2) {
BigInt result = new BigInt();
BigInt B1 = this;
result = singleDigitMultiply(B1,B2); Line 423
return result;
}
private BigInt singleDigitMultiply(BigInt B1, BigInt B2) {
int size1 = B1.num.size(), size2 = B2.num.size();
BigInt result = new BigInt();
//result.num = new ArrayList (Collections.nCopies( size1+1, null ));
boolean carryover = false;
int one, two, three, four, five, carry;
for (int i = size1-1; i >= 0; i--) {
one = B1.num.get(i);
two = B2.num.get(0);
int prod = B1.num.get(i) * B2.num.get(0);
int prodInt = prod / 10;
if (prod > 9) carryover = true;
if (i == size1-1) {
if (carryover) {
three = prod % (prodInt * 10);
}
else {
three = prod;
}
System.out.println( result.num.set(size1-1,three)); Line 452
}
// else {
// four = B1.num.get(i+1) * two;
// carry = four % (four - prodInt);
// if (four > 9) {
//
// five = prod + carry;
// three = five % (prodInt * 10);
// }
// else {
// three = prod;
// }
// result.num.add(i,three);
// }
}
return result;
}
Main class:
public class Dem {
public static void main(String[] args) {
BigInt B1 = new BigInt("55");
BigInt B2 = new BigInt("1");
BigInt D = new BigInt();
int u = 8;
int j = 10;
//BigInt J = new BigInt("u");
D = B1.multiply(B2); Line 11
System.out.println(u/j);
}
}
The problem is that you probably didn't set the result.num yet at the point in which you are trying to access this value, so you should assign it at whatever point, either in singleDigitMultiply(...) method or in BigInt constructor, but before reading the value.

Setting logonHours property to lock unlock user accounts

How do I set each bit of the logonHours property (which as 21 bytes) to either zero (for locking user account) or one (for unlocking) ? I have obtained the logonHours property in bytes as follows:
bytes[] logonHours = (byte[])de.Properties["logonHours"].Value;
//After seaching the web, I used the following code :
public void myMethod(String p_UserName)
{
byte[] logonHours = null;
logonHours = (byte[])de.Properties["logonHours"].Value;
BitArray bitArray = new BitArray(logonHours);
for (int i = 0; i < bitArray.Count; i++)
{
//If bit is zero (that is false), logonHours is Locked
//If bit is one (that is true) then set to zero (false) to LOCK the account
if (bitArray[i])
{
bitArray.Set(i, false);
}
}
byte[] m_Bytes1 = MyExtension.ConvertToByteArray(bitArray);
de.Properties["logonHours"].Value = m_Bytes;
de.CommitChanges();
}
static class MyExtension
{
public static byte[] ConvertToByteArray(this BitArray bits)
{
int numBytes = bits.Count / 8;
if (bits.Count % 8 != 0) numBytes++;
byte[] bytes = new byte[numBytes];
int byteIndex = 0, bitIndex = 0;
for (int i = 0; i < bits.Count; i++)
{
if (bits[i])
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
bitIndex++;
if (bitIndex == 8)
{
bitIndex = 0;
byteIndex++;
}
}
return bytes;
}//end of method
}
Here is an article that can help you : Active Directory Permitted Logon Times with C#

How is a guid actually stored and sorted/compared in SQL Server?

Say I have this guid:
{2A87E3E2-2B6A-4149-9F5A-1B76092843D9}
Does it actually store this an an alpha numeric in the database? (I don't think so cause it has to fit in 16 bytes.)
If it does not, then how is it stored? (My guess is as a hex number, but I am not sure.)
How can you tell if one GUID is greater than another? (Which you may need to know for indexing purposes.) Do you read the GUID just like a hex number (for comparison)?
A GUID is stored as binary(16) internally. "Using uniqueidentifier Data" on MSDN tells you this.
The { } and - are not part of the value.
GUIDs can be "sorted" and have greater/lesser comparisons: see the canonical "How are GUIDs sorted by SQL Server?".
Note: this means they don't sort as binary(16) (unless you CAST I suppose...)
I can't see why you'd want this in real life (not indexing, I mean real world): about the only use for the "sorting" potential of NEWID is for the random rows tricks of ORDER BY NEWID()
You can have "ascending" GUIDs (based on the article above) with NEWSEQUENTIALID. However, this "sorting" doesn't continue after a Windows restart = pointless IMO.
Necromancing.
The GUID is stored as byte-array, that is to say binary(16).
You could also store it as UInt128, or two bigints.
As to how a GUID is sorted:
The code speaks for itselfs, the magical parts are
System.Guid g
g.ToByteArray();
int[] m_byteOrder = new int[16] // 16 Bytes = 128 Bit
{10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};
public int Compare(Guid x, Guid y)
{
byte byte1, byte2;
//Swap to the correct order to be compared
for (int i = 0; i < NUM_BYTES_IN_GUID; i++)
{
byte1 = x.ToByteArray()[m_byteOrder[i]];
byte2 = y.ToByteArray()[m_byteOrder[i]];
if (byte1 != byte2)
return (byte1 < byte2) ? (int)EComparison.LT : (int)EComparison.GT;
} // Next i
return (int)EComparison.EQ;
}
Full code:
namespace BlueMine.Data
{
public class SqlGuid
: System.IComparable
, System.IComparable<SqlGuid>
, System.Collections.Generic.IComparer<SqlGuid>
, System.IEquatable<SqlGuid>
{
private const int NUM_BYTES_IN_GUID = 16;
// Comparison orders.
private static readonly int[] m_byteOrder = new int[16] // 16 Bytes = 128 Bit
{10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};
private byte[] m_bytes; // the SqlGuid is null if m_value is null
public SqlGuid(byte[] guidBytes)
{
if (guidBytes == null || guidBytes.Length != NUM_BYTES_IN_GUID)
throw new System.ArgumentException("Invalid array size");
m_bytes = new byte[NUM_BYTES_IN_GUID];
guidBytes.CopyTo(m_bytes, 0);
}
public SqlGuid(System.Guid g)
{
m_bytes = g.ToByteArray();
}
public byte[] ToByteArray()
{
byte[] ret = new byte[NUM_BYTES_IN_GUID];
m_bytes.CopyTo(ret, 0);
return ret;
}
int CompareTo(object obj)
{
if (obj == null)
return 1; // https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx
System.Type t = obj.GetType();
if (object.ReferenceEquals(t, typeof(System.DBNull)))
return 1;
if (object.ReferenceEquals(t, typeof(SqlGuid)))
{
SqlGuid ui = (SqlGuid)obj;
return this.Compare(this, ui);
} // End if (object.ReferenceEquals(t, typeof(UInt128)))
return 1;
} // End Function CompareTo(object obj)
int System.IComparable.CompareTo(object obj)
{
return this.CompareTo(obj);
}
int CompareTo(SqlGuid other)
{
return this.Compare(this, other);
}
int System.IComparable<SqlGuid>.CompareTo(SqlGuid other)
{
return this.Compare(this, other);
}
enum EComparison : int
{
LT = -1, // itemA precedes itemB in the sort order.
EQ = 0, // itemA occurs in the same position as itemB in the sort order.
GT = 1 // itemA follows itemB in the sort order.
}
public int Compare(SqlGuid x, SqlGuid y)
{
byte byte1, byte2;
//Swap to the correct order to be compared
for (int i = 0; i < NUM_BYTES_IN_GUID; i++)
{
byte1 = x.m_bytes[m_byteOrder[i]];
byte2 = y.m_bytes[m_byteOrder[i]];
if (byte1 != byte2)
return (byte1 < byte2) ? (int)EComparison.LT : (int)EComparison.GT;
} // Next i
return (int)EComparison.EQ;
}
int System.Collections.Generic.IComparer<SqlGuid>.Compare(SqlGuid x, SqlGuid y)
{
return this.Compare(x, y);
}
public bool Equals(SqlGuid other)
{
return Compare(this, other) == 0;
}
bool System.IEquatable<SqlGuid>.Equals(SqlGuid other)
{
return this.Equals(other);
}
}
}

Resources