├── .gitignore ├── .github └── workflows │ ├── test.yml │ ├── snapshot.yml │ ├── doc-build.yml │ └── release.yml ├── CONTRIBUTING.md ├── project.clj ├── src ├── perf │ └── clojure │ │ └── clojure │ │ └── data │ │ └── codec │ │ └── perf_base64.clj ├── test │ └── clojure │ │ └── clojure │ │ └── data │ │ └── codec │ │ └── test_base64.clj └── main │ └── clojure │ └── clojure │ └── data │ └── codec │ └── base64.clj ├── README.md ├── pom.xml ├── LICENSE └── epl.html /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | bin/ 3 | classes/ 4 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push] 4 | 5 | jobs: 6 | call-test: 7 | uses: clojure/build.ci/.github/workflows/test.yml@master 8 | -------------------------------------------------------------------------------- /.github/workflows/snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Snapshot on demand 2 | 3 | on: [workflow_dispatch] 4 | 5 | jobs: 6 | call-snapshot: 7 | uses: clojure/build.ci/.github/workflows/snapshot.yml@master 8 | secrets: inherit 9 | -------------------------------------------------------------------------------- /.github/workflows/doc-build.yml: -------------------------------------------------------------------------------- 1 | name: Build API Docs 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | call-doc-build-workflow: 8 | uses: clojure/build.ci/.github/workflows/doc-build.yml@master 9 | with: 10 | project: clojure/data.codec 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This is a [Clojure contrib] project. 2 | 3 | Under the Clojure contrib [guidelines], this project cannot accept 4 | pull requests. All patches must be submitted via [JIRA]. 5 | 6 | See [Contributing] on the Clojure website for 7 | more information on how to contribute. 8 | 9 | [Clojure contrib]: https://clojure.org/community/contrib_libs 10 | [Contributing]: https://clojure.org/community/contributing 11 | [JIRA]: https://clojure.atlassian.net/browse/DCODEC 12 | [guidelines]: https://clojure.org/community/contrib_howto 13 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release on demand 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | releaseVersion: 7 | description: "Version to release" 8 | required: true 9 | snapshotVersion: 10 | description: "Snapshot version after release" 11 | required: true 12 | 13 | jobs: 14 | call-release: 15 | uses: clojure/build.ci/.github/workflows/release.yml@master 16 | with: 17 | releaseVersion: ${{ github.event.inputs.releaseVersion }} 18 | snapshotVersion: ${{ github.event.inputs.snapshotVersion }} 19 | secrets: inherit -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject org.clojure/data.codec "0.1.2-SNAPSHOT" 2 | :description "Clojure codec implementations." 3 | :url "https://github.com/clojure/data.codec" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :source-paths ["src/main/clojure"] 7 | :test-paths ["src/test/clojure"] 8 | :dependencies [[org.clojure/clojure "1.9.0"]] 9 | :aliases {"perf" ["with-profile" "perf" "run"]} 10 | :profiles {:dev {:dependencies [[org.clojure/test.check "1.1.1"] 11 | [commons-codec "1.16.1"]] 12 | :plugins [[lein-cloverage "1.0.9"]]} 13 | :perf {:dependencies [[commons-codec "1.16.1"] 14 | [criterium "0.4.6"]] 15 | :source-paths ["src/perf/clojure"] 16 | :main clojure.data.codec.perf-base64}}) 17 | -------------------------------------------------------------------------------- /src/perf/clojure/clojure/data/codec/perf_base64.clj: -------------------------------------------------------------------------------- 1 | (ns clojure.data.codec.perf-base64 2 | (:import org.apache.commons.codec.binary.Base64) 3 | (:use clojure.test 4 | clojure.data.codec.base64) 5 | (:require [criterium.core :as crit])) 6 | 7 | (set! *warn-on-reflection* true) 8 | 9 | (defn rand-bytes [n] 10 | (->> #(byte (- (rand-int 256) 128)) 11 | (repeatedly n) 12 | (byte-array n))) 13 | 14 | (defmacro mean [expr] 15 | `(-> ~expr (crit/quick-benchmark {}) :mean first)) 16 | 17 | (defn -main [& _] 18 | (let [byte-counts [1e2 1e4 1e6] 19 | byte-arrays (map rand-bytes byte-counts) 20 | encoded-arrays (map encode byte-arrays)] 21 | (binding [crit/*final-gc-problem-threshold* 1] 22 | (printf "%23s %14s%n" "base64.clj" "commons-codec") 23 | (println "encode:") 24 | (flush) 25 | (doseq [^bytes ba byte-arrays] 26 | (printf "%7dB %ems %ems%n" (alength ba) (mean (encode ba)) (mean (Base64/encodeBase64 ba))) 27 | (flush)) 28 | (println "decode:") 29 | (doseq [^bytes ba encoded-arrays] 30 | (printf "%7dB %ems %ems%n" (alength ba) (mean (decode ba)) (mean (Base64/decodeBase64 ba))) 31 | (flush))))) 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # data.codec 2 | 3 | Native codec implementations. Currently only base64 has been implemented. 4 | 5 | API documentation: https://clojure.github.io/data.codec 6 | 7 | ## base64 8 | 9 | NOTE: Superseded by [Base64](https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html), included in the JDK since Java 8. 10 | 11 | Implements the standard base64 encoding character set, but does not yet support automatic fixed line-length encoding. 12 | 13 | All operations work on either byte arrays or Input/OutputStreams. 14 | 15 | Performance is on par with Java implementations, e.g., Apache commons-codec. 16 | 17 | ### Example Usage 18 | 19 | Transform a binary file into a base64 encoded file: 20 | 21 | ```clojure 22 | (require '[clojure.data.codec.base64 :as b64] 23 | '[clojure.java.io :as io]) 24 | 25 | (with-open [in (io/input-stream "input.bin") 26 | out (io/output-stream "output.b64")] 27 | (b64/encoding-transfer in out)) 28 | ``` 29 | 30 | ## Installation 31 | 32 | The data.codec library is available in Maven central. Add it to your Maven project's `pom.xml`: 33 | 34 | 35 | org.clojure 36 | data.codec 37 | 0.1.1 38 | 39 | 40 | or your leiningen `project.clj`: 41 | 42 | [org.clojure/data.codec "0.1.1"] 43 | 44 | ## License 45 | 46 | Copyright © Alex Taggart, Rich Hickey, and contributors 47 | 48 | Licensed under the EPL. (See the file epl.html.) 49 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | data.codec 4 | 0.2.1-SNAPSHOT 5 | data.codec 6 | Native codec implementations. 7 | 8 | 9 | org.clojure 10 | pom.contrib 11 | 1.3.0 12 | 13 | 14 | 15 | 16 | Alex Taggart 17 | 18 | 19 | 20 | 21 | scm:git:git@github.com:clojure/data.codec.git 22 | scm:git:git@github.com:clojure/data.codec.git 23 | git@github.com:clojure/data.codec.git 24 | HEAD 25 | 26 | 27 | 28 | 1.9.0 29 | true 30 | 31 | 32 | 33 | 34 | org.clojure 35 | test.check 36 | 1.1.1 37 | test 38 | 39 | 40 | commons-codec 41 | commons-codec 42 | 1.16.1 43 | test 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/test/clojure/clojure/data/codec/test_base64.clj: -------------------------------------------------------------------------------- 1 | (ns clojure.data.codec.test-base64 2 | (:import org.apache.commons.codec.binary.Base64 3 | java.io.ByteArrayInputStream 4 | java.io.ByteArrayOutputStream) 5 | (:require [clojure.test :refer [deftest is]] 6 | [clojure.test.check :as tc] 7 | [clojure.test.check.clojure-test :refer [defspec]] 8 | [clojure.test.check.generators :as gen] 9 | [clojure.test.check.properties :as prop]) 10 | (:use clojure.data.codec.base64)) 11 | 12 | (set! *warn-on-reflection* true) 13 | 14 | (defmethod print-method (class (byte-array 0)) [bytes, ^java.io.Writer w] 15 | (.write w "#bytes") 16 | (print-method (vec bytes) w)) 17 | 18 | (defn aeq? 19 | ([a b] 20 | (= (seq a) (seq b))) 21 | ([a b len] 22 | (= (take len a) (take len b)))) 23 | 24 | (defn copy-bytes ^bytes [array offset length] 25 | (let [arr (byte-array length)] 26 | (when (pos? length) 27 | (System/arraycopy array offset arr 0 length)) 28 | arr)) 29 | 30 | (defn expected-enc 31 | (^bytes [input] 32 | (Base64/encodeBase64 input)) 33 | (^bytes [input offset length] 34 | (Base64/encodeBase64 (copy-bytes input offset length)))) 35 | 36 | (defn expected-dec 37 | (^bytes [^bytes input] 38 | (Base64/decodeBase64 input)) 39 | (^bytes [input offset length] 40 | (Base64/decodeBase64 (copy-bytes input offset length)))) 41 | 42 | (defn gen-discrete [min max base] 43 | (let [min (quot min base) 44 | max (quot max base)] 45 | (gen/fmap #(* base %) (gen/large-integer* {:min min :max max})))) 46 | 47 | (defn gen-with-offset-length [gen-array step] 48 | (gen/bind gen-array 49 | (fn [^bytes array] 50 | (if (zero? (alength array)) 51 | (gen/tuple (gen/return array) 52 | (gen/return -1) 53 | (gen/return 0)) 54 | (gen/bind (gen-discrete 0 (dec (alength array)) step) 55 | (fn [len] 56 | (gen/tuple 57 | (gen/return array) 58 | (gen-discrete 0 (- (alength array) len) step) 59 | (gen/return len)))))))) 60 | 61 | (def gen-bytes-offset-length (gen-with-offset-length gen/bytes 1)) 62 | 63 | (def gen-encbytes (gen/fmap #(Base64/encodeBase64 %) gen/bytes)) 64 | 65 | (def gen-encbytes-offset-length (gen-with-offset-length gen-encbytes 4)) 66 | 67 | (defspec check-encode! 68 | (prop/for-all [[^bytes input offset length] gen-bytes-offset-length] 69 | (let [dest (byte-array (* 2 (alength input))) 70 | enc-len (encode! input offset length dest) 71 | exp (expected-enc input offset length)] 72 | (and (= enc-len (alength exp)) 73 | (aeq? dest exp enc-len))))) 74 | 75 | (deftest test-encode!-prim 76 | (is (instance? clojure.lang.IFn$OLLOL encode!))) 77 | 78 | (defspec check-encode-1 79 | (prop/for-all [^bytes input gen/bytes] 80 | (let [enc (encode input) 81 | exp (expected-enc input)] 82 | (aeq? enc exp)))) 83 | 84 | (defspec check-encode-3 85 | (prop/for-all [[^bytes input offset length] gen-bytes-offset-length] 86 | (let [enc (encode input offset length) 87 | exp (expected-enc input offset length)] 88 | (aeq? enc exp)))) 89 | 90 | (defspec check-decode! 91 | (prop/for-all [[^bytes input offset length] gen-encbytes-offset-length] 92 | (let [dest (byte-array (alength input)) 93 | dec-len (decode! input offset length dest) 94 | exp (expected-dec input offset length)] 95 | (and (= dec-len (alength exp)) 96 | (aeq? dest exp dec-len))))) 97 | 98 | (deftest test-decode!-prim 99 | (is (instance? clojure.lang.IFn$OLLOL decode!))) 100 | 101 | (defspec check-decode-1 102 | (prop/for-all [^bytes input gen-encbytes] 103 | (let [dec (decode input) 104 | exp (expected-dec input)] 105 | (aeq? dec exp)))) 106 | 107 | (defspec check-decode-3 108 | (prop/for-all [[^bytes input offset length] gen-encbytes-offset-length] 109 | (let [dec (decode input offset length) 110 | exp (expected-dec input offset length)] 111 | (aeq? dec exp)))) 112 | 113 | (defspec check-encoding-transfer-default-buffer-size 114 | (prop/for-all [input gen/bytes] 115 | (let [in (ByteArrayInputStream. input) 116 | out (ByteArrayOutputStream.)] 117 | (encoding-transfer in out) 118 | (aeq? (.toByteArray out) (expected-enc input))))) 119 | 120 | (defspec check-encoding-transfer-buffer-size 121 | (prop/for-all [input gen/bytes 122 | buffer-size (gen/fmap #(* 3 %) (gen/fmap inc gen/nat))] 123 | (let [in (ByteArrayInputStream. input) 124 | out (ByteArrayOutputStream.)] 125 | (encoding-transfer in out :buffer-size buffer-size) 126 | (aeq? (.toByteArray out) (expected-enc input))))) 127 | 128 | (defspec check-encoding-transfer-bad-buffer-size 129 | (prop/for-all [input gen/bytes] 130 | (let [in (ByteArrayInputStream. input) 131 | out (ByteArrayOutputStream.)] 132 | (try 133 | (encoding-transfer in out :buffer-size 2) 134 | false 135 | (catch IllegalArgumentException _ 136 | true))))) 137 | 138 | (defspec check-decoding-transfer-default-buffer-size 139 | (prop/for-all [input gen-encbytes] 140 | (let [in (ByteArrayInputStream. input) 141 | out (ByteArrayOutputStream.)] 142 | (decoding-transfer in out) 143 | (aeq? (.toByteArray out) (expected-dec input))))) 144 | 145 | (defspec check-decoding-transfer-buffer-size 146 | (prop/for-all [input gen-encbytes 147 | buffer-size (gen/fmap #(* 4 %) (gen/fmap inc gen/nat))] 148 | (let [in (ByteArrayInputStream. input) 149 | out (ByteArrayOutputStream.)] 150 | (decoding-transfer in out :buffer-size buffer-size) 151 | (aeq? (.toByteArray out) (expected-dec input))))) 152 | 153 | (defspec check-decoding-transfer-bad-buffer-size 154 | (prop/for-all [input gen-encbytes] 155 | (let [in (ByteArrayInputStream. input) 156 | out (ByteArrayOutputStream.)] 157 | (try 158 | (decoding-transfer in out :buffer-size 2) 159 | false 160 | (catch IllegalArgumentException _ 161 | true))))) 162 | -------------------------------------------------------------------------------- /src/main/clojure/clojure/data/codec/base64.clj: -------------------------------------------------------------------------------- 1 | ;; by Alex Taggart 2 | ;; October 11, 2011 3 | 4 | ;; Copyright (c) Alex Taggart, October 2011. All rights reserved. The use 5 | ;; and distribution terms for this software are covered by the Eclipse 6 | ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 7 | ;; which can be found in the file epl.html at the root of this 8 | ;; distribution. By using this software in any fashion, you are 9 | ;; agreeing to be bound by the terms of this license. You must not 10 | ;; remove this notice, or any other, from this software. 11 | 12 | (ns ^{:author "Alex Taggart" 13 | :doc "Functions for working with base64 encodings."} 14 | clojure.data.codec.base64 15 | (:import [java.io InputStream OutputStream])) 16 | 17 | (set! *unchecked-math* true) 18 | (set! *warn-on-reflection* true) 19 | 20 | (def ^:private ^"[B" enc-bytes 21 | (byte-array 22 | (map (comp byte int) 23 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))) 24 | 25 | (def ^:private ^"[B" dec-bytes 26 | (let [^bytes ba (byte-array (inc (apply max enc-bytes)))] 27 | (doseq [[idx enc] (map-indexed vector enc-bytes)] 28 | (aset ba enc (unchecked-byte idx))) 29 | ba)) 30 | 31 | (defn enc-length 32 | "Calculates what would be the length after encoding of an input array of length n." 33 | ^long [^long n] 34 | (-> n 35 | (+ 2) 36 | (quot 3) 37 | (* 4))) 38 | 39 | (defn dec-length 40 | "Calculates what would be the length after decoding of an input array of length 41 | in-length with the specified padding length." 42 | ^long [^long in-length ^long pad-length] 43 | (-> in-length 44 | (quot 4) 45 | (* 3) 46 | (- pad-length))) 47 | 48 | 49 | (defn pad-length 50 | "Returns the length of padding on the end of the input array." 51 | ^long [^bytes input ^long offset ^long length] 52 | (if (zero? length) 53 | 0 54 | (let [end (+ offset length -1)] 55 | (if (== 61 (long (aget input end))) 56 | (if (== 61 (long (aget input (dec end)))) 57 | 2 58 | 1) 59 | 0)))) 60 | 61 | (defn decode! 62 | "Reads from the input byte array for the specified length starting at the offset 63 | index, and base64 decodes into the output array starting at index 0. Returns the 64 | length written to output. 65 | 66 | Note: length must be a multiple of 4." 67 | ^long [^bytes input ^long offset ^long length ^bytes output] 68 | (if (zero? length) 69 | 0 70 | (let [pad-len (pad-length input offset length) 71 | out-len (dec-length length pad-len) 72 | tail-len (rem out-len 3) 73 | loop-lim (- out-len tail-len)] 74 | (loop [i offset j 0] 75 | (if (< j loop-lim) 76 | (let [a (long (aget dec-bytes (aget input i))) 77 | b (long (aget dec-bytes (aget input (inc i)))) 78 | c (long (aget dec-bytes (aget input (+ 2 i)))) 79 | d (long (aget dec-bytes (aget input (+ 3 i)))) 80 | x1 (-> a 81 | (bit-and 0x3F) 82 | (bit-shift-left 2)) 83 | x2 (-> b 84 | (bit-shift-right 4) 85 | (bit-and 0x3)) 86 | y1 (-> 87 | (bit-and b 0xF) 88 | (bit-shift-left 4)) 89 | y2 (-> c 90 | (bit-shift-right 2) 91 | (bit-and 0xF)) 92 | z1 (-> c 93 | (bit-and 0x3) 94 | (bit-shift-left 6)) 95 | z2 (bit-and d 0x3F) 96 | x (bit-or x1 x2) 97 | y (bit-or y1 y2) 98 | z (bit-or z1 z2)] 99 | (aset output j (unchecked-byte x)) 100 | (aset output (inc j) (unchecked-byte y)) 101 | (aset output (+ 2 j) (unchecked-byte z)) 102 | (recur (+ 4 i) (+ 3 j))) 103 | 104 | ; handle padded section 105 | (case tail-len 106 | 0 j 107 | 1 (let [a (long (aget dec-bytes (aget input i))) 108 | b (long (aget dec-bytes (aget input (inc i)))) 109 | x1 (-> a 110 | (bit-and 0x3F) 111 | (bit-shift-left 2)) 112 | x2 (-> b 113 | (bit-shift-right 4) 114 | (bit-and 0x3)) 115 | x (bit-or x1 x2)] 116 | (aset output j (unchecked-byte x)) 117 | (inc j)) 118 | 2 (let [a (long (aget dec-bytes (aget input i))) 119 | b (long (aget dec-bytes (aget input (inc i)))) 120 | c (long (aget dec-bytes (aget input (+ 2 i)))) 121 | x1 (-> a 122 | (bit-and 0x3F) 123 | (bit-shift-left 2)) 124 | x2 (-> b 125 | (bit-shift-right 4) 126 | (bit-and 0x3)) 127 | y1 (-> 128 | (bit-and b 0xF) 129 | (bit-shift-left 4)) 130 | y2 (-> c 131 | (bit-shift-right 2) 132 | (bit-and 0xF)) 133 | x (bit-or x1 x2) 134 | y (bit-or y1 y2)] 135 | (aset output j (unchecked-byte x)) 136 | (aset output (inc j) (unchecked-byte y)) 137 | (+ 2 j)))))))) 138 | 139 | (defn decode 140 | "Returns a base64 decoded byte array. 141 | 142 | Note: length must be a multiple of 4." 143 | ([^bytes input] 144 | (decode input 0 (alength input))) 145 | ([^bytes input ^long offset ^long length] 146 | (let [dest (byte-array (dec-length length (pad-length input offset length)))] 147 | (decode! input offset length dest) 148 | dest))) 149 | 150 | 151 | (defn encode! 152 | "Reads from the input byte array for the specified length starting at the offset 153 | index, and base64 encodes into the output array starting at index 0. Returns the 154 | length written to output. 155 | 156 | Note: if using partial input, length must be a multiple of 3 to avoid padding." 157 | ^long [^bytes input ^long offset ^long length ^bytes output] 158 | (if (zero? length) 159 | 0 160 | (let [tail-len (rem length 3) 161 | loop-lim (- (+ offset length) tail-len)] 162 | (loop [i offset j 0] 163 | (if (< i loop-lim) 164 | (let [x (long (aget input i)) 165 | y (long (aget input (inc i))) 166 | z (long (aget input (+ 2 i))) 167 | a (-> x 168 | (bit-shift-right 2) 169 | (bit-and 0x3F)) 170 | b1 (-> x 171 | (bit-and 0x3) 172 | (bit-shift-left 4)) 173 | b2 (-> y 174 | (bit-shift-right 4) 175 | (bit-and 0xF)) 176 | b (bit-or b1 b2) 177 | c1 (-> y 178 | (bit-and 0xF) 179 | (bit-shift-left 2)) 180 | c2 (-> z 181 | (bit-shift-right 6) 182 | (bit-and 0x3)) 183 | c (bit-or c1 c2) 184 | d (bit-and z 0x3F)] 185 | (aset output j (aget enc-bytes a)) 186 | (aset output (inc j) (aget enc-bytes b)) 187 | (aset output (+ 2 j) (aget enc-bytes c)) 188 | (aset output (+ 3 j) (aget enc-bytes d)) 189 | (recur (+ 3 i) (+ 4 j))) 190 | 191 | ; write padded section 192 | (case tail-len 193 | 0 j 194 | 1 (let [x (long (aget input i)) 195 | a (-> x 196 | (bit-shift-right 2) 197 | (bit-and 0x3F)) 198 | b1 (-> x 199 | (bit-and 0x3) 200 | (bit-shift-left 4))] 201 | (aset output j (aget enc-bytes a)) 202 | (aset output (inc j) (aget enc-bytes b1)) 203 | (aset output (+ 2 j) (unchecked-byte 61)) 204 | (aset output (+ 3 j) (unchecked-byte 61)) 205 | (+ 4 j)) 206 | 2 (let [x (long (aget input i)) 207 | y (long (aget input (inc i))) 208 | a (-> x 209 | (bit-shift-right 2) 210 | (bit-and 0x3F)) 211 | b1 (-> x 212 | (bit-and 0x3) 213 | (bit-shift-left 4)) 214 | b2 (-> y 215 | (bit-shift-right 4) 216 | (bit-and 0xF)) 217 | b (bit-or b1 b2) 218 | c1 (-> y 219 | (bit-and 0xF) 220 | (bit-shift-left 2))] 221 | (aset output j (aget enc-bytes a)) 222 | (aset output (inc j) (aget enc-bytes b)) 223 | (aset output (+ 2 j) (aget enc-bytes c1)) 224 | (aset output (+ 3 j) (unchecked-byte 61)) 225 | (+ 4 j)))))))) 226 | 227 | (defn encode 228 | "Returns a base64 encoded byte array." 229 | ([^bytes input] 230 | (encode input 0 (alength input))) 231 | ([^bytes input ^long offset ^long length] 232 | (let [dest (byte-array (enc-length length))] 233 | (encode! input offset length dest) 234 | dest))) 235 | 236 | 237 | (defn- read-fully 238 | "Will fill the buffer to capacity, or with whatever is left in the input. 239 | Returns the bytes read." 240 | ; This is necessary since a partial fill from .read does not necessarily mean EOS, 241 | ; and we need full buffers to avoid incorrect padding. 242 | ^long [^InputStream input ^bytes buf] 243 | (loop [off 0 len (alength buf)] 244 | (let [in-size (.read input buf off len)] 245 | (cond 246 | (== in-size len) (+ off in-size) 247 | (neg? in-size) off 248 | :else (recur (+ off in-size) (- len in-size)))))) 249 | 250 | (defn- buf-size ^long [opts ^long default ^long multiple-of] 251 | (if-let [in-size (:buffer-size opts)] 252 | (if (zero? (rem in-size multiple-of)) 253 | in-size 254 | (throw (IllegalArgumentException. ^String (format "Buffer size must be a multiple of %d." multiple-of)))) 255 | default)) 256 | 257 | (defn decoding-transfer 258 | "Base64 decodes from input-stream to output-stream. Returns nil or throws IOException. 259 | 260 | Options are key/value pairs and may be one of 261 | :buffer-size read buffer size to use, must be a multiple of 4; default is 8192." 262 | [^InputStream input-stream ^OutputStream output-stream & opts] 263 | (let [opts (when opts (apply hash-map opts)) 264 | in-size (buf-size opts 8192 4) 265 | out-size (if (== in-size 8192) 6144 (dec-length in-size 0)) 266 | in-buf (byte-array in-size) 267 | out-buf (byte-array out-size)] 268 | (loop [] 269 | (let [in-size (read-fully input-stream in-buf)] 270 | (when (pos? in-size) 271 | (let [out-size (decode! in-buf 0 in-size out-buf)] 272 | (.write output-stream out-buf 0 out-size) 273 | (recur))))))) 274 | 275 | (defn encoding-transfer 276 | "Base64 encodes from input-stream to output-stream. Returns nil or throws IOException. 277 | 278 | Options are key/value pairs and may be one of 279 | :buffer-size read buffer size to use, must be a multiple of 3; default is 6144." 280 | [^InputStream input-stream ^OutputStream output-stream & opts] 281 | (let [opts (when opts (apply hash-map opts)) 282 | in-size (buf-size opts 6144 3) 283 | out-size (if (== in-size 6144) 8192 (enc-length in-size)) 284 | in-buf (byte-array in-size) 285 | out-buf (byte-array out-size)] 286 | (loop [] 287 | (let [in-size (read-fully input-stream in-buf)] 288 | (when (pos? in-size) 289 | (let [out-size (encode! in-buf 0 in-size out-buf)] 290 | (.write output-stream out-buf 0 out-size) 291 | (recur))))))) 292 | 293 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and documentation 12 | distributed under this Agreement, and 13 | b) in the case of each subsequent Contributor: 14 | i) changes to the Program, and 15 | ii) additions to the Program; 16 | 17 | where such changes and/or additions to the Program originate from and are 18 | distributed by that particular Contributor. A Contribution 'originates' 19 | from a Contributor if it was added to the Program by such Contributor 20 | itself or anyone acting on such Contributor's behalf. Contributions do not 21 | include additions to the Program which: (i) are separate modules of 22 | software distributed in conjunction with the Program under their own 23 | license agreement, and (ii) are not derivative works of the Program. 24 | 25 | "Contributor" means any person or entity that distributes the Program. 26 | 27 | "Licensed Patents" mean patent claims licensable by a Contributor which are 28 | necessarily infringed by the use or sale of its Contribution alone or when 29 | combined with the Program. 30 | 31 | "Program" means the Contributions distributed in accordance with this 32 | Agreement. 33 | 34 | "Recipient" means anyone who receives the Program under this Agreement, 35 | including all Contributors. 36 | 37 | 2. GRANT OF RIGHTS 38 | a) Subject to the terms of this Agreement, each Contributor hereby grants 39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 40 | reproduce, prepare derivative works of, publicly display, publicly 41 | perform, distribute and sublicense the Contribution of such Contributor, 42 | if any, and such derivative works, in source code and object code form. 43 | b) Subject to the terms of this Agreement, each Contributor hereby grants 44 | Recipient a non-exclusive, worldwide, royalty-free patent license under 45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 46 | transfer the Contribution of such Contributor, if any, in source code and 47 | object code form. This patent license shall apply to the combination of 48 | the Contribution and the Program if, at the time the Contribution is 49 | added by the Contributor, such addition of the Contribution causes such 50 | combination to be covered by the Licensed Patents. The patent license 51 | shall not apply to any other combinations which include the Contribution. 52 | No hardware per se is licensed hereunder. 53 | c) Recipient understands that although each Contributor grants the licenses 54 | to its Contributions set forth herein, no assurances are provided by any 55 | Contributor that the Program does not infringe the patent or other 56 | intellectual property rights of any other entity. Each Contributor 57 | disclaims any liability to Recipient for claims brought by any other 58 | entity based on infringement of intellectual property rights or 59 | otherwise. As a condition to exercising the rights and licenses granted 60 | hereunder, each Recipient hereby assumes sole responsibility to secure 61 | any other intellectual property rights needed, if any. For example, if a 62 | third party patent license is required to allow Recipient to distribute 63 | the Program, it is Recipient's responsibility to acquire that license 64 | before distributing the Program. 65 | d) Each Contributor represents that to its knowledge it has sufficient 66 | copyright rights in its Contribution, if any, to grant the copyright 67 | license set forth in this Agreement. 68 | 69 | 3. REQUIREMENTS 70 | 71 | A Contributor may choose to distribute the Program in object code form under 72 | its own license agreement, provided that: 73 | 74 | a) it complies with the terms and conditions of this Agreement; and 75 | b) its license agreement: 76 | i) effectively disclaims on behalf of all Contributors all warranties 77 | and conditions, express and implied, including warranties or 78 | conditions of title and non-infringement, and implied warranties or 79 | conditions of merchantability and fitness for a particular purpose; 80 | ii) effectively excludes on behalf of all Contributors all liability for 81 | damages, including direct, indirect, special, incidental and 82 | consequential damages, such as lost profits; 83 | iii) states that any provisions which differ from this Agreement are 84 | offered by that Contributor alone and not by any other party; and 85 | iv) states that source code for the Program is available from such 86 | Contributor, and informs licensees how to obtain it in a reasonable 87 | manner on or through a medium customarily used for software exchange. 88 | 89 | When the Program is made available in source code form: 90 | 91 | a) it must be made available under this Agreement; and 92 | b) a copy of this Agreement must be included with each copy of the Program. 93 | Contributors may not remove or alter any copyright notices contained 94 | within the Program. 95 | 96 | Each Contributor must identify itself as the originator of its Contribution, 97 | if 98 | any, in a manner that reasonably allows subsequent Recipients to identify the 99 | originator of the Contribution. 100 | 101 | 4. COMMERCIAL DISTRIBUTION 102 | 103 | Commercial distributors of software may accept certain responsibilities with 104 | respect to end users, business partners and the like. While this license is 105 | intended to facilitate the commercial use of the Program, the Contributor who 106 | includes the Program in a commercial product offering should do so in a manner 107 | which does not create potential liability for other Contributors. Therefore, 108 | if a Contributor includes the Program in a commercial product offering, such 109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify 110 | every other Contributor ("Indemnified Contributor") against any losses, 111 | damages and costs (collectively "Losses") arising from claims, lawsuits and 112 | other legal actions brought by a third party against the Indemnified 113 | Contributor to the extent caused by the acts or omissions of such Commercial 114 | Contributor in connection with its distribution of the Program in a commercial 115 | product offering. The obligations in this section do not apply to any claims 116 | or Losses relating to any actual or alleged intellectual property 117 | infringement. In order to qualify, an Indemnified Contributor must: 118 | a) promptly notify the Commercial Contributor in writing of such claim, and 119 | b) allow the Commercial Contributor to control, and cooperate with the 120 | Commercial Contributor in, the defense and any related settlement 121 | negotiations. The Indemnified Contributor may participate in any such claim at 122 | its own expense. 123 | 124 | For example, a Contributor might include the Program in a commercial product 125 | offering, Product X. That Contributor is then a Commercial Contributor. If 126 | that Commercial Contributor then makes performance claims, or offers 127 | warranties related to Product X, those performance claims and warranties are 128 | such Commercial Contributor's responsibility alone. Under this section, the 129 | Commercial Contributor would have to defend claims against the other 130 | Contributors related to those performance claims and warranties, and if a 131 | court requires any other Contributor to pay any damages as a result, the 132 | Commercial Contributor must pay those damages. 133 | 134 | 5. NO WARRANTY 135 | 136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN 137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each 140 | Recipient is solely responsible for determining the appropriateness of using 141 | and distributing the Program and assumes all risks associated with its 142 | exercise of rights under this Agreement , including but not limited to the 143 | risks and costs of program errors, compliance with applicable laws, damage to 144 | or loss of data, programs or equipment, and unavailability or interruption of 145 | operations. 146 | 147 | 6. DISCLAIMER OF LIABILITY 148 | 149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 156 | OF SUCH DAMAGES. 157 | 158 | 7. GENERAL 159 | 160 | If any provision of this Agreement is invalid or unenforceable under 161 | applicable law, it shall not affect the validity or enforceability of the 162 | remainder of the terms of this Agreement, and without further action by the 163 | parties hereto, such provision shall be reformed to the minimum extent 164 | necessary to make such provision valid and enforceable. 165 | 166 | If Recipient institutes patent litigation against any entity (including a 167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 168 | (excluding combinations of the Program with other software or hardware) 169 | infringes such Recipient's patent(s), then such Recipient's rights granted 170 | under Section 2(b) shall terminate as of the date such litigation is filed. 171 | 172 | All Recipient's rights under this Agreement shall terminate if it fails to 173 | comply with any of the material terms or conditions of this Agreement and does 174 | not cure such failure in a reasonable period of time after becoming aware of 175 | such noncompliance. If all Recipient's rights under this Agreement terminate, 176 | Recipient agrees to cease use and distribution of the Program as soon as 177 | reasonably practicable. However, Recipient's obligations under this Agreement 178 | and any licenses granted by Recipient relating to the Program shall continue 179 | and survive. 180 | 181 | Everyone is permitted to copy and distribute copies of this Agreement, but in 182 | order to avoid inconsistency the Agreement is copyrighted and may only be 183 | modified in the following manner. The Agreement Steward reserves the right to 184 | publish new versions (including revisions) of this Agreement from time to 185 | time. No one other than the Agreement Steward has the right to modify this 186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 187 | Eclipse Foundation may assign the responsibility to serve as the Agreement 188 | Steward to a suitable separate entity. Each new version of the Agreement will 189 | be given a distinguishing version number. The Program (including 190 | Contributions) may always be distributed subject to the version of the 191 | Agreement under which it was received. In addition, after a new version of the 192 | Agreement is published, Contributor may elect to distribute the Program 193 | (including its Contributions) under the new version. Except as expressly 194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 195 | licenses to the intellectual property of any Contributor under this Agreement, 196 | whether expressly, by implication, estoppel or otherwise. All rights in the 197 | Program not expressly granted under this Agreement are reserved. 198 | 199 | This Agreement is governed by the laws of the State of New York and the 200 | intellectual property laws of the United States of America. No party to this 201 | Agreement will bring a legal action under this Agreement more than one year 202 | after the cause of action arose. Each party waives its rights to a jury trial in 203 | any resulting litigation. 204 | 205 | 206 | -------------------------------------------------------------------------------- /epl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Eclipse Public License - Version 1.0 8 | 25 | 26 | 27 | 28 | 29 | 30 |

