Skip to content

Commit

Permalink
Proposed fix for compare-bytes comparator function
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Fingerhut committed May 23, 2019
1 parent 3e0822b commit 6bc9799
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/byte_streams.clj
Expand Up @@ -895,7 +895,20 @@
(p/int->uint (.getInt b (p/+ idx b-offset))))]
(if (p/== 0 cmp)
(recur (p/+ idx 4))
(p/* sign cmp)))))]
;; Use (if (pos? cmp) 1 -1) to ensure that the
;; sign of the value x returned by cmp-bufs (and
;; compare-bytes) is not modified when Clojure's
;; comparator infrastructure calls (.intValue
;; x). The intValue method truncates a Java
;; Long's most significant 32 bits away, which
;; in some cases changes the sign of the result,
;; and thus the direction of the comparison
;; result. Such code is not needed when
;; comparing individual bytes below, because the
;; subtraction result fits within the least
;; significant 9 bits, and (.intValue x) never
;; changes the sign.
(p/* sign (if (pos? cmp) 1 -1))))))]
(if (p/== 0 (long cmp))
(let [limit' (.remaining a)]
(loop [idx limit]
Expand Down
6 changes: 6 additions & 0 deletions test/byte_streams_test.clj
Expand Up @@ -138,3 +138,9 @@
(is (bytes= text-bytes (-> text-bytes to-string to-byte-array)))
(is (bytes= text-bytes (-> text-bytes to-input-stream to-string to-byte-array)))
(is (bytes= text-bytes (-> text-bytes (to-input-stream {:chunk-size 128}) to-string to-byte-array)))))

(deftest compare-bytes-former-bug
(let [bx (convert (byte-array [0x00 0x00 0x00 0x01]) java.nio.ByteBuffer)
by (convert (byte-array [0x80 0x00 0x00 0x01]) java.nio.ByteBuffer)]
(is (= [bx by] (sort compare-bytes [bx by])))
(is (= [bx by] (sort compare-bytes [by bx])))))

0 comments on commit 6bc9799

Please sign in to comment.