r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[I'm new] Ask any question, and a helpful person will try to answer.

Ladislav
21-Jun-2010
[3737]
the use of Mold is something I would discourage to use for this purpose
Maxim
21-Jun-2010
[3738]
the denominator is handling the return type, which is consistent 
with how you'd express the division in real life.
BrianH
21-Jun-2010
[3739x2]
No string conversion, no floating point division(?); we have a winner!
I still like the "Use R3" method, but that is not always practical 
:(
Graham
21-Jun-2010
[3741]
How about .. use R2 1.7.8 ?
BrianH
21-Jun-2010
[3742]
Fixing conversions is not on the roadmap for 2.7.8.
Graham
21-Jun-2010
[3743]
ok, 2.7.9 then
Davide
21-Jun-2010
[3744]
thanks for the quick answers! you guys are great


I'm building a function that computes the challenging code for  web 
socket  protocol, 

It uses unsigned 32 bit integer, so I use money instead of integer, 
to avoid overflow.
Ladislav
21-Jun-2010
[3745]
there is no advantage to use money in R2 against the decimals, they 
are pretty much the same in R2
Davide
21-Jun-2010
[3746x2]
(by the way, which is the best method to convert 32 bit integer to 
4 byte string big endian ?)
thanks ladislav, I will use decimal.
BrianH
21-Jun-2010
[3748]
Does it have to be a string, or will binary do?
Davide
21-Jun-2010
[3749x3]
I think binary would be ok too...
this is my quick & dirty func:
int-2-char: func [n [decimal!] /local ret] [
			ret: copy "" 
			repeat k [16777216 65536 256 1] [
				append ret to char! (n / k)
				n: modulo n k
			]
			ret
		]
BrianH
21-Jun-2010
[3752]
That function would be sped up by unrolling the loop.
Ladislav
21-Jun-2010
[3753x3]
one way is to use my http://www.fm.tul.cz/~ladislav/rebol/peekpoke.r
(you can find other conversions in there)
and, btw, unsigned and signed integers differ only in interpretation, 
using the same representation
Davide
21-Jun-2010
[3756x5]
thanks ladislav, but I prefer a small routine ad hoc instead of a 
generic and more complex one.
I have to be small with this code
here we go:

int-2-char: func [n [decimal!] /local ret] [
	ret: copy "" 
	append ret to char! (n / 16777216) n: modulo n 16777216
	append ret to char! (n / 65536) n: modulo n 65536
	append ret to char! (n / 256) n: modulo n 256
	append ret to char! n			
	
	ret
]
mmm there's something strange, with the first version of the function 
the protocol works, 

with the second version every 10-20 times the protocol fails to estabilish
<poker face>
they return the same values, maybe some side-effects ?
BrianH
21-Jun-2010
[3761x4]
Some standard R2 optimizations, but compare results to be sure, I 
might have messed it up:

int-2-char: func [n [integer! decimal!]] [
	n: to integer! n
	head insert insert insert insert make string! 4
		to char! n / 16777216
		to char! (n // 16777216) / 65536 
		to char! (n // 65536) / 256
		to char! n // 256
]
You messed up by using decimal. Integer division has different properties 
than decimal.
Crap, I messed it up too, / returns decimal in R2.
I should use SHIFT instead of // here.
Davide
21-Jun-2010
[3765]
ah ok  good to know !
BrianH
21-Jun-2010
[3766x3]
Switching to bitwise operations:

int-2-char: func [n [integer! decimal!]] [
	n: to integer! n
	head insert insert insert insert make string! 4
		to char! shift/logical n 24
		to char! 255 and shift/logical n 16
		to char! 255 and shift/logical n 8
		to char! 255 and n
]
Note that this is R2 code, and it depends on R2's 32bit integers 
and SHIFT behavior.
Davide
21-Jun-2010
[3769]
umh... but this fails if I pass a number > 2^31
BrianH
21-Jun-2010
[3770x2]
Try the last version then, tell me if it works.
Perhaps removing the n: to integer! n from the math version, instead 
of the bitwise version.
Davide
21-Jun-2010
[3772x3]
your function works well, but I'm getting random protocol fails
It's strange ... every 40-50 times chrome does not connect to ws 
on the server
need to sleep. 
Thanks Brian for the help :-)
BrianH
21-Jun-2010
[3775]
It might be that the new function is fast enough that you are running 
into timing errors in Chrome...
Davide
22-Jun-2010
[3776x2]
The bug was my fault, I was using a wrong variable name.
Thanks all for the help.

The complete (working) function to calculate the challenging code 
server side in web socket protocol is:

ws-chall: funct [header [string!]] [		
	
	cnt: funct [k] [
		n: copy "" 
		ns: 0 
		repeat x k [
			if all [x >= #"0" x <= #"9"][
				append n x
			] 
			if x = #" " [
				ns: ns + 1
			]
		]
		if ns = 0 [
			return none
		]			
		(to decimal! n) / ns
	]
	
	int-2-char: funct [n [integer! decimal!]] [
		;n: to decimal! n
		head insert insert insert insert make string! 4
			to char! n / 16777216
			to char! (n // 16777216) / 65536 
			to char! (n // 65536) / 256
			to char! n // 256
	]

	attempt [
		t: parse/all replace/all header crlf lf "^/"

  l: copy [] repeat x t [if n: find x ":" [insert tail l reduce [copy/part 
  x (index? n) - 1 next n]]] l: head l
		k1: next select l "Sec-WebSocket-Key1"
		k2: next select l "Sec-WebSocket-Key2"
		k3: next next find header "^/^/"
		aux1: cnt k1
		aux2: cnt k2
	]

	if any [none? aux1 none? aux2 none? k3] [return ""]

 to-string checksum/method rejoin [int-2-char aux1 int-2-char aux2 
 k3] 'md5		
]
the protocol is described here: http://www.whatwg.org/specs/web-socket-protocol/
Davide
26-Jun-2010
[3778]
why  join "a" find "x" "abc" gives "anone" ? Is it useful ?
Henrik
26-Jun-2010
[3779]
JOIN concatenates based on the first argument datatype.
Sunanda
26-Jun-2010
[3780]
[Henrik was faster] so the second argument gets changed to the type 
of the first. Or, failing that, both are changed to string!
Try these to see:
   join "a" [1 2 3]
   join 26-jun-2010 "999"
Davide
26-Jun-2010
[3781x3]
this seems correct, but none isn't a special type?  I would like 
to use it as "neutral value" in operations
IMHO join "a" none should give "a" , length? none should give 0 and 
next none should give none
because every time I use "find" I have to check the return value
Fork
26-Jun-2010
[3784x3]
@Davide: I've actually thought the same thing about none, with respect 
to joining (though I think [0 = length? none] would be unwise, just 
as [true = true? 0] would be a mistake).
Yet in Rebol sometimes the "tail wags the dog"... there are often 
deeply entrenched reasons where some implementation detail of how 
X functionality is built on top of Y functionality means you get 
a certain behavior... like, if none didn't print as "none" it would 
break the reflection model or something with MOLD.  The go-to person 
on telling you the underlying facts of the matter is generally BrianH. 
 :)
Rebol programming can be very much like a trapeze without a safety 
net.  I have bent some of the rules in a dialect I made where (for 
instance) you can use constants or words as the clauses in if or 
either conditions.  So you can write things like [str: either condition 
"truestring" "falsestring"], instead of [str: either condition ["truestring"] 
["falsestring"]]