Eclipse Public License - v 1.0

31 | 32 |

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 33 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR 34 | DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS 35 | AGREEMENT.

36 | 37 |

1. DEFINITIONS

38 | 39 |

"Contribution" means:

40 | 41 |

a) in the case of the initial Contributor, the initial 42 | code and documentation distributed under this Agreement, and

43 |

b) in the case of each subsequent Contributor:

44 |

i) changes to the Program, and

45 |

ii) additions to the Program;

46 |

where such changes and/or additions to the Program 47 | originate from and are distributed by that particular Contributor. A 48 | Contribution 'originates' from a Contributor if it was added to the 49 | Program by such Contributor itself or anyone acting on such 50 | Contributor's behalf. Contributions do not include additions to the 51 | Program which: (i) are separate modules of software distributed in 52 | conjunction with the Program under their own license agreement, and (ii) 53 | are not derivative works of the Program.

54 | 55 |

"Contributor" means any person or entity that distributes 56 | the Program.

57 | 58 |

"Licensed Patents" mean patent claims licensable by a 59 | Contributor which are necessarily infringed by the use or sale of its 60 | Contribution alone or when combined with the Program.

61 | 62 |

"Program" means the Contributions distributed in accordance 63 | with this Agreement.

64 | 65 |

"Recipient" means anyone who receives the Program under 66 | this Agreement, including all Contributors.

