Mercurial > lasercutter
comparison 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 |
comparison
equal
deleted
inserted
replaced
9:35cf337adfcf | 10:ef7dbbd6452c |
---|---|
1 ;;; base64.clj: Experimental Base-64 encoding and (later) decoding | |
2 | |
3 ;; by Stuart Sierra, http://stuartsierra.com/ | |
4 ;; August 19, 2009 | |
5 | |
6 ;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use | |
7 ;; and distribution terms for this software are covered by the Eclipse | |
8 ;; 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 this | |
10 ;; distribution. By using this software in any fashion, you are | |
11 ;; agreeing to be bound by the terms of this license. You must not | |
12 ;; remove this notice, or any other, from this software. | |
13 | |
14 | |
15 (ns ^{:doc "Base-64 encoding and (maybe later) decoding. | |
16 | |
17 This is mainly here as an example. It is much slower than the | |
18 Apache Commons Codec implementation or sun.misc.BASE64Encoder." | |
19 :author "Stuart Sierra"} | |
20 clojure.contrib.base64 | |
21 (:import (java.io InputStream Writer ByteArrayInputStream | |
22 StringWriter))) | |
23 | |
24 (def *base64-alphabet* | |
25 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=") | |
26 | |
27 (defn encode | |
28 "Encodes bytes of input, writing Base 64 text on output. alphabet | |
29 is a 65-character String containing the 64 characters to use in the | |
30 encoding; the 65th character is the pad character. line-length is | |
31 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 for | |
38 ;; 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 0x3F | |
45 (bit-or (bit-shift-left b0 4) | |
46 (bit-shift-right b1 4))) | |
47 s2 (bit-and 0x3F | |
48 (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))) | |
55 | |
56 (= len 2) | |
57 (let [s0 (bit-and 0x3F (bit-shift-right b0 2)) | |
58 s1 (bit-and 0x3F | |
59 (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))) | |
66 | |
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)))))))) | |
78 | |
79 (defn encode-str | |
80 "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)))) | |
88 | |
89 | |
90 ;;; tests | |
91 | |
92 ;; (deftest t-encode-str | |
93 ;; (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"))) |