- (defvar *encode-table*
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
- (declaim (type simple-string *encode-table*))
-
- (defvar *uri-encode-table*
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")
- (declaim (type simple-string *uri-encode-table*))
-
- (deftype decode-table () '(array fixnum (256)))
+(defvar *encode-table*
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+(declaim (type simple-string *encode-table*))
+
+(defvar *uri-encode-table*
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")
+(declaim (type simple-string *uri-encode-table*))
+
+(defvar *pad-char* #\=)
+(defvar *uri-pad-char* #\.)
+(declaim (type character *pad-char* *uri-pad-char*))
+
+ (deftype decode-table () '(simple-array (signed-byte 8) (128)))
+ (defun make-decode-table (encode-table pad-char
+ &key (whitespace-chars
+ '(#\Linefeed #\Return #\Space #\Tab)))
+ (assert (< (length encode-table) 128)
+ (encode-table)
+ "Encode table too big: ~S" encode-table)
+ (let ((dt (make-array 128 :element-type '(signed-byte 8)
+ :initial-element -1)))
+ (declare (type decode-table dt))
+ (loop for char across encode-table
+ for index upfrom 0
+ do (setf (aref dt (char-code char)) index))
+ (setf (aref dt (char-code pad-char)) -2)
+ (loop for char in whitespace-chars
+ do (setf (aref dt (char-code char)) -3))
+ dt)))
+
+(defconstant +decode-table+
+ (if (boundp '+decode-table+)
+ (symbol-value '+decode-table+)
+ (make-decode-table *encode-table* *pad-char*)))
+(defvar *decode-table* +decode-table+ "Deprecated.")
+(declaim (type decode-table +decode-table+ *decode-table*))