67 | 68 |

2. GRANT OF RIGHTS

69 | 70 |

a) Subject to the terms of this Agreement, each 71 | Contributor hereby grants Recipient a non-exclusive, worldwide, 72 | royalty-free copyright license to reproduce, prepare derivative works 73 | of, publicly display, publicly perform, distribute and sublicense the 74 | Contribution of such Contributor, if any, and such derivative works, in 75 | source code and object code form.

76 | 77 |

b) Subject to the terms of this Agreement, each 78 | Contributor hereby grants Recipient a non-exclusive, worldwide, 79 | royalty-free patent license under Licensed Patents to make, use, sell, 80 | offer to sell, import and otherwise transfer the Contribution of such 81 | Contributor, if any, in source code and object code form. This patent 82 | license shall apply to the combination of the Contribution and the 83 | Program if, at the time the Contribution is added by the Contributor, 84 | such addition of the Contribution causes such combination to be covered 85 | by the Licensed Patents. The patent license shall not apply to any other 86 | combinations which include the Contribution. No hardware per se is 87 | licensed hereunder.

88 | 89 |

c) Recipient understands that although each Contributor 90 | grants the licenses to its Contributions set forth herein, no assurances 91 | are provided by any Contributor that the Program does not infringe the 92 | patent or other intellectual property rights of any other entity. Each 93 | Contributor disclaims any liability to Recipient for claims brought by 94 | any other entity based on infringement of intellectual property rights 95 | or otherwise. As a condition to exercising the rights and licenses 96 | granted hereunder, each Recipient hereby assumes sole responsibility to 97 | secure any other intellectual property rights needed, if any. For 98 | example, if a third party patent license is required to allow Recipient 99 | to distribute the Program, it is Recipient's responsibility to acquire 100 | that license before distributing the Program.

