mIRC Home    About    Download    Register    News    Help

Print Thread
Expanded Binary Variable handlers #265352 03/04/19 09:23 PM
Joined: Dec 2002
Posts: 198
T
Talon Offline OP
Vogon poet
OP Offline
Vogon poet
T
Joined: Dec 2002
Posts: 198
It would be nice to have other "clones" of the original binary variable handlers: /bset, /bcopy, /breplace, $bfind, $bvar() mainly...

It would be nice to have support for at least WORD and DWORD sizes (16bit and 32bit, possibly QWORD:64bit) where everything remains the same except the range difference.

It could still utilize original binary variables, and just break down the integer (or ascii value with flags like -t) into High/Low bits, to satisfy the 0-255 range. It would just make a binvar used with 16bit 2x as large as a normal 8bit (since it takes two slots to represent 1 number) and 4x larger for 32bit (as now it takes four slots to represent 1 number).

While if you do the math yourself to break down high/low bits, you can use /bset and achieve this to get back a single number. for instance:

bset &a 1 $calc(65530 // 256) $calc(65530 % 256)

&a == 255 250
$bvar(&a,1).nword == 65530

But there's the issue about traversal now, You can't assume "2" is the 2nd nword position representing positions 3-4... as it's not. You literally have to use "3" with .nword for the 2nd number (if you constructed more than one number)

Examples:
$bvar(&a,1).nword
$bvar(&a,3).nword <== you'd think this should be 2, since we're telling mIRC we're processing this binvar in 16bit WORD chunks, but actually your indexing must still remain in 8bit...

Not to mention .props don't work on ranges like 1-3 for instance. Only single place parameters work with .nword/.word/etc...

I'd like to propose prepended bit-sizes onto the existing functions so you have handlers for all of these, like:

/bset16 [-tac] <&binvar> <N> <0-65535>...
$bvar16(&binvar,N,M)
etc.. for WORD (16bit)...

/bset32 [-tac] <&binvar> <N> <0-4294967295>...
$bvar32(&binvar,N,M)
etc.. for DWORD(32bit)...

and if you go further

/bset64
$bvar64()
etc.. for QWORD(64bit)...

Although I doubt QWORD would be supported as a good chunk of the range isn't really usable by mIRC, as seen with $calc() where you can see accurate results up to 53 bits. Anything higher is lost.

Here's some rather basic aliases to do partially WORD support (16bit)

Code:
alias bset16 { bset $1 $calc(($2 - 1) * 2 + 1) $regsubex($3-,/(\d+)/g,$calc(\t // 256) $calc(\t % 256)) }
alias bvar16 {
  if ($2 == 0) { return $calc($bvar($1,0) // 2) }
  elseif ($2 isnum) { return $regsubex($bvar($1,$+($calc(($2 -1) * 2 + 1),-,$calc($2 * 2))),/(\d+) (\d+)/g,$calc(\1 * 256 + \2)) }
  return $regsubex($bvar($1,$regsubex($2,/(\d+)/g,$calc((\t -1) * 2 + \n))),/(\d+) (\d+)/g,$calc(\1 * 256 + \2))
}


Examples of usage:
bset16 &a 1 255 512 768 1024 65530
echo -a Size: $bvar16(&a,0) vs $bvar(&a,0) ...
echo -a Single Position: $Bvar16(&a,2) == $bvar(&a,3-4) ...
echo -a Multiples Example: $bvar16(&a,1-3) vs $bvar(&a,1-6)

Output
===============
Size: 5 vs 10 ...
Single Position: 512 vs 2 0 ...
Multiples Example: 255 512 768 vs 0 255 2 0 3 0

And here's another snippet for bitwise operations up to $calc()'s 53bit limitation incorporating the hi/low breakdown:

Code:
bitwise53 {
  var %hi = 2147483648 , %a = $calc($1 // %hi) , %b = $calc($1 % %hi)
  if ($prop == isbit) { 
    if ($2 <= 31) { return $isbit(%b,$2) }
    else { return $isbit(%a,$calc($2 - 31)) }
  }
  elseif ($istok(biton bitoff,$prop,32)) {
    if ($2 <= 31) { 
      if ($prop == biton) { var %b = $biton(%b,$2) }
      else { var %b = $bitoff(%b,$2) }
    }
    else { 
      if ($prop == biton) { var %a = $biton(%a,$calc($2 - 31)) }
      else { var %a = $bitoff(%a,$calc($2 - 31)) }
    }
    return $calc(%a * %hi + %b)
  }
  elseif ($istok(and or xor not,$prop,32)) {
    var %c = $calc($2 // %hi) , %d = $calc($2 % %hi)
    if ($prop == and) { return $calc($and(%a,%c) * %hi + $and(%b,%d)) }
    if ($prop == or) { return $calc($or(%a,%c) * %hi + $or(%b,%d)) }
    if ($prop == xor) { return $calc($xor(%a,%c) * %hi + $xor(%b,%d)) }
    if ($prop == not) { return $calc($not(%a,%c) * %hi + $not(%b,%d)) }
  }
}


Usage: $Bitwise53(A,N).<prop>
Props are: isbit, biton, bitoff, and, or, xor, not

By breaking a number down into two smaller numbers representing the Hi/low, you're able to achieve 53 bit accuracy manipulation greater than mIRC's internal limitation of 32bits for these functions.

we will use: 6051711999279104
in binary is: 10101100000000000000000000000000000000000000000000000

Example:
var %x = 6051711999279104
echo -a $bitwise53(%x,53).isbit
echo -a $bitwise53(%x,52).isbit
echo -a $bitwise53(%x,51).isbit
echo -a $bitwise53(%x,50).isbit
echo -a $bitwise53(%x,49).isbit
echo -a $bitwise53(%x,48).isbit
echo -a $bitwise53(%x,47).isbit

Output
===============
1
0
1
0
1
1
0

Re: Expanded Binary Variable handlers [Re: Talon] #265358 04/04/19 07:16 AM
Joined: Jan 2004
Posts: 1,173
maroon Offline
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,173
If the above does not result in a modification of $bvar, then this is a related feature request to update the /help $bvar documentation. As written now, it looks like "The word, nword, long, and nlong properties return values in host or network byte order" means that these .props should return multiple values, but instead the .prop is ignored if the M parameter is anything except 1. If range greater than 1 is invalid in combination with these .props, it should either be an error or $null rather than reverting to returning byte values instead.