1 | ;; Copyright (c) 2004 James Bailey (dgym.REMOVE_THIS.bailey@gmail.com). |
---|
2 | ;; |
---|
3 | ;; Permission is hereby granted, free of charge, to any person obtaining a |
---|
4 | ;; copy of this software and associated documentation files (the "Software"), to |
---|
5 | ;; deal in the Software without restriction, including without limitation the |
---|
6 | ;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
---|
7 | ;; sell copies of the Software, and to permit persons to whom the Software is |
---|
8 | ;; furnished to do so, subject to the following conditions: |
---|
9 | ;; |
---|
10 | ;; The above copyright notice and this permission notice shall be included in all |
---|
11 | ;; copies or substantial portions of the Software. |
---|
12 | ;; |
---|
13 | ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
14 | ;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
15 | ;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
16 | ;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
17 | ;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
18 | ;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
19 | ;; SOFTWARE. |
---|
20 | |
---|
21 | ;; base64 routines for bigloo, apart from the module info, bit routines, "when" |
---|
22 | ;; and fixed division "/fx" it should be slightly portable |
---|
23 | |
---|
24 | ;; ported to CHICKEN by felix |
---|
25 | ;; reimplemented in C by zbigniew [2008] |
---|
26 | |
---|
27 | (module base64 |
---|
28 | (encode decode) |
---|
29 | (import chicken scheme) |
---|
30 | |
---|
31 | (declare (fixnum)) |
---|
32 | |
---|
33 | #> |
---|
34 | static char enc_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
---|
35 | |
---|
36 | static char dec_table[] = { |
---|
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
39 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, |
---|
40 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, |
---|
41 | 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
---|
42 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, |
---|
43 | 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, |
---|
44 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, |
---|
45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
48 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
49 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
50 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
51 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
---|
53 | }; |
---|
54 | |
---|
55 | static void base64_encode(char *dst, const char *src, int len) { |
---|
56 | int i, o, r; |
---|
57 | for (i = 0, o = 0, r = len; i < len; i+= 3, o+= 4, r -= 3) { |
---|
58 | int n = src[i] << 16; |
---|
59 | if (r > 1) |
---|
60 | n |= src[i+1] << 8; |
---|
61 | dst[o] = enc_table[(n >> 18) & 63]; |
---|
62 | dst[o+1] = enc_table[(n >> 12) & 63]; |
---|
63 | if (r > 1) { |
---|
64 | if (r > 2) { |
---|
65 | n |= src[i+2]; |
---|
66 | dst[o+3] = enc_table[n & 63]; |
---|
67 | } |
---|
68 | dst[o+2] = enc_table[(n >> 6) & 63]; |
---|
69 | } |
---|
70 | } |
---|
71 | |
---|
72 | switch(r) { |
---|
73 | case -2: dst[o-2] = '='; |
---|
74 | case -1: dst[o-1] = '='; |
---|
75 | } |
---|
76 | } |
---|
77 | |
---|
78 | static void base64_decode(char *dst, const char *src, int len) { |
---|
79 | int i, o, r; |
---|
80 | for (i = 0, o = 0, r = len; i < len; i += 4, o += 3, r -= 3) { |
---|
81 | int n = dec_table[(int) src[i]] << 18 | dec_table[(int) src[i+1]] << 12 | |
---|
82 | dec_table[(int) src[i+2]] << 6 | dec_table[(int) src[i+3]]; |
---|
83 | dst[o] = (n >> 16) & 255; |
---|
84 | if (r > 1) { |
---|
85 | dst[o+1] = (n >> 8) & 255; |
---|
86 | if (r > 2) { |
---|
87 | dst[o+2] = n & 255; |
---|
88 | } |
---|
89 | } |
---|
90 | } |
---|
91 | } |
---|
92 | |
---|
93 | <# |
---|
94 | |
---|
95 | (define (encode str) |
---|
96 | (define base64_encode (foreign-lambda void base64_encode pointer c-string int)) |
---|
97 | (let* ((len (string-length str)) |
---|
98 | (buf (##sys#make-string (* 4 (/ (+ len 2) 3)) |
---|
99 | #f))) |
---|
100 | (base64_encode buf str len) |
---|
101 | buf)) |
---|
102 | |
---|
103 | (define (decode str) |
---|
104 | (define base64_decode (foreign-lambda void base64_decode pointer c-string int)) |
---|
105 | (let ((len (string-length str))) |
---|
106 | (if (zero? len) |
---|
107 | "" |
---|
108 | (let* ((result-len (- (* 3 (/ len 4)) |
---|
109 | (cond ((char=? (string-ref str (- len 2)) #\=) 2) |
---|
110 | ((char=? (string-ref str (- len 1)) #\=) 1) |
---|
111 | (else 0)))) |
---|
112 | (buf (##sys#make-string result-len #f))) |
---|
113 | (base64_decode buf str len) |
---|
114 | buf)))) |
---|
115 | ) |
---|