101 | 102 |

d) Each Contributor represents that to its knowledge it 103 | has sufficient copyright rights in its Contribution, if any, to grant 104 | the copyright license set forth in this Agreement.

105 | 106 |

3. REQUIREMENTS

107 | 108 |

A Contributor may choose to distribute the Program in object code 109 | form under its own license agreement, provided that:

110 | 111 |

a) it complies with the terms and conditions of this 112 | Agreement; and

113 | 114 |

b) its license agreement:

115 | 116 |

i) effectively disclaims on behalf of all Contributors 117 | all warranties and conditions, express and implied, including warranties 118 | or conditions of title and non-infringement, and implied warranties or 119 | conditions of merchantability and fitness for a particular purpose;

120 | 121 |

ii) effectively excludes on behalf of all Contributors 122 | all liability for damages, including direct, indirect, special, 123 | incidental and consequential damages, such as lost profits;

124 | 125 |

iii) states that any provisions which differ from this 126 | Agreement are offered by that Contributor alone and not by any other 127 | party; and

128 | 129 |

iv) states that source code for the Program is available 130 | from such Contributor, and informs licensees how to obtain it in a 131 | reasonable manner on or through a medium customarily used for software 132 | exchange.

133 | 134 |

When the Program is made available in source code form:

135 | 136 |

