Mercurial > lasercutter
view src/clojure/contrib/base64.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line source
1 ;;; base64.clj: Experimental Base-64 encoding and (later) decoding3 ;; by Stuart Sierra, http://stuartsierra.com/4 ;; August 19, 20096 ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use7 ;; and distribution terms for this software are covered by the Eclipse8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)9 ;; which can be found in the file epl-v10.html at the root of this10 ;; distribution. By using this software in any fashion, you are11 ;; agreeing to be bound by the terms of this license. You must not12 ;; remove this notice, or any other, from this software.15 (ns ^{:doc "Base-64 encoding and (maybe later) decoding.17 This is mainly here as an example. It is much slower than the18 Apache Commons Codec implementation or sun.misc.BASE64Encoder."19 :author "Stuart Sierra"}20 clojure.contrib.base6421 (:import (java.io InputStream Writer ByteArrayInputStream22 StringWriter)))24 (def *base64-alphabet*25 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")27 (defn encode28 "Encodes bytes of input, writing Base 64 text on output. alphabet29 is a 65-character String containing the 64 characters to use in the30 encoding; the 65th character is the pad character. line-length is31 the maximum number of characters per line, nil for no line breaks."32 [^InputStream input ^Writer output ^String alphabet line-length]33 (let [buffer (make-array Byte/TYPE 3)]34 (loop [line 0]35 (let [len (.read input buffer)]36 (when (pos? len)37 ;; Pre-boxing the bytes as Integers is more efficient for38 ;; Clojure's bit operations.39 (let [b0 (Integer/valueOf (int (aget buffer 0)))40 b1 (Integer/valueOf (int (aget buffer 1)))41 b2 (Integer/valueOf (int (aget buffer 2)))]42 (cond (= len 3)43 (let [s0 (bit-and 0x3F (bit-shift-right b0 2))44 s1 (bit-and 0x3F45 (bit-or (bit-shift-left b0 4)46 (bit-shift-right b1 4)))47 s2 (bit-and 0x3F48 (bit-or (bit-shift-left b1 2)49 (bit-shift-right b2 6)))50 s3 (bit-and 0x3F b2)]51 (.append output (.charAt alphabet s0))52 (.append output (.charAt alphabet s1))53 (.append output (.charAt alphabet s2))54 (.append output (.charAt alphabet s3)))56 (= len 2)57 (let [s0 (bit-and 0x3F (bit-shift-right b0 2))58 s1 (bit-and 0x3F59 (bit-or (bit-shift-left b0 4)60 (bit-shift-right b1 4)))61 s2 (bit-and 0x3F (bit-shift-left b1 2))]62 (.append output (.charAt alphabet s0))63 (.append output (.charAt alphabet s1))64 (.append output (.charAt alphabet s2))65 (.append output (.charAt alphabet 64)))67 (= len 1)68 (let [s0 (bit-and 0x3F (bit-shift-right b0 2))69 s1 (bit-and 0x3F (bit-shift-left b0 4))]70 (.append output (.charAt alphabet s0))71 (.append output (.charAt alphabet s1))72 (.append output (.charAt alphabet 64))73 (.append output (.charAt alphabet 64)))))74 (if (and line-length (> (+ line 4) line-length))75 (do (.append output \newline)76 (recur 0))77 (recur (+ line 4))))))))79 (defn encode-str80 "Encodes String in base 64; returns a String. If not specified,81 encoding is UTF-8 and line-length is nil."82 ([s] (encode-str s "UTF-8" nil))83 ([^String s ^String encoding line-length]84 (let [output (StringWriter.)]85 (encode (ByteArrayInputStream. (.getBytes s encoding))86 output *base64-alphabet* line-length)87 (.toString output))))90 ;;; tests92 ;; (deftest t-encode-str93 ;; (is (= (encode-str "") ""))94 ;; (is (= (encode-str "f") "Zg=="))95 ;; (is (= (encode-str "fo") "Zm8="))96 ;; (is (= (encode-str "foo") "Zm9v"))97 ;; (is (= (encode-str "foob") "Zm9vYg=="))98 ;; (is (= (encode-str "fooba") "Zm9vYmE="))99 ;; (is (= (encode-str "foobar") "Zm9vYmFy")))