Permalink
Browse files

Remove calc requirement, based on observations and suggestions by Jul…

…ian Scheid.
  • Loading branch information...
ahyatt committed Sep 2, 2012
1 parent 36d675f commit d29b171b812893b30fa0b86eebbaf548518992f9
Showing with 26 additions and 27 deletions.
  1. +5 −4 websocket-test.el
  2. +21 −23 websocket.el
View
@@ -51,10 +51,11 @@
(ert-deftest websocket-get-bytes ()
(should (equal #x5 (websocket-get-bytes "\x5" 1)))
(should (equal #x101 (websocket-get-bytes "\x1\x1" 2)))
- (let ((f (lambda () (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8))))
- (if websocket-test-64-bit-p
- (should (equal #x100000001 (funcall f)))
- (should-error (funcall f) :type 'websocket-unparseable-frame)))
+ (should (equal #xffffff
+ (websocket-get-bytes "\x0\x0\x0\x0\x0\xFF\xFF\xFF" 8)))
+ (when websocket-test-64-bit-p
+ (should-error (websocket-get-bytes "\x0\x0\x0\x1\x0\x0\x0\x1" 8)
+ :type 'websocket-unparseable-frame))
(should-error (websocket-get-bytes "\x0\x0\x0" 3))
(should-error (websocket-get-bytes "\x0" 2) :type 'websocket-unparseable-frame))
View
@@ -47,7 +47,6 @@
(require 'bindat)
(require 'url-parse)
-(require 'calc)
(eval-when-compile (require 'cl))
;;; Code:
@@ -197,16 +196,18 @@ This is based on the KEY from the Sec-WebSocket-Key header."
(defun websocket-get-bytes (s n)
"From string S, retrieve the value of N bytes.
Return the value as an unsigned integer. The value N must be a
-power of 2, up to 8."
+power of 2, up to 8.
+
+We support getting frames up to 4294967295 bytes (2^32) long."
(if (= n 8)
(let* ((32-bit-parts
(bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val))
- (cval (calc-eval '("(2^32 * $ + $$)") nil
- (aref 32-bit-parts 0) (aref 32-bit-parts 1))))
- (when (calc-eval '("$ > $$") 'pred cval most-positive-fixnum)
+ (cval
+ (logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1))))
+ (if (= (aref 32-bit-parts 0) 0)
+ cval
(signal 'websocket-unparseable-frame
- "Frame value found too large to parse!"))
- (string-to-number cval))
+ "Frame value found too large to parse!")))
;; n is not 8
(bindat-get-field
(condition-case err
@@ -226,26 +227,23 @@ power of 2, up to 8."
(defun websocket-to-bytes (val nbytes)
"Encode the integer VAL in NBYTES of data.
-NBYTES much be a power of 2, up to 8."
- (unless (or (and (< nbytes 8)
- (< val (expt 2 (* 8 nbytes))))
- (and (= nbytes 8)
- (calc-eval "% < 2^(8 * %%)" 'pred val nbytes)))
+NBYTES much be a power of 2, up to 8.
+
+This supports encoding values up to "
+ (when (and (< nbytes 8)
+ (> val (expt 2 (* 8 nbytes))))
;; not a user-facing error, this must be caused from an error in
;; this library
(error "websocket-to-bytes: Value %d could not be expressed in %d bytes"
val nbytes))
(if (= nbytes 8)
(progn
- (when (calc-eval "$ < 4294967296" 'pred most-positive-fixnum)
- (signal 'websocket-frame-too-large
- most-positive-fixnum))
- ;; Need to use calc even though at this point things are manageable,
- ;; since some emacs cannot parse the value 4294967296, even if
- ;; they never evaluate it.
- (bindat-pack `((:val vec 2 u32))
- `((:val . [,(calc-eval "floor($ / 4294967296)" 'raw val)
- ,(calc-eval "$ % 4294967296" 'raw val)]))))
+ (let ((hi-32bits (lsh val -32))
+ (low-32bits (logand #xffffffff val)))
+ (when (> hi-32bits 0)
+ (signal 'websocket-frame-too-large val))
+ (bindat-pack `((:val vec 2 u32))
+ `((:val . [,hi-32bits ,low-32bits])))))
(bindat-pack
`((:val ,(cond ((= nbytes 1) 'u8)
((= nbytes 2) 'u16)
@@ -507,8 +505,8 @@ also the frame.
The frame may be too large for this buid of emacs, in which case
`websocket-frame-too-large' is returned, with the data of the
-system's `most-positive-fixnum', whose length was exceeded. This
-also has the `websocket-error' condition."
+size of the frame which was too large to process. This also has
+the `websocket-error' condition."
(unless (websocket-check frame)
(signal 'websocket-illegal-frame frame))
(websocket-debug websocket "Sending frame, opcode: %s payload: %s"

0 comments on commit d29b171

Please sign in to comment.