diff --git a/pom.xml b/pom.xml index 144b849..94c861d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 data.codec - 0.1.2-SNAPSHOT + 0.2.0-SNAPSHOT data.codec diff --git a/project.clj b/project.clj index 91f9fb5..3d9c1f6 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject org.clojure/data.codec "0.1.2-SNAPSHOT" +(defproject org.clojure/data.codec "0.2.0-SNAPSHOT" :description "Clojure codec implementations." :url "https://github.com/clojure/data.codec" :license {:name "Eclipse Public License" diff --git a/src/main/clojure/clojure/data/codec/base64.clj b/src/main/clojure/clojure/data/codec/base64.clj index b9dda11..9b5e6c9 100644 --- a/src/main/clojure/clojure/data/codec/base64.clj +++ b/src/main/clojure/clojure/data/codec/base64.clj @@ -148,6 +148,15 @@ dest))) +(defn str->decode + "Returns a decoded byte array from the given base64 encoded string. + + Note: length must be a multiple of 4." + ([^String input] + (let [bytes (.getBytes input "US-ASCII")] + (decode bytes 0 (alength bytes))))) + + (defn encode! "Reads from the input byte array for the specified length starting at the offset index, and base64 encodes into the output array starting at index 0. Returns the @@ -233,6 +242,15 @@ (encode! input offset length dest) dest))) +(defn encode->str + "Returns a base64 encoded string of the provided byte array." + ([^bytes input] + (encode->str input 0 (alength input))) + ([^bytes input ^long offset ^long length] + (let [dest (byte-array (enc-length length))] + (encode! input offset length dest) + (String. dest "US-ASCII")))) + (defn- read-fully "Will fill the buffer to capacity, or with whatever is left in the input. diff --git a/src/test/clojure/clojure/data/codec/test_base64.clj b/src/test/clojure/clojure/data/codec/test_base64.clj index 66ef527..c6e00f8 100644 --- a/src/test/clojure/clojure/data/codec/test_base64.clj +++ b/src/test/clojure/clojure/data/codec/test_base64.clj @@ -2,7 +2,7 @@ (:import org.apache.commons.codec.binary.Base64 java.io.ByteArrayInputStream java.io.ByteArrayOutputStream) - (:require [clojure.test :refer [deftest is]] + (:require [clojure.test :refer [deftest is]] [clojure.test.check :as tc] [clojure.test.check.clojure-test :refer [defspec]] [clojure.test.check.generators :as gen] @@ -17,9 +17,9 @@ (defn aeq? ([a b] - (= (seq a) (seq b))) + (= (seq a) (seq b))) ([a b len] - (= (take len a) (take len b)))) + (= (take len a) (take len b)))) (defn copy-bytes ^bytes [array offset length] (let [arr (byte-array length)] @@ -29,15 +29,25 @@ (defn expected-enc (^bytes [input] - (Base64/encodeBase64 input)) + (Base64/encodeBase64 input)) (^bytes [input offset length] - (Base64/encodeBase64 (copy-bytes input offset length)))) + (Base64/encodeBase64 (copy-bytes input offset length)))) + +(defn expected-enc-str + (^bytes [input] + (Base64/encodeBase64String input)) + (^bytes [input offset length] + (Base64/encodeBase64String (copy-bytes input offset length)))) (defn expected-dec (^bytes [^bytes input] - (Base64/decodeBase64 input)) + (Base64/decodeBase64 input)) (^bytes [input offset length] - (Base64/decodeBase64 (copy-bytes input offset length)))) + (Base64/decodeBase64 (copy-bytes input offset length)))) + +(defn expected-str-dec + ^bytes [^String input] + (Base64/decodeBase64 input)) (defn gen-discrete [min max base] (let [min (quot min base) @@ -46,29 +56,31 @@ (defn gen-with-offset-length [gen-array step] (gen/bind gen-array - (fn [^bytes array] - (if (zero? (alength array)) - (gen/tuple (gen/return array) - (gen/return -1) - (gen/return 0)) - (gen/bind (gen-discrete 0 (dec (alength array)) step) - (fn [len] - (gen/tuple - (gen/return array) - (gen-discrete 0 (- (alength array) len) step) - (gen/return len)))))))) + (fn [^bytes array] + (if (zero? (alength array)) + (gen/tuple (gen/return array) + (gen/return -1) + (gen/return 0)) + (gen/bind (gen-discrete 0 (dec (alength array)) step) + (fn [len] + (gen/tuple + (gen/return array) + (gen-discrete 0 (- (alength array) len) step) + (gen/return len)))))))) (def gen-bytes-offset-length (gen-with-offset-length gen/bytes 1)) (def gen-encbytes (gen/fmap #(Base64/encodeBase64 %) gen/bytes)) +(def gen-encstr (gen/fmap #(Base64/encodeBase64String %) gen/bytes)) + (def gen-encbytes-offset-length (gen-with-offset-length gen-encbytes 4)) (defspec check-encode! (prop/for-all [[^bytes input offset length] gen-bytes-offset-length] - (let [dest (byte-array (* 2 (alength input))) + (let [dest (byte-array (* 2 (alength input))) enc-len (encode! input offset length dest) - exp (expected-enc input offset length)] + exp (expected-enc input offset length)] (and (= enc-len (alength exp)) (aeq? dest exp enc-len))))) @@ -87,32 +99,50 @@ exp (expected-enc input offset length)] (aeq? enc exp)))) +(defspec check-encode->str-1 + (prop/for-all [^bytes input gen/bytes] + (let [enc (encode->str input) + exp (expected-enc-str input)] + (= enc exp)))) + +(defspec check-encode->str-3 + (prop/for-all [[^bytes input offset length] gen-bytes-offset-length] + (let [enc (encode->str input offset length) + exp (expected-enc-str input offset length)] + (= enc exp)))) + (defspec check-decode! (prop/for-all [[^bytes input offset length] gen-encbytes-offset-length] - (let [dest (byte-array (alength input)) - dec-len (decode! input offset length dest) - exp (expected-dec input offset length)] - (and (= dec-len (alength exp)) - (aeq? dest exp dec-len))))) + (let [dest (byte-array (alength input)) + dec-len (decode! input offset length dest) + exp (expected-dec input offset length)] + (and (= dec-len (alength exp)) + (aeq? dest exp dec-len))))) (deftest test-decode!-prim (is (instance? clojure.lang.IFn$OLLOL decode!))) (defspec check-decode-1 (prop/for-all [^bytes input gen-encbytes] - (let [dec (decode input) - exp (expected-dec input)] - (aeq? dec exp)))) + (let [dec (decode input) + exp (expected-dec input)] + (aeq? dec exp)))) (defspec check-decode-3 (prop/for-all [[^bytes input offset length] gen-encbytes-offset-length] - (let [dec (decode input offset length) - exp (expected-dec input offset length)] - (aeq? dec exp)))) + (let [dec (decode input offset length) + exp (expected-dec input offset length)] + (aeq? dec exp)))) + +(defspec check-str->decode + (prop/for-all [^String input gen-encstr] + (let [dec (str->decode input) + exp (expected-str-dec input)] + (aeq? dec exp)))) (defspec check-encoding-transfer-default-buffer-size (prop/for-all [input gen/bytes] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (encoding-transfer in out) (aeq? (.toByteArray out) (expected-enc input))))) @@ -120,14 +150,14 @@ (defspec check-encoding-transfer-buffer-size (prop/for-all [input gen/bytes buffer-size (gen/fmap #(* 3 %) (gen/fmap inc gen/nat))] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (encoding-transfer in out :buffer-size buffer-size) (aeq? (.toByteArray out) (expected-enc input))))) (defspec check-encoding-transfer-bad-buffer-size (prop/for-all [input gen/bytes] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (try (encoding-transfer in out :buffer-size 2) @@ -137,7 +167,7 @@ (defspec check-decoding-transfer-default-buffer-size (prop/for-all [input gen-encbytes] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (decoding-transfer in out) (aeq? (.toByteArray out) (expected-dec input))))) @@ -145,14 +175,14 @@ (defspec check-decoding-transfer-buffer-size (prop/for-all [input gen-encbytes buffer-size (gen/fmap #(* 4 %) (gen/fmap inc gen/nat))] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (decoding-transfer in out :buffer-size buffer-size) (aeq? (.toByteArray out) (expected-dec input))))) (defspec check-decoding-transfer-bad-buffer-size (prop/for-all [input gen-encbytes] - (let [in (ByteArrayInputStream. input) + (let [in (ByteArrayInputStream. input) out (ByteArrayOutputStream.)] (try (decoding-transfer in out :buffer-size 2)