a) it must be made available under this Agreement; and

137 | 138 |

b) a copy of this Agreement must be included with each 139 | copy of the Program.

140 | 141 |

Contributors may not remove or alter any copyright notices contained 142 | within the Program.

143 | 144 |

Each Contributor must identify itself as the originator of its 145 | Contribution, if any, in a manner that reasonably allows subsequent 146 | Recipients to identify the originator of the Contribution.

147 | 148 |

4. COMMERCIAL DISTRIBUTION

149 | 150 |

Commercial distributors of software may accept certain 151 | responsibilities with respect to end users, business partners and the 152 | like. While this license is intended to facilitate the commercial use of 153 | the Program, the Contributor who includes the Program in a commercial 154 | product offering should do so in a manner which does not create 155 | potential liability for other Contributors. Therefore, if a Contributor 156 | includes the Program in a commercial product offering, such Contributor 157 | ("Commercial Contributor") hereby agrees to defend and 158 | indemnify every other Contributor ("Indemnified Contributor") 159 | against any losses, damages and costs (collectively "Losses") 160 | arising from claims, lawsuits and other legal actions brought by a third 161 | party against the Indemnified Contributor to the extent caused by the 162 | acts or omissions of such Commercial Contributor in connection with its 163 | distribution of the Program in a commercial product offering. The 164 | obligations in this section do not apply to any claims or Losses 165 | relating to any actual or alleged intellectual property infringement. In 166 | order to qualify, an Indemnified Contributor must: a) promptly notify 167 | the Commercial Contributor in writing of such claim, and b) allow the 168 | Commercial Contributor to control, and cooperate with the Commercial 169 | Contributor in, the defense and any related settlement negotiations. The 170 | Indemnified Contributor may participate in any such claim at its own 171 | expense.

