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.

BrianH
21-Jun-2010
[3740]
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
[3784x6]
@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"]]
Rebol could do this by default, but people screw up enough as it 
is.  Is it worth the potential errors to allow this?  Absolutely 
not...
I think your "none = next none" falls in that category as well... 
it can be useful here or there, sure, but most of the time you're 
probably masking bugs.
Or making them harder to find...