source: project/release/4/base64/trunk/base64.scm @ 11448

Last change on this file since 11448 was 11448, checked in by sjamaan, 13 years ago

Port base64 egg to Hygienic Chicken

File size: 4.5 KB
Line 
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#>
34static char enc_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
35
36static 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
55static 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
78static 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)
Note: See TracBrowser for help on using the repository browser.