172 | 173 |

For example, a Contributor might include the Program in a commercial 174 | product offering, Product X. That Contributor is then a Commercial 175 | Contributor. If that Commercial Contributor then makes performance 176 | claims, or offers warranties related to Product X, those performance 177 | claims and warranties are such Commercial Contributor's responsibility 178 | alone. Under this section, the Commercial Contributor would have to 179 | defend claims against the other Contributors related to those 180 | performance claims and warranties, and if a court requires any other 181 | Contributor to pay any damages as a result, the Commercial Contributor 182 | must pay those damages.

183 | 184 |

5. NO WARRANTY

185 | 186 |

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS 187 | PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 188 | OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 189 | ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY 190 | OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely 191 | responsible for determining the appropriateness of using and 192 | distributing the Program and assumes all risks associated with its 193 | exercise of rights under this Agreement , including but not limited to 194 | the risks and costs of program errors, compliance with applicable laws, 195 | damage to or loss of data, programs or equipment, and unavailability or 196 | interruption of operations.

197 | 198 |

6. DISCLAIMER OF LIABILITY

199 | 200 |

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT 201 | NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, 202 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING 203 | WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 204 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 205 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR 206 | DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 207 | HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

208 | 209 |

7. GENERAL

210 | 211 |

If any provision of this Agreement is invalid or unenforceable under 212 | applicable law, it shall not affect the validity or enforceability of 213 | the remainder of the terms of this Agreement, and without further action 214 | by the parties hereto, such provision shall be reformed to the minimum 215 | extent necessary to make such provision valid and enforceable.

