World: r3wp
[I'm new] Ask any question, and a helpful person will try to answer.
older newer | first last |
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... | |
Davide 26-Jun-2010 [3790x2] | fork you probably are right, but I still think that length? none should not stop the script with an error. Could'n it produce a "warnig" only or a catchable error instead? |
like "error_reporting(x)" in php let me choose which kind of error intercept | |
Fork 26-Jun-2010 [3792] | Well Rebol is very flexible, if you disagree with the choices made you can indeed write your own LENG? or whatever which reacts specially to NONE and says 0. |
Henrik 26-Jun-2010 [3793] | what I do is normally wrap such code in an ALL block. NONE can mean so many things and it's best to trap a NONE where you know it appears during an operation that requires a series as input. |
Fork 26-Jun-2010 [3794] | But 90% of the time, when you find a Rebol decision when you are not used to the language and study it after a time you will find it was made after a lot of deliberation. |
Henrik 26-Jun-2010 [3795] | Right. Many designs in later REBOL versions are based on code patterns after writing many scripts in early REBOL versions. |
Fork 26-Jun-2010 [3796] | For better or worse, this thing has been cooked and tweaked for far more than a decade... so there's a lot of experience guiding the choices, especially if you're using R3. (R2 had rather more clunky edges to it when viewed in hindsight.) |
Henrik 26-Jun-2010 [3797x2] | most of the time you're probably masking bugs - exactly. Now if all these accepted NONE and returned 0 at the end: length? find find find my-string "a" "b" "c" == 0 where would the error be? |
in an opposite, REMOVE supports NONE: remove find string "something" | |
older newer | first last |