216 | 217 |

If Recipient institutes patent litigation against any entity 218 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 219 | Program itself (excluding combinations of the Program with other 220 | software or hardware) infringes such Recipient's patent(s), then such 221 | Recipient's rights granted under Section 2(b) shall terminate as of the 222 | date such litigation is filed.

223 | 224 |

All Recipient's rights under this Agreement shall terminate if it 225 | fails to comply with any of the material terms or conditions of this 226 | Agreement and does not cure such failure in a reasonable period of time 227 | after becoming aware of such noncompliance. If all Recipient's rights 228 | under this Agreement terminate, Recipient agrees to cease use and 229 | distribution of the Program as soon as reasonably practicable. However, 230 | Recipient's obligations under this Agreement and any licenses granted by 231 | Recipient relating to the Program shall continue and survive.

232 | 233 |

Everyone is permitted to copy and distribute copies of this 234 | Agreement, but in order to avoid inconsistency the Agreement is 235 | copyrighted and may only be modified in the following manner. The 236 | Agreement Steward reserves the right to publish new versions (including 237 | revisions) of this Agreement from time to time. No one other than the 238 | Agreement Steward has the right to modify this Agreement. The Eclipse 239 | Foundation is the initial Agreement Steward. The Eclipse Foundation may 240 | assign the responsibility to serve as the Agreement Steward to a 241 | suitable separate entity. Each new version of the Agreement will be 242 | given a distinguishing version number. The Program (including 243 | Contributions) may always be distributed subject to the version of the 244 | Agreement under which it was received. In addition, after a new version 245 | of the Agreement is published, Contributor may elect to distribute the 246 | Program (including its Contributions) under the new version. Except as 247 | expressly stated in Sections 2(a) and 2(b) above, Recipient receives no 248 | rights or licenses to the intellectual property of any Contributor under 249 | this Agreement, whether expressly, by implication, estoppel or 250 | otherwise. All rights in the Program not expressly granted under this 251 | Agreement are reserved.

252 | 253 |

This Agreement is governed by the laws of the State of New York and 254 | the intellectual property laws of the United States of America. No party 255 | to this Agreement will bring a legal action under this Agreement more 256 | than one year after the cause of action arose. Each party waives its 257 | rights to a jury trial in any resulting litigation.

258 | 259 | 260 | 261 | 262 | --------------------------------------------------------------------------------